ref: b7e50c61fac413c2e9c4d2dec9df7a8f2e0858b3
dir: /SDL_Examples/model.c/
//#define PLAY_MUSIC #include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "../include/GL/gl.h" #define STB_IMAGE_IMPLEMENTATION #include "../include-demo/stb_image.h" #define CHAD_MATH_IMPL #include "../include-demo/3dMath.h" #include "../include-demo/tobjparse.h" #define CHAD_API_IMPL #include "../include/zbuffer.h" #ifdef PLAY_MUSIC #include "../include-demo/api_audio.h" #else typedef unsigned char uchar; #endif #include <SDL/SDL.h> #include <time.h> int noSDL = 0; int doblend = 0; #ifndef M_PI #define M_PI 3.14159265 #endif vec3 campos = (vec3){.d[0] = 0, .d[1] = 0, .d[2] = -3}; vec3 camforw = (vec3){.d[0] = 0, .d[1] = 0, .d[2] = -1}; vec3 camup = (vec3){.d[0] = 0, .d[1] = 1, .d[2] = 0}; uint wasdstate[4] = {0, 0, 0, 0}; const float mouseratiox = 1.0 / 300.0f; const float mouseratioy = 1.0 / 300.0f; int mousex = 0, mousey = 0; int ModelArrayLoaded = 0; int testingModelArrays = 0; int testingCopyImage2D = 0; struct { float* points; uint npoints; float* normals; float* colors; float* texcoords; } ModelArray; void FreeModelArray() { if (!ModelArrayLoaded) { ModelArray.points = NULL; ModelArray.normals = NULL; ModelArray.npoints = 0; ModelArray.colors = NULL; ModelArray.texcoords = NULL; return; } ModelArrayLoaded = 0; if (ModelArray.points) free(ModelArray.points); if (ModelArray.normals) free(ModelArray.normals); if (ModelArray.texcoords) free(ModelArray.texcoords); if (ModelArray.colors) free(ModelArray.colors); ModelArray.npoints = 0; return; } void rotateCamera() { vec3 a; a.d[1] = (float)mousex * mouseratiox; a.d[2] = (float)mousey * mouseratioy; vec3 right = normalizev3(crossv3(camforw, camup)); right.d[1] = 0; // vec3 forward = glm::vec3(glm::normalize(glm::rotate(angle, right) * glm::vec4(forward, 0.0))); camforw = normalizev3(rotatev3(camforw, right, -a.d[2])); // up = glm::normalize(glm::cross(forward, right)); camup = normalizev3(crossv3(right, camforw)); // Perform the rotation about the Y axis last. static const vec3 UP = (vec3){{0, 1, 0}}; static const vec3 DOWN = (vec3){{0, -1, 0}}; if (dotv3(UP, camup) < 0) { camforw = normalizev3(rotatev3(camforw, DOWN, -a.d[1])); camup = normalizev3(rotatev3(camup, DOWN, -a.d[1])); } else { camforw = normalizev3(rotatev3(camforw, UP, -a.d[1])); camup = normalizev3(rotatev3(camup, UP, -a.d[1])); } } GLuint loadRGBTexture(unsigned char* buf, unsigned int w, unsigned int h) { GLuint t = 0; glGenTextures(1, &t); glBindTexture(GL_TEXTURE_2D, t); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, 3, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, buf); return t; } void LoadModelArrays( // HUGE important note! these depend on the math library using // f_ as float and not double! // Remember that! vec3* points, uint npoints, vec3* colors, vec3* normals, vec3* texcoords) { if (!points) return; FreeModelArray(); ModelArrayLoaded = 1; ModelArray.npoints = npoints; ModelArray.points = malloc(sizeof(float) * npoints * 3); if (normals) ModelArray.normals = malloc(sizeof(float) * npoints * 3); if (texcoords) ModelArray.texcoords = malloc(sizeof(float) * npoints * 2); if (colors) ModelArray.colors = malloc(sizeof(float) * npoints * 3); for (uint i = 0; i < npoints; i++) { if (colors) { // Fix for TinyGL color interpolation. ModelArray.colors[i * 3 + 0] = colors[i].d[0]; ModelArray.colors[i * 3 + 1] = colors[i].d[1]; ModelArray.colors[i * 3 + 2] = colors[i].d[2]; } if (texcoords) { ModelArray.texcoords[i * 2 + 0] = texcoords[i].d[0]; ModelArray.texcoords[i * 2 + 1] = texcoords[i].d[1]; } if (normals) { ModelArray.normals[i * 3 + 0] = normals[i].d[0]; ModelArray.normals[i * 3 + 1] = normals[i].d[1]; ModelArray.normals[i * 3 + 2] = normals[i].d[2]; } ModelArray.points[i * 3 + 0] = points[i].d[0]; ModelArray.points[i * 3 + 1] = points[i].d[1]; ModelArray.points[i * 3 + 2] = points[i].d[2]; } } // Without display list void drawModelArrays( // HUGE important note! these depend on the math library using // f_ as float and not double! // Remember that! vec3* points, uint npoints, vec3* colors, vec3* normals, vec3* texcoords) { if (!points) return; glBegin(GL_TRIANGLES); for (uint i = 0; i < npoints; i++) { if (colors) { // Fix for TinyGL color interpolation. glColor3f(colors[i].d[0], colors[i].d[1], colors[i].d[2]); } if (texcoords) glTexCoord2f(texcoords[i].d[0], texcoords[i].d[1]); if (normals) glNormal3f(normals[i].d[0], normals[i].d[1], normals[i].d[2]); glVertex3f(points[i].d[0], points[i].d[1], points[i].d[2]); } glEnd(); } GLuint createModelDisplayList( // HUGE important note! these depend on the math library using // f_ as float and not double! // Remember that! vec3* points, uint npoints, vec3* colors, vec3* normals, vec3* texcoords) { GLuint ret = 0; if (!points) return 0; ret = glGenLists(1); glNewList(ret, GL_COMPILE); glBegin(GL_TRIANGLES); for (uint i = 0; i < npoints; i++) { if (colors) { glColor3f(colors[i].d[0], colors[i].d[1], colors[i].d[2]); } if (texcoords) glTexCoord2f(texcoords[i].d[0], texcoords[i].d[1]); if (normals) glNormal3f(normals[i].d[0], normals[i].d[1], normals[i].d[2]); glVertex3f(points[i].d[0], points[i].d[1], points[i].d[2]); } // printf("\ncreateModelDisplayList is not the problem.\n"); glEnd(); glEndList(); return ret; } GLubyte stipplepattern[128] = {0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55}; #define BEGIN_EVENT_HANDLER \ void events(SDL_Event* e) { \ switch (e->type) { #define E_KEYSYM e->key.keysym.sym #define END_EVENT_HANDLER \ } \ } #define EVENT_HANDLER events #define E_MOTION e->motion #define E_BUTTON e->button.button #define E_WINEVENT e->window.event #define E_WINW e->window.data1 #define E_WINH e->window.data2 int isRunning = 1; /* mousex = (kHeld & KEY_Y)?-30:0 + (kHeld & KEY_A)?30:0; mousey = (kHeld & KEY_X)?-30:0 + (kHeld & KEY_B)?30:0; */ BEGIN_EVENT_HANDLER case SDL_KEYDOWN: switch (E_KEYSYM) { case SDLK_w: wasdstate[0] = 1; break; case SDLK_a: wasdstate[1] = 1; break; case SDLK_s: wasdstate[2] = 1; break; case SDLK_d: wasdstate[3] = 1; break; case SDLK_UP: mousey = -30; break; case SDLK_DOWN: mousey = 30; break; case SDLK_LEFT: mousex = -30; break; case SDLK_RIGHT: mousex = 30; break; case SDLK_ESCAPE: case SDLK_q: isRunning = 0; break; default: break; } break; case SDL_KEYUP: switch (E_KEYSYM) { case SDLK_w: wasdstate[0] = 0; break; case SDLK_a: wasdstate[1] = 0; break; case SDLK_s: wasdstate[2] = 0; break; case SDLK_d: wasdstate[3] = 0; break; case SDLK_UP: case SDLK_DOWN: mousey = 0; break; case SDLK_LEFT: case SDLK_RIGHT: mousex = 0; break; default: break; } break; case SDL_QUIT: isRunning = 0; break; END_EVENT_HANDLER int main(int argc, char** argv) { // initialize SDL video: int winSizeX = 640; int winSizeY = 480; char needsRGBAFix = 0; unsigned int count = 40; GLuint modelDisplayList = 0; GLuint buffers[4]; // pos,color,normal,texcoord int dlExists = 0; int doTextures = 1; char* modelName = "extrude.obj"; #ifdef PLAY_MUSIC track* myTrack = NULL; #endif unsigned int fps = 0; if (argc > 1) { char* larg = argv[0]; for (int i = 1; i < argc; i++) { if (!strcmp(larg, "-w")) winSizeX = atoi(argv[i]); if (!strcmp(larg, "-h")) winSizeY = atoi(argv[i]); if (!strcmp(larg, "-fps")) fps = strtoull(argv[i], 0, 10); if (!strcmp(larg, "-count")) count = strtoull(argv[i], 0, 10); if (!strcmp(larg, "-m")) modelName = argv[i]; if (!strcmp(argv[i], "-notexture") || !strcmp(larg, "-notexture")) doTextures = 0; if (!strcmp(argv[i], "-arrays")) testingModelArrays = 1; if (!strcmp(argv[i], "-copy")) testingCopyImage2D = 1; if (!strcmp(argv[i], "-blend")) doblend = 1; larg = argv[i]; } } #ifdef PLAY_MUSIC if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) { #else if (SDL_Init(SDL_INIT_VIDEO) < 0) { #endif fprintf(stderr, "ERROR: cannot initialize SDL video.\n"); return 1; } #ifdef PLAY_MUSIC ainit(0); #endif SDL_Surface* screen = NULL; if ((screen = SDL_SetVideoMode(winSizeX, winSizeY, TGL_FEATURE_RENDER_BITS, SDL_SWSURFACE)) == 0) { fprintf(stderr, "ERROR: Video mode set failed.\n"); return 1; } printf("\nRMASK IS %u", screen->format->Rmask); printf("\nGMASK IS %u", screen->format->Gmask); printf("\nBMASK IS %u", screen->format->Bmask); printf("\nAMASK IS %u", screen->format->Amask); #if TGL_FEATURE_RENDER_BITS == 32 if (screen->format->Rmask != 0x00FF0000 || screen->format->Gmask != 0x0000FF00 || screen->format->Bmask != 0x000000FF) { needsRGBAFix = 1; printf("\nYour screen is using an RGBA output different than this library expects."); printf("\nYou should consider using the 16 bit version for optimal performance"); } #endif printf("\nRSHIFT IS %u", screen->format->Rshift); printf("\nGSHIFT IS %u", screen->format->Gshift); printf("\nBSHIFT IS %u", screen->format->Bshift); printf("\nASHIFT IS %u\n", screen->format->Ashift); fflush(stdout); #ifdef PLAY_MUSIC myTrack = lmus("WWGW.mp3"); mplay(myTrack, -1, 1000); #endif SDL_ShowCursor(SDL_DISABLE); SDL_WM_SetCaption(argv[0], 0); // initialize TinyGL: int mode; switch (screen->format->BitsPerPixel) { case 8: fprintf(stderr, "ERROR: Palettes are currently not supported.\n"); fprintf(stderr, "\nUnsupported by maintainer!!!"); return 1; case 16: // fprintf(stderr,"\nUnsupported by maintainer!!!"); mode = ZB_MODE_5R6G5B; // return 1; break; case 24: fprintf(stderr, "\nUnsupported by maintainer!!!"); mode = ZB_MODE_RGB24; return 1; break; case 32: mode = ZB_MODE_RGBA; break; default: return 1; break; } ZBuffer* frameBuffer = NULL; if (TGL_FEATURE_RENDER_BITS == 32) frameBuffer = ZB_open(winSizeX, winSizeY, ZB_MODE_RGBA, 0); else frameBuffer = ZB_open(winSizeX, winSizeY, ZB_MODE_5R6G5B, 0); glInit(frameBuffer); srand(time(NULL)); glShadeModel(GL_SMOOTH); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glSetEnableSpecular(0); static GLfloat white[4] = {1.0, 1.0, 1.0, 0.0}; static GLfloat pos[4] = {5, 5, 10, 0.0}; // Light at infinity. glLightfv(GL_LIGHT0, GL_POSITION, pos); glLightfv(GL_LIGHT0, GL_DIFFUSE, white); // glLightfv( GL_LIGHT0, GL_AMBIENT, white); // glLightfv( GL_LIGHT0, GL_SPECULAR, white); glEnable(GL_CULL_FACE); // glDisable( GL_LIGHTING ); glEnable(GL_LIGHT0); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glEnable(GL_COLOR_MATERIAL); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glClearColor(0, 0, 0, 0); glClearDepth(1.0f); glClearColor(0, 0, 0.3, 0); glDisable(GL_TEXTURE_2D); glEnable(GL_DEPTH_TEST); // glDisable(GL_LIGHTING); glShadeModel(GL_SMOOTH); // glDisable(GL_DEPTH_TEST); double t = 0; glViewport(0, 0, winSizeX, winSizeY); // glEnable(GL_POLYGON_STIPPLE); glPolygonStipple(stipplepattern); // initScene(); { objraw omodel; model m = initmodel(); omodel = tobj_load(modelName); if (!omodel.positions) { puts("\nERROR! No positions in model. Aborting...\n"); } else { m = tobj_tomodel(&omodel); printf("\nHas %d points.\n", m.npoints); if (!testingModelArrays) { modelDisplayList = createModelDisplayList(m.d, m.npoints, m.c, m.n, m.t); dlExists = 1; } else { LoadModelArrays(m.d, m.npoints, m.c, m.n, m.t); /* if(ModelArray.colors)glEnableClientState(GL_COLOR_ARRAY); if(ModelArray.points)glEnableClientState(GL_VERTEX_ARRAY); if(ModelArray.normals)glEnableClientState(GL_NORMAL_ARRAY); if(ModelArray.texcoords)glEnableClientState(GL_TEXTURE_COORD_ARRAY); if(ModelArray.points)glVertexPointer(3,GL_FLOAT,0,ModelArray.points); if(ModelArray.normals)glNormalPointer(GL_FLOAT,0,ModelArray.normals); //Must be 3! if(ModelArray.colors)glColorPointer(3,GL_FLOAT,0,ModelArray.colors); if(ModelArray.texcoords)glTexCoordPointer(2,GL_FLOAT,0,ModelArray.texcoords); */ glGenBuffers(4, buffers); for (int i = 0; i < 4; i++) { printf("\nBuffer %d is %d", i, buffers[i]); if (buffers[i] == 0) { printf("\nBuffer allocation failed for buffer %d!\n", i); return 1; } } glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); /*Done multiple times to test and make sure that data isn't leaked*/ puts("\nTesting glBufferData data integrity\n"); glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * ModelArray.npoints, ModelArray.points, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * ModelArray.npoints, ModelArray.points, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * ModelArray.npoints, ModelArray.points, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * ModelArray.npoints, ModelArray.points, GL_STATIC_DRAW); if (glMapBuffer(GL_ARRAY_BUFFER, 0) == NULL) printf("\nglBufferData failed for buffer %d!\n", 0); glBindBufferAsArray(GL_VERTEX_BUFFER, buffers[0], GL_FLOAT, 3, 0); if (ModelArray.colors) { glBindBuffer(GL_ARRAY_BUFFER, buffers[1]); glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * ModelArray.npoints, ModelArray.colors, GL_STATIC_DRAW); glBindBufferAsArray(GL_COLOR_BUFFER, buffers[1], GL_FLOAT, 3, 0); } if (ModelArray.normals) { glBindBuffer(GL_ARRAY_BUFFER, buffers[2]); glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * ModelArray.npoints, ModelArray.normals, GL_STATIC_DRAW); glBindBufferAsArray(GL_NORMAL_BUFFER, buffers[2], GL_FLOAT, 3, 0); } if (ModelArray.texcoords) { glBindBuffer(GL_ARRAY_BUFFER, buffers[3]); glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 2 * ModelArray.npoints, ModelArray.texcoords, GL_STATIC_DRAW); glBindBufferAsArray(GL_TEXTURE_COORD_BUFFER, buffers[3], GL_FLOAT, 2, 0); } } freemodel(&m); } freeobjraw(&omodel); } GLuint tex = 0; if (doTextures) { int sw = 0, sh = 0, sc = 0; // sc goes unused. #if TGL_FEATURE_NO_DRAW_COLOR == 1 uchar* source_data = stbi_load("tex_hole.png", &sw, &sh, &sc, 3); #else uchar* source_data = stbi_load("tex.jpg", &sw, &sh, &sc, 3); #endif if (source_data) { tex = loadRGBTexture(source_data, sw, sh); free(source_data); } // tex = } // glDisable(GL_LIGHTING); // glEnable( GL_NORMALIZE ); // variables for timing: unsigned int frames = 0; unsigned int tNow = SDL_GetTicks(); unsigned int tLastFps = tNow; // main loop: while (isRunning) { ++frames; t += 0.016666f; tNow = SDL_GetTicks(); // do event handling: SDL_Event evt; mousex = 0; mousey = 0; while (SDL_PollEvent(&evt)) EVENT_HANDLER(&evt); /* switch(evt.type) { } */ // draw scene: #define WIDTH winSizeX #define HEIGHT winSizeY glMatrixMode(GL_PROJECTION); glLoadIdentity(); // gluPerspective(70,(float)WIDTH/(float)HEIGHT,1,512); mat4 matrix = perspective(70, (float)WIDTH / (float)HEIGHT, 1, 512); glLoadMatrixf(matrix.d); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glPushMatrix(); // Pushing on the LookAt Matrix. vec3 right = normalizev3(crossv3(camforw, camup)); // right.d[1] = 0; matrix = (lookAt(campos, addv3(campos, camforw), camup)); // Using right vector to correct for screen rotation. glLoadMatrixf(matrix.d); if (wasdstate[0]) campos = addv3(campos, scalev3(0.1, camforw)); if (wasdstate[2]) campos = addv3(campos, scalev3(-0.1, camforw)); if (wasdstate[1]) campos = addv3(campos, scalev3(-0.1, right)); if (wasdstate[3]) campos = addv3(campos, scalev3(0.1, right)); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); if (doTextures) glBindTexture(GL_TEXTURE_2D, tex); // glDisable(GL_BLEND); // Testing blending for textured triangles. // glDisable(GL_DEPTH_TEST); if (doblend) { glEnable(GL_BLEND); glDepthMask(GL_FALSE); glDisable(GL_DEPTH_TEST); } else { glDisable(GL_BLEND); } glBlendFunc(GL_ONE_MINUS_SRC_COLOR, GL_DST_COLOR); glBlendEquation(GL_FUNC_ADD); // glDisable(GL_TEXTURE_2D); // printf("\nNew triangle!\n"); if (!dlExists) { if (!testingModelArrays) { glDisable(GL_TEXTURE_2D); glBegin(GL_TRIANGLES); // glColor3f(0,0,1); glColor3f(1, 0, 0); glTexCoord2f(0, 0); glVertex3f(-1, -1, -10); glColor3f(0, 1, 0); glTexCoord2f(1, 0); glVertex3f(1, -1, -10); glColor3f(0, 0, 1); glTexCoord2f(0.5, 1); glVertex3f(0, 1, -10); // glColor3f(0,1,0); glEnd(); } else { if (doTextures) glEnable(GL_TEXTURE_2D); // glDisable(GL_TEXTURE_2D); glEnable(GL_POLYGON_STIPPLE); // puts("\nUSING ARRAYS!"); // glDisable(GL_COLOR_MATERIAL); for (unsigned int i = 0; i < count; i++) { glPushMatrix(); mat4 horiz_translation = translate((vec3){{8.0 * (i % 10), 0.0, 0.0}}); mat4 vert_translation = translate((vec3){{0.0, 8.0 * (i / 10), 0.0}}); const mat4 ztranslation = translate((vec3){{0, 0, -10}}); mat4 total_translation = multm4(multm4(horiz_translation, vert_translation), ztranslation); glMultMatrixf(total_translation.d); // glTranslatef((float)(i % 10) * 8.0, (float)(i / 10) * 8.0, -10); glBegin(GL_TRIANGLES); for (uint j = 0; j < ModelArray.npoints; j++) glArrayElement(j); glEnd(); glPopMatrix(); } glDisable(GL_POLYGON_STIPPLE); glDisable(GL_TEXTURE_2D); } } else { if (doTextures) glEnable(GL_TEXTURE_2D); // glDisable(GL_TEXTURE_2D); glEnable(GL_POLYGON_STIPPLE); // glDisable(GL_COLOR_MATERIAL); for (unsigned int i = 0; i < count; i++) { glPushMatrix(); mat4 horiz_translation = translate((vec3){{8.0 * (i % 10), 0.0, 0.0}}); mat4 vert_translation = translate((vec3){{0.0, 8.0 * (i / 10), 0.0}}); const mat4 ztranslation = translate((vec3){{0, 0, -10}}); mat4 total_translation = multm4(multm4(horiz_translation, vert_translation), ztranslation); glMultMatrixf(total_translation.d); // glTranslatef((float)(i % 10) * 8.0, (float)(i / 10) * 8.0, -10); glCallList(modelDisplayList); // drawModel( // m.d, m.npoints, // m.c, // m.n, // m.t // ); glPopMatrix(); } glDisable(GL_POLYGON_STIPPLE); if (doTextures) glDisable(GL_TEXTURE_2D); } // draw(); glPopMatrix(); // The view transform. rotateCamera(); glTextSize(GL_TEXT_SIZE16x16); glDrawText((unsigned char*)"\nModel Viewer Demo-\nTinyGL\nSDL 1.2\n", 0, 0, 0x000000FF); // swap buffers: if (SDL_MUSTLOCK(screen) && (SDL_LockSurface(screen) < 0)) { fprintf(stderr, "SDL ERROR: Can't lock screen: %s\n", SDL_GetError()); return 1; } if (testingCopyImage2D && doTextures) { glBindTexture(GL_TEXTURE_2D, tex); glReadBuffer(GL_FRONT); glCopyTexImage2D(GL_TEXTURE_2D, // 1 0, // 2 GL_RGBA, // 3 0, // 4 256, // 5 256, // 6 256, 0); } /* printf("\nRMASK IS %u",screen->format->Rmask); printf("\nGMASK IS %u",screen->format->Gmask); printf("\nBMASK IS %u",screen->format->Bmask); printf("\nAMASK IS %u",screen->format->Amask); */ // Quickly convert all pixels to the correct format #if TGL_FEATURE_RENDER_BITS == 32 if (needsRGBAFix) for (int i = 0; i < frameBuffer->xsize * frameBuffer->ysize; i++) { #define DATONE (frameBuffer->pbuf[i]) DATONE = ((DATONE & 0x000000FF)) << screen->format->Rshift | ((DATONE & 0x0000FF00) >> 8) << screen->format->Gshift | ((DATONE & 0x00FF0000) >> 16) << screen->format->Bshift; } #endif ZB_copyFrameBuffer(frameBuffer, screen->pixels, screen->pitch); if (SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen); SDL_Flip(screen); if (fps > 0) if ((1000 / fps) > (SDL_GetTicks() - tNow)) { SDL_Delay((1000 / fps) - (SDL_GetTicks() - tNow)); // Yay stable framerate! } // check for error conditions: char* sdl_error = SDL_GetError(); if (sdl_error[0] != '\0') { fprintf(stderr, "SDL ERROR: \"%s\"\n", sdl_error); SDL_ClearError(); } // update fps: if (tNow >= tLastFps + 5000) { printf("%i frames in %f secs, %f frames per second.\n", frames, (float)(tNow - tLastFps) * 0.001f, (float)frames * 1000.0f / (float)(tNow - tLastFps)); tLastFps = tNow; frames = 0; } } printf("%i frames in %f secs, %f frames per second.\n", frames, (float)(tNow - tLastFps) * 0.001f, (float)frames * 1000.0f / (float)(tNow - tLastFps)); // cleanup: glDeleteTextures(1, &tex); // glDeleteList(modelDisplayList); if (dlExists) glDeleteLists(modelDisplayList, 1); FreeModelArray(); ZB_close(frameBuffer); glClose(); if (SDL_WasInit(SDL_INIT_VIDEO)) SDL_QuitSubSystem(SDL_INIT_VIDEO); #ifdef PLAY_MUSIC mhalt(); Mix_FreeMusic(myTrack); acleanup(); #endif SDL_Quit(); return 0; }