#include <gp/coord.h>
#include <gp/colors.h>
#include "frame_buffer.h"
#if 0
pColor red(1,0,0);
pColor pink(1,0.5,0.5);
pColor Red( 0xff0000 );
pColor Pink( 0xff8080 );
pColor purg = 0.4 * color_purple + 0.6 * color_gold;
#endif
class World_Z : public World_Base {
public:
World_Z(pFrame_Buffer& fb):World_Base(fb){};
virtual void render(bool first_time);
};
void
World_Z::render(bool first_time)
{
vector<pCoor> coors_os;
vector<pColor> colors;
coors_os << pCoor( 0, 0, 0 ) << pCoor( 9, 6, -9 ) << pCoor( 0, 7, -5 );
colors << color_white;
coors_os << pCoor(7,4,-2) << pCoor(-3,5,-9) << pCoor(9,2,-2);
colors << color_red;
colors << color_red << color_green;
coors_os << pCoor(-4,0,-2) << pCoor(-4,2,-2) << pCoor(-2,0,-2);
coors_os << pCoor(-4,2,-2) << pCoor(-2,2,-2) << pCoor(-2,0,-2);
int n_segs = 20;
pCoor center(1,-1,-3);
pVect sz( 0, 0.5, 0.05 );
pNorm ax( 0, -sz.z, sz.y ), ay = cross(sz,ax);
vector<pCoor> strip_coor(n_segs+1);
float r = 4, d_th = 2 * M_PI / n_segs;
for ( int i=0; i<=n_segs; i++ )
strip_coor[i] = center + r*ax * cosf(i*d_th) + r*ay * sinf(i*d_th);
for ( int i=0; i<n_segs; i++ )
{
coors_os << strip_coor[i] << strip_coor[i+1] << strip_coor[i] + sz;
coors_os << strip_coor[i] + sz << strip_coor[i+1] + sz << strip_coor[i+1];
if ( i == 0 ) colors << color_red << color_green;
else colors << pColor(0xff00ff) << pColor(0xffff);
}
if ( first_time ) eye_location = pCoor(1,.5,10.2);
switch ( frame_buffer.keyboard_key ) {
case FB_KEY_LEFT: eye_location.x += 0.1; break;
case FB_KEY_RIGHT: eye_location.x -= 0.1; break;
case FB_KEY_PAGE_UP: eye_location.y += 0.1; break;
case FB_KEY_PAGE_DOWN: eye_location.y -= 0.1; break;
case FB_KEY_UP: eye_location.z -= 0.1; break;
case FB_KEY_DOWN: eye_location.z += 0.1; break;
}
pVect eye_direction = pVect(0,0,-1);
pVect eye_to_light = pVect(0,1,0);
pCoor light_location = eye_location + eye_to_light;
pColor light_color = color_white * 100;
const float width_m = 1.6; const float qn = 1; const uint win_width = frame_buffer.width_get();
const uint win_height = frame_buffer.height_get();
const float aspect = 1.0 * win_width / win_height;
const float height_m = width_m / aspect;
pMatrix_Translate center_eye(-eye_location);
pMatrix_Rotation rotate_eye(eye_direction,pVect(0,0,-1));
pMatrix eye_from_object = rotate_eye * center_eye;
pMatrix_Frustum clip_from_eye
( -width_m/2, width_m/2, -height_m/2, height_m/2, qn, 5000 );
pMatrix_Translate recenter(pVect(1,1,0));
pMatrix_Scale scale( win_width/2, win_height/2, 1 );
pMatrix window_from_clip = scale * recenter;
pMatrix ws_from_os = window_from_clip * clip_from_eye * eye_from_object;
float* const zbuffer = frame_buffer.buffer_depth_get();
auto ic = colors.begin();
for ( auto it = coors_os.begin(); it != coors_os.end(); )
{
pCoor o0 = *it++, o1 = *it++, o2 = *it++;
pCoor_Homogenized
w0( ws_from_os * o0 ), w1( ws_from_os * o1 ), w2( ws_from_os * o2 );
pColor color = *ic++;
pNorm n = cross(o0,o1,o2);
pVect v20(w2,w0), v21(w2,w1);
const float db0 = 1/max(fabs(v20.x),fabs(v20.y));
const float db1 = 1/max(fabs(v21.x),fabs(v21.y));
for ( float b0=0; b0<=1; b0 += db0 )
for ( float b1=0; b1<=1-b0; b1 += db1 )
{
pCoor wf = w2 + b0 * v20 + b1 * v21;
if ( uint(wf.x) >= win_width || uint(wf.y) >= win_height ) continue;
const size_t idx = wf.x + int(wf.y) * win_width;
float zinv = wf.z;
if ( zinv < 0 || zinv > 1 ) continue;
if ( zbuffer[ idx ] < zinv ) continue;
zbuffer[ idx ] = zinv;
pCoor of = o0*b0 + o1*b1 + o2*(1-b0-b1);
pNorm f_to_l(of,light_location);
float phase = fabs(dot(n,f_to_l));
pColor lighted_color = phase / f_to_l.mag_sq * light_color * color;
frame_buffer[ idx ] = lighted_color.int_rgb();
}
}
}
int
main(int argc, char **argv)
{
pFrame_Buffer demo_frame_buffer(argc,argv);
World_Z worldz(demo_frame_buffer);
WRender render(demo_frame_buffer);
WRENDER_INSERT(render, worldz);
render.run();
return 0;
}