#include #include #include #include #define dword __UINT32_TYPE__ #define byte __UINT8_TYPE__ typedef struct { char magic[4]; dword size, flags, height, width, pitch, depth, mipmaps, reserved1[11], pf_size, pf_flags; char pf_fourcc[4]; dword pf_bitcount, pf_rmask, pf_gmask, pf_bmask, pf_amask, caps[4], reserved2; } __attribute__((packed)) ddsheader_t; ddsheader_t head = { .magic = "DDS ", .size = 124, .flags = 0x0000100F, /* caps|height|width|pitch|pixelformat */ .height = 0, .width = 0, .pitch = 0, .depth = 0, /* set later */ .mipmaps = 0, .reserved1 = {0,0,0,0,0,0,0,0,0,0,0}, .pf_size = 32, .pf_flags = 0x41 /* uncompressed|alpha */, .pf_fourcc = {0}, /* N/A */ .pf_bitcount = 32, .pf_rmask = 0xff, .pf_gmask = 0xff00, .pf_bmask = 0xff0000, .pf_amask = 0xff000000, /* RGBA mask */ .caps = {0x1000,0,0,0}, /* texture */ .reserved2 = 0 }; typedef struct { byte r,g,b,a; } __attribute__((packed)) pixel_t; unsigned w = 0, h = 0; pixel_t *tex = 0, *ttex = 0; FILE *obj, *dds, *tmap; typedef struct { float x,y,z; } vect_t; typedef struct { float u,v; } uv_t; typedef struct { int v,c,n; } vert_t; typedef struct { vert_t a,b,c; } tri_t; typedef struct { int x,y; } vec2_t; typedef struct { pixel_t c[2]; vec2_t p[2]; } edge_t; vect_t *verts = 0, *norms = 0, *tangents = 0, *binormals = 0; uv_t *uvs = 0; tri_t *tris = 0; int nvert = 0, nnorm = 0, ncoord = 0, nface = 0; void cross( vect_t *a, vect_t b, vect_t c ) { a->x = b.y*c.z-b.z*c.y; a->y = b.z*c.x-b.x*c.z; a->z = b.x*c.y-b.y*c.x; } void normalize( vect_t *a ) { float scale = sqrtf(powf(a->x,2.f)+powf(a->y,2.f)+powf(a->z,2.f)); a->x /= scale; a->y /= scale; a->z /= scale; } void normalize2( uv_t *a ) { float scale = sqrtf(powf(a->u,2.f)+powf(a->v,2.f)); a->u /= scale; a->v /= scale; } float dot( vect_t a, vect_t b ) { return a.x*b.x+a.y*b.y+a.z*b.z; } void tangent( vect_t *t, vect_t *b, int n ) { vect_t t1 = {0,0,0}, t2 = {0,0,0}; for ( int j=0; jc[0] = c1; e->p[0] = p1; e->c[1] = c2; e->p[1] = p2; } else { e->c[0] = c2; e->p[0] = p2; e->c[1] = c1; e->p[1] = p1; } } void lerpcolor( pixel_t *o, pixel_t a, pixel_t b, float f ) { f = (f>0.f)?(f>1.f)?1.f:f:0.f; o->r = a.r*(1.f-f)+b.r*f; o->g = a.g*(1.f-f)+b.g*f; o->b = a.b*(1.f-f)+b.b*f; o->a = a.a*(1.f-f)+b.a*f; } void drawspans( edge_t a, edge_t b ) { float e1 = a.p[1].y-a.p[0].y; if ( e1 == 0.f ) return; float e2 = b.p[1].y-b.p[0].y; if ( e2 == 0.f ) return; float is1 = (float)(a.p[1].x-a.p[0].x); float is2 = (float)(b.p[1].x-b.p[0].x); float f1 = (float)(b.p[0].y-a.p[0].y)/e1; float fs1 = 1.f/e1; float f2 = 0.f; float fs2 = 1.f/e2; for ( int y=b.p[0].y; yx2 ) { int tmp = x1; x1 = x2; x2 = tmp; pixel_t tmpc = c1; c1 = c2; c2 = tmpc; } int xd = x2-x1; if ( xd != 0 ) { float fx = 0.f, fsx = 1.f/(float)xd; for ( int x=x1; x= 0) && (x < w) && (y >= 0) && (y < h) ) if ( !tex[x+y*w].a ) tex[x+y*w] = c3; fx += fsx; } } f1 += fs1; f2 += fs2; } } void drawtriangle( int t1, int t2, int t3, int n1, int n2, int n3 ) { pixel_t col[3] = { {(norms[n1].x*0.5f+0.5f)*255,(norms[n1].z*0.5f+0.5f)*255, (norms[n1].y*0.5+0.5)*255,255}, {(norms[n2].x*0.5f+0.5f)*255,(norms[n2].z*0.5f+0.5f)*255, (norms[n2].y*0.5+0.5)*255,255}, {(norms[n3].x*0.5f+0.5f)*255,(norms[n3].z*0.5f+0.5f)*255, (norms[n3].y*0.5f+0.5f)*255,255}, }; vec2_t pts[3] = { {uvs[t1].u*w,uvs[t1].v*h}, {uvs[t2].u*w,uvs[t2].v*h}, {uvs[t3].u*w,uvs[t3].v*h} }; edge_t edges[3]; mkedge(&edges[0],col[0],pts[0],col[1],pts[1]); mkedge(&edges[1],col[1],pts[1],col[2],pts[2]); mkedge(&edges[2],col[2],pts[2],col[0],pts[0]); float ml = 0; int longest = 0, short1 = 0, short2 = 0; for ( int i=0; i<3; i++ ) { float l = edges[i].p[1].y-edges[i].p[0].y; if ( l > ml ) { ml = l; longest = i; } } short1 = (longest+1)%3; short2 = (longest+2)%3; drawspans(edges[longest],edges[short1]); drawspans(edges[longest],edges[short2]); } void plotnormals( void ) { int x1, y1, x2, y2, x3, y3; for ( int i=0; i