From c8ac7aff278b873aeb88c30115ea95366bf09ef2 Mon Sep 17 00:00:00 2001 From: Wolfgang Thaller Date: Wed, 17 Sep 2014 03:39:50 +0200 Subject: [PATCH] convert raytracer.cc to plain C --- README.md | 7 +-- Raytracer/CMakeLists.txt | 3 +- Raytracer/{raytracer.cc => raytracer.c} | 75 ++++++++++++++----------- 3 files changed, 46 insertions(+), 39 deletions(-) rename Raytracer/{raytracer.cc => raytracer.c} (80%) diff --git a/README.md b/README.md index 0b3b68e528..5a674f34b1 100644 --- a/README.md +++ b/README.md @@ -168,11 +168,10 @@ in MacBinary format and also on a disk image named Test.dsk. ### Sample Program: Raytracer Calculates a nice 3D image, pixel by pixel. -There are two versions: raytracer.cc is a straightforward -almost-plain-C implementation (a few C++ features have been used) -using floating point arithmetic. +There are two versions: raytracer.c is a straightforward +plain C implementation 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 (operator overloading FTW). diff --git a/Raytracer/CMakeLists.txt b/Raytracer/CMakeLists.txt index 8fe1b50cfd..f3dc5ebd38 100644 --- a/Raytracer/CMakeLists.txt +++ b/Raytracer/CMakeLists.txt @@ -23,7 +23,7 @@ endif() include_directories(../App2) add_executable(Raytracer MACOSX_BUNDLE - raytracer.cc + raytracer.c ) add_executable(Raytracer2 MACOSX_BUNDLE raytracer2.cc @@ -48,6 +48,7 @@ add_custom_command( OUTPUT Raytracer.bin COMMAND ${MAKE_APPL} -c Raytracer -o Raytracer DEPENDS Raytracer) +target_link_libraries(Raytracer "-lm") add_custom_target(RaytracerAPPL ALL DEPENDS Raytracer.bin) target_link_libraries(Raytracer2 retrocrt) diff --git a/Raytracer/raytracer.cc b/Raytracer/raytracer.c similarity index 80% rename from Raytracer/raytracer.cc rename to Raytracer/raytracer.c index b50ab76553..c10eae78e8 100644 --- a/Raytracer/raytracer.cc +++ b/Raytracer/raytracer.c @@ -1,5 +1,5 @@ /* - Copyright 2012 Wolfgang Thaller. + Copyright 2014 Wolfgang Thaller. This file is part of Retro68. @@ -20,8 +20,6 @@ #ifdef __APPLE__ #include #include -#define PSTR(x) ("\p" x) - #else #include @@ -32,23 +30,19 @@ #include #ifdef __GNUC__ -#include "MacUtils.h" QDGlobals qd; -#else -#define PSTR(x) ("\p" x) #endif #endif -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include - -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; 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) { - t = (-b - std::sqrt(D)) / (2*a); - return t >= 0; + *t = (-b - sqrtf(D)) / (2*a); + return *t >= 0; } return false; } const float lx = -2, ly = 4, lz = 3; -const float lenl = 1.0f / std::sqrt(lx*lx + ly*ly + lz*lz); -const float lxn = lx*lenl, lyn = ly*lenl, lzn = lz*lenl; +float lenl; +float lxn, lyn, lzn; 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) { - float t = (-b - std::sqrt(D)) / (2*a); + float t = (-b - sqrtf(D)) / (2*a); if(t > 0) { 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; - - return 0.2f + 0.4f * std::max(0.0f,lambert) + 0.4f * reflected; + if(lambert < 0.0f) + 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 color; - if( (static_cast( std::floor(x) ) - + static_cast( std::floor(z) )) % 2 ) + if( ((int)( floorf(x) ) + + (int)( floorf(z) )) % 2 ) color = 0.8f; else color = 0.1f; 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; - 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() @@ -171,7 +174,7 @@ int main() Rect r = bm.bounds; #endif 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 SetPort(win); @@ -184,12 +187,16 @@ int main() float accum = 0.0f; short cx = r.right /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(); - std::vector accumV(r.right); - for(int y = 0; y < r.bottom; y++) + float *accumV = calloc(sizeof(float), r.right); + for(y = 0; y < r.bottom; y++) { - for(int x = 0; x < r.right; x++) + for(x = 0; x < r.right; x++) { float pixel; @@ -200,7 +207,7 @@ int main() float dx = x - cx; float dy = - (y - cy); 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); @@ -232,7 +239,7 @@ int main() Line(0,0); } #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); accum += pixel; accum += accumV[x]; @@ -256,8 +263,8 @@ int main() char buf[256]; unsigned char* pstr = (unsigned char*)buf; - std::sprintf(buf+1, "pps = %d", (int)( (float)r.right * r.bottom / (endTime - startTime) * 60.0f )); - buf[0] = std::strlen(buf+1); + sprintf(buf+1, "pps = %d", (int)( (float)r.right * r.bottom / (endTime - startTime) * 60.0f )); + buf[0] = strlen(buf+1); SetRect(&r, 10, 10, 10 + StringWidth(pstr) + 10, 30); PaintRect(&r);