convert raytracer.cc to plain C

This commit is contained in:
Wolfgang Thaller 2014-09-17 03:39:50 +02:00
parent 534ef17a1f
commit c8ac7aff27
3 changed files with 46 additions and 39 deletions

View File

@ -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).

View File

@ -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)

View File

@ -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);