#include <stdio.h>
#include <string.h>
#include <vector>
#include <Magick++.h>
using namespace Magick;
#include <coord.h>
#include <colors.h>
void
print_coors(vector<pCoor>& coors, const char* pf, int max_v = 3)
{
printf("%6s",pf);
for ( pCoor c: coors )
if ( max_v-- ) printf(" (%6.2f,%6.2f,%6.2f)",c.x,c.y,c.z);
else break;
printf("\n");
};
vector<pCoor>
operator * (pMatrix& m, vector<pCoor>& cv)
{
vector<pCoor> rv(cv.size()); for ( size_t i=0; i<cv.size(); i++ ) rv[i] = m * cv[i];
return rv;
}
void
render_simple()
{
pCoor p0 = { 0, 0, 0 };
pCoor p1 = { 9, 6, -9 };
pCoor p2 = { 0, 5, -5 };
vector<pCoor> coors_os = { p0, p1, p2 };
print_coors(coors_os,"Obj");
pCoor eye_location = pCoor(1,.5,10.2);
pVect eye_direction = pVect(0,0,-1);
const int win_width = 900;
const int win_height = 660;
const float aspect = 1.0 * win_width / win_height;
const float width_m = 1.6;
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;
vector<pCoor> coors_es;
for ( pCoor& c: coors_os ) coors_es.push_back( eye_from_object * c );
print_coors(coors_es,"Eye");
pMatrix_Frustum clip_from_eye
( -width_m/2, width_m/2, -height_m/2, height_m/2, 1, 5000 );
vector<pCoor> coors_clip;
for ( pCoor& c: coors_es ) coors_clip.push_back( clip_from_eye * c );
print_coors(coors_clip,"Clip U");
for ( pCoor& c: coors_clip ) c = c / c.w;
print_coors(coors_clip,"Clip N");
pMatrix_Translate recenter(pVect(1,1,0));
pMatrix_Scale scale( win_width/2, win_height/2, 1 );
pMatrix pixel_from_clip = scale * recenter;
vector<pCoor> coors_window = pixel_from_clip* coors_clip;
print_coors(coors_window,"Window");
pMatrix pixel_from_obj = pixel_from_clip * clip_from_eye * eye_from_object;
vector<pCoor> coors_w2;
for ( pCoor& c: coors_os ) coors_w2.push_back( pixel_from_obj * c );
for ( pCoor& c: coors_w2 ) c = c / c.w;
print_coors(coors_w2,"Win N");
vector<uint32_t> f_buffer( win_width * win_height, 0xff222222 );
pCoor w0 = coors_w2[0];
pCoor w1 = coors_w2[1];
pCoor w2 = coors_w2[2];
pVect bx(w2,w0), by(w2,w1);
const float dx = 1/bx.mag(), dy = 1/by.mag();
for ( float x=0; x<=1; x += dx )
for ( float y=0; y<=1-x; y += dy )
if ( pCoor c = w2 + x * bx + y * by;
c.x >= 0 || c.y >= 0 || c.x < win_width || c.y < win_height )
f_buffer[ c.x + int(c.y) * win_width ] = 0xffffffff;
Image image( win_width, win_height, "RGBA", CharPixel, f_buffer.data() );
image.write( "demo-0-coor-simple.png" );
}
void
render_less_simple()
{
pCoor p0 = { 0, 0, 0 };
pCoor p1 = { 9, 6, -9 };
pCoor p2 = { 0, 5, -5 };
vector<pCoor> coors_os = { p0, p1, p2 };
vector<uint32_t> colors = { 0xffffffff };
coors_os.insert
( coors_os.end(), { pCoor(7,4,2), pCoor(-6,5,3), pCoor(9,3,2) } );
colors.push_back( 0xffff0000 );
print_coors(coors_os,"Obj");
pCoor eye_location = pCoor(1,.5,10.2);
pVect eye_direction = pVect(0,0,-1);
const int win_width = 900;
const int win_height = 660;
const float aspect = 1.0 * win_width / win_height;
const float width_m = 1.6;
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;
vector<pCoor> coors_es = eye_from_object * coors_os;
print_coors(coors_es,"Eye");
pMatrix_Frustum clip_from_eye
( -width_m/2, width_m/2, -height_m/2, height_m/2, 1, 5000 );
vector<pCoor> coors_clip;
for ( pCoor& c: coors_es ) coors_clip.push_back( clip_from_eye * c );
print_coors(coors_clip,"Clip U");
for ( pCoor& c: coors_clip ) c = c / c.w;
print_coors(coors_clip,"Clip N");
pMatrix_Translate recenter(pVect(1,1,0));
pMatrix_Scale scale( win_width/2, win_height/2, 1 );
pMatrix pixel_from_clip = scale * recenter;
vector<pCoor> coors_window = pixel_from_clip* coors_clip;
print_coors(coors_window,"Window");
pMatrix pixel_from_obj = pixel_from_clip * clip_from_eye * eye_from_object;
vector<pCoor> coors_w2;
for ( pCoor& c: coors_os ) coors_w2.push_back( pixel_from_obj * c );
for ( pCoor& c: coors_w2 ) c = c / c.w;
print_coors(coors_w2,"Win N");
vector<uint32_t> f_buffer( win_width * win_height, 0xff222222 );
auto ic = colors.begin();
for ( auto it = coors_window.begin(); it != coors_window.end(); )
{
pCoor w0 = *it++, w1 = *it++, w2 = *it++;
uint32_t color = *ic++;
pVect bx(w2,w0), by(w2,w1);
const float dx = 1/bx.mag(), dy = 1/by.mag();
for ( float x=0; x<=1; x += dx )
for ( float y=0; y<=1-x; y += dy )
{
pCoor c = w2 + x * bx + y * by;
if ( c.x < 0 || c.y < 0 || c.x >= win_width || c.y >= win_height )
continue;
if ( int(c.x) & 1 ) continue;
f_buffer[ c.x + int(c.y) * win_width ] = color;
}
}
Image image( win_width, win_height, "RGBA", CharPixel, f_buffer.data() );
image.write( "demo-3-cpu-only-less-simple.png" );
}
int
main(int argc, char **argv)
{
InitializeMagick(nullptr);
render_simple();
render_less_simple();
}