int main(int argc, char **argv) { int i; int ret = -1; int screen = -1; int usealpha = 0; int fullscreen = 0; SDL_SysWMinfo info; SDL_Window *window = NULL; SDL_GLContext *ctx = NULL; for (i = 0; i < argc; i++) { if (!SDL_strncasecmp(argv[i], "-h", 2) || !SDL_strncasecmp(argv[i], "-?", 2)) { usage(argv); exit(0); } if (!SDL_strncasecmp(argv[i], "-c", 2)) useci = 1; else if (!SDL_strncasecmp(argv[i], "-i", 2)) interactive = 1; else if (!SDL_strncasecmp(argv[i], "-l", 2)) locolor = 1; else if (!SDL_strncasecmp(argv[i], "-m", 2)) useimm = 1; else if (!SDL_strncasecmp(argv[i], "-32", 3)) usealpha = 1; else if (!SDL_strncasecmp(argv[i], "-w", 2) && i < argc - 1) { int w = 0, h = 0; if (sscanf(argv[++i], "%dx%d", &w, &h) == 2 && w > 0 && h > 0) { width = w; height = h; printf("Window dimensions: %d x %d\n", width, height); } } else if (!SDL_strncasecmp(argv[i], "-p", 2) && i < argc - 1) { int npolys = atoi(argv[++i]); if (npolys > 0) { slices = stacks = (int)(sqrt((double)npolys / ((double)(3 * NSPHERES + 1)))); if (slices < 1) slices = stacks = 1; } } else if (!SDL_strncasecmp(argv[i], "-fs", 3)) { fullscreen = 1; } else if (!SDL_strncasecmp(argv[i], "-f", 2) && i < argc - 1) { int mf = atoi(argv[++i]); if (mf > 0) { maxframes = mf; printf("Number of frames to render: %d\n", maxframes); } } else if (!SDL_strncasecmp(argv[i], "-bt", 3) && i < argc - 1) { double temp = atof(argv[++i]); if (temp > 0.0) benchtime = temp; } else if (!SDL_strncasecmp(argv[i], "-sc", 3) && i < argc - 1) { int sc = atoi(argv[++i]); if (sc > 0) { screen = sc; printf("Rendering to screen %d\n", screen); } } else if (!SDL_strncasecmp(argv[i], "-s", 2)) { usestereo = 1; } } if (useci) { SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, usealpha ? 8 : 0); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 1); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0); } else { SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, usealpha ? 8 : 0); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 1); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_STEREO, usestereo); } // Initialize SDL for video output. if (SDL_Init(SDL_INIT_VIDEO) < 0) _throw("Unable to initialize SDL"); // Create our OpenGL window. window = SDL_CreateWindow("vogltest", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); if (!window) _throw("Unable to create OpenGL window"); ctx = SDL_GL_CreateContext(window); if (!ctx) _throw("Unable to create OpenGL context"); SDL_VERSION(&info.version); if (SDL_GetWindowWMInfo(window, &info) == SDL_TRUE) { const char *subsystem = "Unknown system"; switch(info.subsystem) { case SDL_SYSWM_UNKNOWN: break; case SDL_SYSWM_WINDOWS: subsystem = "Microsoft Windows(TM)"; break; case SDL_SYSWM_X11: subsystem = "X Window System"; break; case SDL_SYSWM_DIRECTFB: subsystem = "DirectFB"; break; case SDL_SYSWM_COCOA: subsystem = "Apple OS X"; break; case SDL_SYSWM_UIKIT: subsystem = "UIKit"; break; case SDL_SYSWM_WAYLAND: subsystem = "Wayland"; break; } printf("Running SDL version %d.%d.%d on '%s'\n", (int)info.version.major, (int)info.version.minor, (int)info.version.patch, subsystem); if (useci) { #ifdef __linux__ int n; XVisualInfo vinfo_template; XVisualInfo *vinfo; memset(&vinfo_template, 0, sizeof(vinfo_template)); vinfo_template.colormap_size = 256; vinfo = XGetVisualInfo(info.info.x11.display, VisualColormapSizeMask, &vinfo_template, &n); if (vinfo && (n > 0)) { ncolors = np2(vinfo->colormap_size); } #else // TODO: Just assume 256 for Windows? ncolors = 256; #endif if (ncolors < 32) _throw("Color map is not large enough"); _catch(setcolorscheme(window, ncolors, colorscheme)); } } fprintf(stderr, "Polygons in scene: %d\n", (NSPHERES * 3 + 1) * slices * stacks); if (fullscreen) { go_fullscreen(window, screen); } ret = event_loop(window); bailout: SDL_Quit(); return ret; }
int loadbmp(char *filename, unsigned char **buf, int *w, int *h, enum BMPPIXELFORMAT f, int align, int dstbottomup) { int fd=-1, bytesread, srcpitch, srcbottomup=1, srcps, dstpitch, retcode=0; unsigned char *tempbuf=NULL; bmphdr bh; int flags=O_RDONLY; dstbottomup=dstbottomup? 1:0; #ifdef _WIN32 flags|=O_BINARY; #endif if(!filename || !buf || !w || !h || f<0 || f>BMPPIXELFORMATS-1 || align<1) _throw("invalid argument to loadbmp()"); if((align&(align-1))!=0) _throw("Alignment must be a power of 2"); _unix(fd=open(filename, flags)); readme(fd, &bh.bfType, sizeof(unsigned short)); if(!littleendian()) bh.bfType=byteswap16(bh.bfType); if(bh.bfType==0x3650) { _catch(loadppm(&fd, buf, w, h, f, align, dstbottomup, 0)); goto finally; } if(bh.bfType==0x3350) { _catch(loadppm(&fd, buf, w, h, f, align, dstbottomup, 1)); goto finally; } readme(fd, &bh.bfSize, sizeof(unsigned int)); readme(fd, &bh.bfReserved1, sizeof(unsigned short)); readme(fd, &bh.bfReserved2, sizeof(unsigned short)); readme(fd, &bh.bfOffBits, sizeof(unsigned int)); readme(fd, &bh.biSize, sizeof(unsigned int)); readme(fd, &bh.biWidth, sizeof(int)); readme(fd, &bh.biHeight, sizeof(int)); readme(fd, &bh.biPlanes, sizeof(unsigned short)); readme(fd, &bh.biBitCount, sizeof(unsigned short)); readme(fd, &bh.biCompression, sizeof(unsigned int)); readme(fd, &bh.biSizeImage, sizeof(unsigned int)); readme(fd, &bh.biXPelsPerMeter, sizeof(int)); readme(fd, &bh.biYPelsPerMeter, sizeof(int)); readme(fd, &bh.biClrUsed, sizeof(unsigned int)); readme(fd, &bh.biClrImportant, sizeof(unsigned int)); if(!littleendian()) { bh.bfSize=byteswap(bh.bfSize); bh.bfOffBits=byteswap(bh.bfOffBits); bh.biSize=byteswap(bh.biSize); bh.biWidth=byteswap(bh.biWidth); bh.biHeight=byteswap(bh.biHeight); bh.biPlanes=byteswap16(bh.biPlanes); bh.biBitCount=byteswap16(bh.biBitCount); bh.biCompression=byteswap(bh.biCompression); bh.biSizeImage=byteswap(bh.biSizeImage); bh.biXPelsPerMeter=byteswap(bh.biXPelsPerMeter); bh.biYPelsPerMeter=byteswap(bh.biYPelsPerMeter); bh.biClrUsed=byteswap(bh.biClrUsed); bh.biClrImportant=byteswap(bh.biClrImportant); } if(bh.bfType!=0x4d42 || bh.bfOffBits<BMPHDRSIZE || bh.biWidth<1 || bh.biHeight==0) _throw("Corrupt bitmap header"); if((bh.biBitCount!=24 && bh.biBitCount!=32) || bh.biCompression!=BI_RGB) _throw("Only uncompessed RGB bitmaps are supported"); *w=bh.biWidth; *h=bh.biHeight; srcps=bh.biBitCount/8; if(*h<0) {*h=-(*h); srcbottomup=0;} srcpitch=(((*w)*srcps)+3)&(~3); dstpitch=(((*w)*ps[f])+(align-1))&(~(align-1)); if(srcpitch*(*h)+bh.bfOffBits!=bh.bfSize) _throw("Corrupt bitmap header"); if((tempbuf=(unsigned char *)malloc(srcpitch*(*h)))==NULL || (*buf=(unsigned char *)malloc(dstpitch*(*h)))==NULL) _throw("Memory allocation error"); if(lseek(fd, (long)bh.bfOffBits, SEEK_SET)!=(long)bh.bfOffBits) _throw(strerror(errno)); _unix(bytesread=read(fd, tempbuf, srcpitch*(*h))); if(bytesread!=srcpitch*(*h)) _throw("Read error"); pixelconvert(tempbuf, BMP_BGR, srcpitch, *buf, f, dstpitch, *w, *h, srcbottomup!=dstbottomup); finally: if(tempbuf) free(tempbuf); if(fd!=-1) close(fd); return retcode; }
int display(SDL_Window *window, int advance) { static int first = 1; static double start = 0., elapsed = 0., mpixels = 0.; static unsigned long frames = 0; static char temps[256]; GLfloat xaspect, yaspect; if (first) { buildfont(); GLfloat id4[] = { 1., 1., 1., 1. }; GLfloat light0_amb[] = { 0.3f, 0.3f, 0.3f, 1.0f }; GLfloat light0_dif[] = { 0.8f, 0.8f, 0.8f, 1.0f }; GLfloat light0_pos[] = { 1., 1., 1., 0. }; spherelist = glGenLists(1); if (!(spherequad = gluNewQuadric())) _throw("Could not allocate GLU quadric object"); glNewList(spherelist, GL_COMPILE); gluSphere(spherequad, 1.3, slices, stacks); glEndList(); if (!locolor) { if (useci) { glMaterialf(GL_FRONT, GL_SHININESS, 50.); } else { glMaterialfv(GL_FRONT, GL_AMBIENT, id4); glMaterialfv(GL_FRONT, GL_DIFFUSE, id4); glMaterialfv(GL_FRONT, GL_SPECULAR, id4); glMaterialf(GL_FRONT, GL_SHININESS, 50.); glLightfv(GL_LIGHT0, GL_AMBIENT, light0_amb); glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_dif); glLightfv(GL_LIGHT0, GL_SPECULAR, id4); } glLightfv(GL_LIGHT0, GL_POSITION, light0_pos); glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 180.); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); } if (locolor) glShadeModel(GL_FLAT); else glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); SDL_snprintf(temps, 255, "Measuring performance ..."); first = 0; } if (advance) { z -= 0.5; if (z < -29.) { if (useci) { colorscheme = (colorscheme + 1) % NSCHEMES; _catch(setcolorscheme(window, ncolors, colorscheme)); } z = -3.5; } outer_angle += 0.1f; if (outer_angle > 360.0f) outer_angle -= 360.0f; middle_angle -= 0.37f; if (middle_angle < -360.0f) middle_angle += 360.0f; inner_angle += 0.63f; if (inner_angle > 360.0f) inner_angle -= 360.0f; lonesphere_color += 0.005f; if (lonesphere_color > 1.0f) lonesphere_color -= 1.0f; } if (usestereo) { renderspheres(GL_BACK_LEFT); renderspheres(GL_BACK_RIGHT); } else { renderspheres(GL_BACK); } glDrawBuffer(GL_BACK); glPushAttrib(GL_CURRENT_BIT); glPushAttrib(GL_LIST_BIT); glPushAttrib(GL_ENABLE_BIT); glDisable(GL_LIGHTING); if (useci) glIndexf(254.); else glColor3f(1., 1., 1.); xaspect = (GLfloat)width / (GLfloat)(min(width, height)); yaspect = (GLfloat)height / (GLfloat)(min(width, height)); glRasterPos3f(-0.95f * xaspect, -0.95f * yaspect, -1.5f); glListBase(fontlistbase); glCallLists((GLsizei)strlen(temps), GL_UNSIGNED_BYTE, temps); glPopAttrib(); glPopAttrib(); glPopAttrib(); SDL_GL_SwapWindow(window); if (start > 0.) { elapsed += rrtime() - start; frames++; totalframes++; mpixels += (double)width * (double)height / 1000000.; if (elapsed > benchtime || (maxframes && totalframes > maxframes)) { SDL_snprintf(temps, 255, "%f frames/sec - %f Mpixels/sec", (double)frames / elapsed, mpixels / elapsed); printf("%s\n", temps); elapsed = mpixels = 0.; frames = 0; } } if (maxframes && totalframes > maxframes) goto bailout; start = rrtime(); return 0; bailout: if (spherequad) { gluDeleteQuadric(spherequad); spherequad = NULL; } return -1; }