mirror of
https://github.com/autc04/Retro68.git
synced 2025-02-05 19:32:29 +00:00
convert raytracer.cc to plain C
This commit is contained in:
parent
534ef17a1f
commit
c8ac7aff27
@ -168,11 +168,10 @@ in MacBinary format and also on a disk image named Test.dsk.
|
|||||||
### Sample Program: Raytracer
|
### Sample Program: Raytracer
|
||||||
|
|
||||||
Calculates a nice 3D image, pixel by pixel.
|
Calculates a nice 3D image, pixel by pixel.
|
||||||
There are two versions: raytracer.cc is a straightforward
|
There are two versions: raytracer.c is a straightforward
|
||||||
almost-plain-C implementation (a few C++ features have been used)
|
plain C implementation using floating point arithmetic.
|
||||||
using floating point arithmetic.
|
|
||||||
|
|
||||||
Raytracer2 makes a bit more use of C++ features; it also uses
|
Raytracer2 makes use of C++ features; it also uses
|
||||||
fixed point arithmetic instead of floating point
|
fixed point arithmetic instead of floating point
|
||||||
(operator overloading FTW).
|
(operator overloading FTW).
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ endif()
|
|||||||
|
|
||||||
include_directories(../App2)
|
include_directories(../App2)
|
||||||
add_executable(Raytracer MACOSX_BUNDLE
|
add_executable(Raytracer MACOSX_BUNDLE
|
||||||
raytracer.cc
|
raytracer.c
|
||||||
)
|
)
|
||||||
add_executable(Raytracer2 MACOSX_BUNDLE
|
add_executable(Raytracer2 MACOSX_BUNDLE
|
||||||
raytracer2.cc
|
raytracer2.cc
|
||||||
@ -48,6 +48,7 @@ add_custom_command(
|
|||||||
OUTPUT Raytracer.bin
|
OUTPUT Raytracer.bin
|
||||||
COMMAND ${MAKE_APPL} -c Raytracer -o Raytracer
|
COMMAND ${MAKE_APPL} -c Raytracer -o Raytracer
|
||||||
DEPENDS Raytracer)
|
DEPENDS Raytracer)
|
||||||
|
target_link_libraries(Raytracer "-lm")
|
||||||
add_custom_target(RaytracerAPPL ALL DEPENDS Raytracer.bin)
|
add_custom_target(RaytracerAPPL ALL DEPENDS Raytracer.bin)
|
||||||
|
|
||||||
target_link_libraries(Raytracer2 retrocrt)
|
target_link_libraries(Raytracer2 retrocrt)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Wolfgang Thaller.
|
Copyright 2014 Wolfgang Thaller.
|
||||||
|
|
||||||
This file is part of Retro68.
|
This file is part of Retro68.
|
||||||
|
|
||||||
@ -20,8 +20,6 @@
|
|||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <Carbon/Carbon.h>
|
#include <Carbon/Carbon.h>
|
||||||
#include <ApplicationServices/ApplicationServices.h>
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
#define PSTR(x) ("\p" x)
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <Quickdraw.h>
|
#include <Quickdraw.h>
|
||||||
@ -32,23 +30,19 @@
|
|||||||
#include <NumberFormatting.h>
|
#include <NumberFormatting.h>
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#include "MacUtils.h"
|
|
||||||
QDGlobals qd;
|
QDGlobals qd;
|
||||||
#else
|
|
||||||
#define PSTR(x) ("\p" x)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include <cmath>
|
#include <math.h>
|
||||||
#include <algorithm>
|
#include <stdlib.h>
|
||||||
#include <cstdlib>
|
#include <string.h>
|
||||||
#include <cstring>
|
#include <stdbool.h>
|
||||||
#include <vector>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
bool hitSphere(float x0, float y0, float z0, float dx, float dy, float dz, float *t)
|
||||||
bool hitSphere(float x0, float y0, float z0, float dx, float dy, float dz, float& t)
|
|
||||||
{
|
{
|
||||||
const float xc = 0.0f, yc = 0.0f, zc = -6.0f, r = 1.0f;
|
const float xc = 0.0f, yc = 0.0f, zc = -6.0f, r = 1.0f;
|
||||||
float x0c = x0 - xc;
|
float x0c = x0 - xc;
|
||||||
@ -70,14 +64,14 @@ bool hitSphere(float x0, float y0, float z0, float dx, float dy, float dz, float
|
|||||||
|
|
||||||
if(D >= 0)
|
if(D >= 0)
|
||||||
{
|
{
|
||||||
t = (-b - std::sqrt(D)) / (2*a);
|
*t = (-b - sqrtf(D)) / (2*a);
|
||||||
return t >= 0;
|
return *t >= 0;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const float lx = -2, ly = 4, lz = 3;
|
const float lx = -2, ly = 4, lz = 3;
|
||||||
const float lenl = 1.0f / std::sqrt(lx*lx + ly*ly + lz*lz);
|
float lenl;
|
||||||
const float lxn = lx*lenl, lyn = ly*lenl, lzn = lz*lenl;
|
float lxn, lyn, lzn;
|
||||||
|
|
||||||
float ray(int n, float x0, float y0, float z0, float dx, float dy, float dz)
|
float ray(int n, float x0, float y0, float z0, float dx, float dy, float dz)
|
||||||
{
|
{
|
||||||
@ -102,7 +96,7 @@ float ray(int n, float x0, float y0, float z0, float dx, float dy, float dz)
|
|||||||
|
|
||||||
if(D >= 0)
|
if(D >= 0)
|
||||||
{
|
{
|
||||||
float t = (-b - std::sqrt(D)) / (2*a);
|
float t = (-b - sqrtf(D)) / (2*a);
|
||||||
if(t > 0)
|
if(t > 0)
|
||||||
{
|
{
|
||||||
float x = x0 + dx * t;
|
float x = x0 + dx * t;
|
||||||
@ -125,8 +119,9 @@ float ray(int n, float x0, float y0, float z0, float dx, float dy, float dz)
|
|||||||
|
|
||||||
|
|
||||||
float lambert = dx2 * lxn + dy2 * lyn + dz2 * lzn;
|
float lambert = dx2 * lxn + dy2 * lyn + dz2 * lzn;
|
||||||
|
if(lambert < 0.0f)
|
||||||
return 0.2f + 0.4f * std::max(0.0f,lambert) + 0.4f * reflected;
|
lambert = 0.0f;
|
||||||
|
return 0.2f + 0.4f * lambert + 0.4f * reflected;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -138,20 +133,28 @@ float ray(int n, float x0, float y0, float z0, float dx, float dy, float dz)
|
|||||||
float z = z0 + dz * t;
|
float z = z0 + dz * t;
|
||||||
|
|
||||||
float color;
|
float color;
|
||||||
if( (static_cast<int>( std::floor(x) )
|
if( ((int)( floorf(x) )
|
||||||
+ static_cast<int>( std::floor(z) )) % 2 )
|
+ (int)( floorf(z) )) % 2 )
|
||||||
color = 0.8f;
|
color = 0.8f;
|
||||||
else
|
else
|
||||||
color = 0.1f;
|
color = 0.1f;
|
||||||
|
|
||||||
float ts;
|
float ts;
|
||||||
if(hitSphere(x,-1.5f,z, lxn, lyn, lzn, ts))
|
if(hitSphere(x,-1.5f,z, lxn, lyn, lzn, &ts))
|
||||||
color *= 0.2f;
|
color *= 0.2f;
|
||||||
|
|
||||||
return std::min(1.0f, color + 0.5f * ray(n-1, x,-1.5f,z,dx,-dy,dz));
|
float v = color + 0.5f * ray(n-1, x,-1.5f,z,dx,-dy,dz);
|
||||||
|
if(v > 1.0f)
|
||||||
|
return 1.0f;
|
||||||
|
else
|
||||||
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::max(0.0f, dy * 0.3f);
|
float v = dy * 0.3f;
|
||||||
|
if(v < 0.0f)
|
||||||
|
return 0.0f;
|
||||||
|
else
|
||||||
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
@ -171,7 +174,7 @@ int main()
|
|||||||
Rect r = bm.bounds;
|
Rect r = bm.bounds;
|
||||||
#endif
|
#endif
|
||||||
SetRect(&r, r.left + 5, r.top + 45, r.right - 5, r.bottom -5);
|
SetRect(&r, r.left + 5, r.top + 45, r.right - 5, r.bottom -5);
|
||||||
win = NewWindow(NULL, &r, PSTR("Raytracer"), true, 0, (WindowPtr)-1, false, 0);
|
win = NewWindow(NULL, &r, (ConstStr255Param)"\x09Raytracer", true, 0, (WindowPtr)-1, false, 0);
|
||||||
|
|
||||||
#if !TARGET_API_MAC_CARBON
|
#if !TARGET_API_MAC_CARBON
|
||||||
SetPort(win);
|
SetPort(win);
|
||||||
@ -184,12 +187,16 @@ int main()
|
|||||||
float accum = 0.0f;
|
float accum = 0.0f;
|
||||||
short cx = r.right /2;
|
short cx = r.right /2;
|
||||||
short cy = r.bottom / 2;
|
short cy = r.bottom / 2;
|
||||||
|
int x,y;
|
||||||
|
|
||||||
|
lenl = 1.0f / sqrtf(lx*lx + ly*ly + lz*lz);
|
||||||
|
lxn = lx*lenl, lyn = ly*lenl, lzn = lz*lenl;
|
||||||
|
|
||||||
long startTime = TickCount();
|
long startTime = TickCount();
|
||||||
std::vector<float> accumV(r.right);
|
float *accumV = calloc(sizeof(float), r.right);
|
||||||
for(int y = 0; y < r.bottom; y++)
|
for(y = 0; y < r.bottom; y++)
|
||||||
{
|
{
|
||||||
for(int x = 0; x < r.right; x++)
|
for(x = 0; x < r.right; x++)
|
||||||
{
|
{
|
||||||
float pixel;
|
float pixel;
|
||||||
|
|
||||||
@ -200,7 +207,7 @@ int main()
|
|||||||
float dx = x - cx;
|
float dx = x - cx;
|
||||||
float dy = - (y - cy);
|
float dy = - (y - cy);
|
||||||
float dz = -cx;
|
float dz = -cx;
|
||||||
float n1 = 1.0f / std::sqrt(dx*dx + dy*dy + dz*dz);
|
float n1 = 1.0f / sqrtf(dx*dx + dy*dy + dz*dz);
|
||||||
|
|
||||||
pixel = ray(1,0,0,0,n1*dx,n1*dy,n1*dz);
|
pixel = ray(1,0,0,0,n1*dx,n1*dy,n1*dz);
|
||||||
|
|
||||||
@ -232,7 +239,7 @@ int main()
|
|||||||
Line(0,0);
|
Line(0,0);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
float thresh = (float)std::rand() / (32767.0f * 65536.0f);
|
float thresh = (float)rand() / (32767.0f * 65536.0f);
|
||||||
thresh = 0.5f + 0.4f * (thresh - 0.5f);
|
thresh = 0.5f + 0.4f * (thresh - 0.5f);
|
||||||
accum += pixel;
|
accum += pixel;
|
||||||
accum += accumV[x];
|
accum += accumV[x];
|
||||||
@ -256,8 +263,8 @@ int main()
|
|||||||
|
|
||||||
char buf[256];
|
char buf[256];
|
||||||
unsigned char* pstr = (unsigned char*)buf;
|
unsigned char* pstr = (unsigned char*)buf;
|
||||||
std::sprintf(buf+1, "pps = %d", (int)( (float)r.right * r.bottom / (endTime - startTime) * 60.0f ));
|
sprintf(buf+1, "pps = %d", (int)( (float)r.right * r.bottom / (endTime - startTime) * 60.0f ));
|
||||||
buf[0] = std::strlen(buf+1);
|
buf[0] = strlen(buf+1);
|
||||||
|
|
||||||
SetRect(&r, 10, 10, 10 + StringWidth(pstr) + 10, 30);
|
SetRect(&r, 10, 10, 10 + StringWidth(pstr) + 10, 30);
|
||||||
PaintRect(&r);
|
PaintRect(&r);
|
Loading…
x
Reference in New Issue
Block a user