CatchSparksEffect::CatchSparksEffect(EffectSettings *conf) : Effect() { flowerCount = conf->getIntegerOrDefault("flowercount", 30); blossomCount = conf->getIntegerOrDefault("blossomcount", 3); sparkCount = conf->getIntegerOrDefault("sparkcount", 30); blossomsize = conf->getFloatOrDefault("blossomsize", 12.0); sparksize = conf->getFloatOrDefault("sparksize", 10.0); xd = 4.0 / env->getMatrixWidth(); yd = 2.0 / env->getMatrixHeight(); Flower::setSparkCount(sparkCount); Flower::setBlossomCount(blossomCount); Flower::setAreaDetector(&detector); Flower::setxyd(xd, yd); flowers = new Flower[flowerCount]; int verticesTotal = flowerCount * (blossomCount + sparkCount); vertices = new GLfloat[2 * verticesTotal]; colors = new GLfloat[4 * verticesTotal]; for ( int i = 0; i < verticesTotal; ++i) { vertices[2*i] = 0.0; vertices[2*i+1] = 0.0; colors[4*i] = 1.0; colors[4*i+1] = 1.0; colors[4*i+2] = 1.0; colors[4*i+3] = 1.0; } unsigned int sparkoffset = blossomCount * 2 * flowerCount; // sparks are stored behind blossoms for (unsigned int i = 0; i < flowerCount; ++i) { flowers[i].setBlossomPointers(vertices + i * 2 * blossomCount, colors + i * 4 * blossomCount); flowers[i].setSparksPointers(vertices + sparkoffset + i * 2 * sparkCount, colors + 2*sparkoffset + i * 4 * sparkCount); flowers[i].reset(); } RGBAbmp *pic = loadBmp("data/blossom.bmp"); glGenTextures(1, &blossomTex); glBindTexture(GL_TEXTURE_2D, blossomTex); int textureType = GL_RGB; if (pic->bpp == 32) textureType = GL_RGBA ; gluBuild2DMipmaps(GL_TEXTURE_2D, pic->bpp/8, pic->width, pic->height, textureType, GL_UNSIGNED_BYTE, pic->data); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR); delete pic->data; delete pic; pic = loadBmp("data/whiteflare.bmp"); glGenTextures(1, &sparkTex); glBindTexture(GL_TEXTURE_2D, sparkTex); if (pic->bpp == 32) textureType = GL_RGBA ; gluBuild2DMipmaps(GL_TEXTURE_2D, pic->bpp/8, pic->width, pic->height, textureType, GL_UNSIGNED_BYTE, pic->data); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR); delete pic->data; delete pic; glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glVertexPointer(2, GL_FLOAT,0, vertices); glColorPointer(4, GL_FLOAT,0, colors); glColor3f(1.0, 1.0, 1.0); glEnable(GL_TEXTURE_2D); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_DST_ALPHA ); // This is how will our point sprite's size will be modified by // distance from the viewer float quadratic[] = { 1.0f, 0.0f, 0.01f }; glPointParameterfvARB( GL_POINT_DISTANCE_ATTENUATION_ARB, quadratic ); glPointParameterfARB( GL_POINT_SIZE_MIN_ARB, 1.0f ); glPointParameterfARB( GL_POINT_SIZE_MAX_ARB, 100.0f ); // Specify point sprite texture coordinate replacement mode for each // texture unit glTexEnvf( 0x8861, 0x8862, GL_TRUE ); glEnable( 0x8861 ); }
/* don't try alpha=GL_FALSE: gluScaleImage implementations seem to be buggy */ GLuint glmLoadTexture(const char *filename, GLboolean alpha, GLboolean repeat, GLboolean filtering, GLboolean mipmaps, GLfloat *texcoordwidth, GLfloat *texcoordheight) { GLuint tex; int width, height,pixelsize; int type; int filter_min, filter_mag; GLubyte *data, *rdata; double xPow2, yPow2; int ixPow2, iyPow2; int xSize2, ySize2; GLint retval; if(glm_do_init) glmImgInit(); #ifdef HAVE_SOIL tex = SOIL_load_OGL_texture(filename, SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_POWER_OF_TWO ); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &height); //glTexEnvf(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_REPLACE); *texcoordwidth = width; *texcoordheight = height; return tex; #endif /* fallback solution (PPM only) */ data = glmReadPPM(filename, alpha, &width, &height, &type); if(data != NULL) { DBG_(__glmWarning("glmLoadTexture(): got PPM for %s",filename)); goto DONE; } #ifdef HAVE_DEVIL data = glmReadDevIL(filename, alpha, &width, &height, &type); if(data != NULL) { DBG_(__glmWarning("glmLoadTexture(): got DevIL for %s",filename)); goto DONE; } #endif #ifdef HAVE_LIBJPEG data = glmReadJPG(filename, alpha, &width, &height, &type); if(data != NULL) { DBG_(__glmWarning("glmLoadTexture(): got JPG for %s",filename)); goto DONE; } #endif #ifdef HAVE_LIBPNG data = glmReadPNG(filename, alpha, &width, &height, &type); if(data != NULL) { DBG_(__glmWarning("glmLoadTexture(): got PNG for %s",filename)); goto DONE; } #endif #ifdef HAVE_LIBSDL_IMAGE data = glmReadSDL(filename, alpha, &width, &height, &type); if(data != NULL) { DBG_(__glmWarning("glmLoadTexture(): got SDL for %s",filename)); goto DONE; } #endif #ifdef HAVE_LIBSIMAGE data = glmReadSimage(filename, alpha, &width, &height, &type); if(data != NULL) { DBG_(__glmWarning("glmLoadTexture(): got simage for %s",filename)); goto DONE; } #endif __glmWarning("glmLoadTexture() failed: Unable to load texture from %s!", filename); DBG_(__glmWarning("glmLoadTexture() failed: tried PPM")); #ifdef HAVE_LIBJPEG DBG_(__glmWarning("glmLoadTexture() failed: tried JPEG")); #endif #ifdef HAVE_LIBSDL_IMAGE DBG_(__glmWarning("glmLoadTexture() failed: tried SDL_image")); #endif return 0; DONE: /*#define FORCE_ALPHA*/ #ifdef FORCE_ALPHA if(alpha && type == GL_RGB) { /* if we really want RGBA */ const unsigned int size = width * height; unsigned char *rgbaimage; unsigned char *ptri, *ptro; int i; rgbaimage = (unsigned char*)malloc(sizeof(unsigned char)* size * 4); ptri = data; ptro = rgbaimage; for(i=0; i<size; i++) { *(ptro++) = *(ptri++); *(ptro++) = *(ptri++); *(ptro++) = *(ptri++); *(ptro++) = 255; } free(data); data = rgbaimage; type = GL_RGBA; } #endif /* FORCE_ALPHA */ switch(type) { case GL_LUMINANCE: pixelsize = 1; break; case GL_RGB: case GL_BGR: pixelsize = 3; break; case GL_RGBA: case GL_BGRA: pixelsize = 4; break; default: __glmFatalError( "glmLoadTexture(): unknown type 0x%x", type); pixelsize = 0; break; } if((pixelsize*width) % 4 == 0) glPixelStorei(GL_UNPACK_ALIGNMENT, 4); else glPixelStorei(GL_UNPACK_ALIGNMENT, 1); xSize2 = width; if (xSize2 > gl_max_texture_size) xSize2 = gl_max_texture_size; ySize2 = height; if (ySize2 > gl_max_texture_size) ySize2 = gl_max_texture_size; if (_glmTextureTarget == GL_TEXTURE_2D) { //if(1) { /* scale image to power of 2 in height and width */ xPow2 = log((double)xSize2) / log(2.0); yPow2 = log((double)ySize2) / log(2.0); ixPow2 = (int)xPow2; iyPow2 = (int)yPow2; if (xPow2 != (double)ixPow2) ixPow2++; if (yPow2 != (double)iyPow2) iyPow2++; xSize2 = 1 << ixPow2; ySize2 = 1 << iyPow2; } DBG_(__glmWarning("gl_max_texture_size=%d / width=%d / xSize2=%d / height=%d / ySize2 = %d", gl_max_texture_size, width, xSize2, height, ySize2)); if((width != xSize2) || (height != ySize2)) { /* TODO: use glTexSubImage2D instead */ DBG_(__glmWarning("scaling texture")); rdata = (GLubyte*)malloc(sizeof(GLubyte) * xSize2 * ySize2 * pixelsize); if (!rdata) return 0; retval = gluScaleImage(type, width, height, GL_UNSIGNED_BYTE, data, xSize2, ySize2, GL_UNSIGNED_BYTE, rdata); free(data); data = rdata; } glGenTextures(1, &tex); /* Generate texture ID */ glBindTexture(_glmTextureTarget, tex); DBG_(__glmWarning("building texture %d",tex)); if(mipmaps && _glmTextureTarget != GL_TEXTURE_2D) { DBG_(__glmWarning("mipmaps only work with GL_TEXTURE_2D")); mipmaps = 0; } if(filtering) { filter_min = (mipmaps) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; filter_mag = GL_LINEAR; } else { filter_min = (mipmaps) ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST; filter_mag = GL_NEAREST; } glTexParameteri(_glmTextureTarget, GL_TEXTURE_MIN_FILTER, filter_min); glTexParameteri(_glmTextureTarget, GL_TEXTURE_MAG_FILTER, filter_mag); glTexParameteri(_glmTextureTarget, GL_TEXTURE_WRAP_S, (repeat) ? GL_REPEAT : GL_CLAMP); glTexParameteri(_glmTextureTarget, GL_TEXTURE_WRAP_T, (repeat) ? GL_REPEAT : GL_CLAMP); if(mipmaps && _glmTextureTarget == GL_TEXTURE_2D) { /* only works for GL_TEXTURE_2D */ #ifdef GL_GENERATE_MIPMAP_SGIS if(gl_sgis_generate_mipmap) { DBG_(__glmWarning("sgis mipmapping")); glTexParameteri(_glmTextureTarget, GL_GENERATE_MIPMAP_SGIS, GL_TRUE ); glTexImage2D(_glmTextureTarget, 0, type, xSize2, ySize2, 0, type, GL_UNSIGNED_BYTE, data); } else #endif { DBG_(__glmWarning("glu mipmapping")); gluBuild2DMipmaps(_glmTextureTarget, type, xSize2, ySize2, type, GL_UNSIGNED_BYTE, data); } } else { glTexImage2D(_glmTextureTarget, 0, type, xSize2, ySize2, 0, type, GL_UNSIGNED_BYTE, data); } /* Clean up and return the texture ID */ free(data); if (_glmTextureTarget == GL_TEXTURE_2D) { *texcoordwidth = 1.; /* texcoords are in [0,1] */ *texcoordheight = 1.; } else { *texcoordwidth = xSize2; /* size of texture coords */ *texcoordheight = ySize2; } return tex; }
//------------------------------------------------------------- //- LoadPCX //- Loads a PCX image (may have problems loading non powers of 2 textures //------------------------------------------------------------- bool CImage::LoadPCX() { //Palette entry struct SPCXPal { unsigned char m_ucColor[3]; }; SPCXPal Palette[256]; unsigned char * ucpPtr = m_ucpBuffer; unsigned char * ucpPixData = 0; unsigned char * ucpData = 0; //Check out the header of the PCX if(ucpPtr[0] != 10 || ucpPtr[1] != 5 || ucpPtr[2] != 1 || ucpPtr[3] != 8) { APP->Log(COLOR_RED, "%s is not a valid PCX texture", m_szFilename); delete [] m_ucpBuffer; } ucpPtr += 4; //Get the dimentions of the texture short sXMin = (ucpPtr[1] << 8) + ucpPtr[0]; short sYMin = (ucpPtr[3] << 8) + ucpPtr[2]; short sXMax = (ucpPtr[5] << 8) + ucpPtr[4]; short sYMax = (ucpPtr[7] << 8) + ucpPtr[6]; m_uiWidth = sXMax - sXMin + 1; m_uiHeight = sYMax - sYMin + 1; //move to 128 bytes into the file, where the px data is ucpPtr += 124; ucpPixData = new unsigned char[m_uiWidth * m_uiHeight]; //decompress the pallete indexes data unsigned int uiIdx = 0; unsigned int uiPixel = 0; while(uiPixel < m_uiWidth * m_uiHeight) { if(ucpPtr[uiIdx] > 191) { uiIdx++; for(int i = 0; i < (63 & ucpPtr[uiIdx-1]); i++) { ucpPixData[uiPixel] = ucpPtr[uiIdx]; uiPixel++; } uiIdx++; } else { ucpPixData[uiPixel] = ucpPtr[uiIdx]; uiIdx++; uiPixel++; } } //go read the palette info ucpPtr = m_ucpBuffer + m_uiFileLen - 769; if(ucpPtr[0] != 12) { APP->Log(COLOR_RED, "Bad palette in %s", m_szFilename); delete [] ucpPixData; return false; } ucpPtr++; memcpy(Palette, ucpPtr, sizeof(SPCXPal[256])); //use the palette to decompress to a 24 bit image ucpData = new unsigned char[m_uiWidth * m_uiHeight * 3]; uiIdx = 0; for(unsigned int i = 0; i < m_uiWidth * m_uiHeight; i++) { ucpData[uiIdx ] = Palette[ucpPixData[i]].m_ucColor[0]; ucpData[uiIdx+1] = Palette[ucpPixData[i]].m_ucColor[1]; ucpData[uiIdx+2] = Palette[ucpPixData[i]].m_ucColor[2]; uiIdx+=3; } m_uiImage = 0; glGenTextures(1, &m_uiImage); glBindTexture(GL_TEXTURE_2D, m_uiImage); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); if(m_bMipMap) { gluBuild2DMipmaps(GL_TEXTURE_2D, 3, m_uiWidth, m_uiHeight, GL_RGB, GL_UNSIGNED_BYTE, ucpData); } else { glTexImage2D(GL_TEXTURE_2D, 0, 3, m_uiWidth, m_uiHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, ucpData); } delete [] m_ucpBuffer; delete [] ucpPixData; delete [] ucpData; APP->Log(COLOR_GREEN, "PCX Image: %s Loaded", m_szFilename); return true; }
unsigned int MakeGlTexture(GLenum Format,const unsigned char *pixels,unsigned int w,unsigned int h,bool compressed, bool makeMips) { unsigned int texObject; // generate a texture object which will be used to reference the // data on the graphics card once loaded. glGenTextures(1,&texObject); // specify byte alignment glPixelStorei (GL_UNPACK_ALIGNMENT, 1); // bind the texture so we can edit it glBindTexture (GL_TEXTURE_2D, texObject); // make the texture repeat in the u and v texture directions glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // linearly filter the texture when it needs to be magnified glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // linearly filter textures into the distance glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // glTexImage2D copies the texture data from system memory onto the graphics // card. If we wish to use DXT compression then we simply change the internal // format parameter to glTexImage2D. // if(compressed) { switch(Format) { // case GL_RGB: if (makeMips) { gluBuild2DMipmaps(GL_TEXTURE_2D, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, w, h, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid *)pixels); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); } else { glTexImage2D (GL_TEXTURE_2D,0,GL_COMPRESSED_RGB_S3TC_DXT1_EXT,w,h,0,GL_RGB,GL_UNSIGNED_BYTE,pixels); } break; // case GL_RGBA: if (makeMips) { gluBuild2DMipmaps(GL_TEXTURE_2D, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *)pixels); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); } else { glTexImage2D (GL_TEXTURE_2D,0,GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,w,h,0,GL_RGBA,GL_UNSIGNED_BYTE,pixels); } break; // case GL_ALPHA: if (makeMips) { gluBuild2DMipmaps(GL_TEXTURE_2D, GL_ALPHA, w, h, GL_ALPHA, GL_UNSIGNED_BYTE, (GLvoid *)pixels); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); } else { glTexImage2D (GL_TEXTURE_2D,0,GL_ALPHA,w,h,0,GL_ALPHA,GL_UNSIGNED_BYTE,pixels); } break; default: ; } } else { if (makeMips) { gluBuild2DMipmaps(GL_TEXTURE_2D, Format, w, h, Format, GL_UNSIGNED_BYTE, (GLvoid *)pixels); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); } else { glTexImage2D (GL_TEXTURE_2D,0,Format,w,h,0,Format,GL_UNSIGNED_BYTE,pixels); } } return texObject; }
int main(int argc, char *argv[]) { unsigned *cloud; int texcomps, texwid, texht; GLUquadricObj *sphere; /* start and end of particles */ static GLfloat begin[] = {0.f, -25.f, 0.f}; static GLfloat end[] = {0.f,-100.f, 0.f}; static GLfloat fogcolor[] = {.4f, .4f, .4f, 1.f}; glutInitWindowSize(winwid, winht); glutInit(&argc, argv); if(argc > 1) { char *args = argv[1]; int done = GL_FALSE; while(!done) { switch(*args) { case 's': /* single buffer */ printf("Single Buffered\n"); dblbuf = GL_FALSE; break; case '-': /* do nothing */ break; case 0: done = GL_TRUE; break; } args++; } } if(dblbuf) glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL|GLUT_DOUBLE); else glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL); (void)glutCreateWindow("snow demo"); glutDisplayFunc(redraw); glutReshapeFunc(reshape); glutMouseFunc(mouse); glutMotionFunc(motion); glutKeyboardFunc(key); glutIdleFunc(idle); glutCreateMenu(menu); glutAddMenuEntry("Toggle Overcast (o, O)", OVERCAST); glutAddMenuEntry("Toggle Fog (f, F)", FOG); glutAddMenuEntry("Toggle Snow (s, S)", SNOW); glutAddMenuEntry("Bigger Flakes (+)", BIGGER); glutAddMenuEntry("Smaller Flakes (-)", SMALLER); glutAddMenuEntry("Reset Flake Size to One (r, R)", RESETSIZE); glutAddMenuEntry("Toggle Point Antialiasing (a, A)", ANTIALIAS); glutAddMenuEntry("Snow Blending (b, B)", BLEND); glutAddMenuEntry("Exit Program", EXIT); glutAttachMenu(GLUT_RIGHT_BUTTON); printf("OpenGL Version %s\n", glGetString(GL_VERSION)); /* draw a perspective scene */ glMatrixMode(GL_PROJECTION); glFrustum(-5., 5., -5., 5., 10., 1000.); glMatrixMode(GL_MODELVIEW); updateMV(); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* turn on features */ glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); /* place light 0 in the right place */ glLightfv(GL_LIGHT0, GL_POSITION, lightpos); glClearColor(0.f, 0.f, 1.f, 1.f); glFogfv(GL_FOG_COLOR, fogcolor); glFogi(GL_FOG_MODE, GL_LINEAR); glFogf(GL_FOG_START, -200.f); glFogf(GL_FOG_END, 200.f); glHint(GL_FOG_HINT, GL_NICEST); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); /* makes texturing faster, and looks better than GL_LINEAR */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glNewList(LIGHT, GL_COMPILE); glDisable(GL_LIGHTING); sphere = gluNewQuadric(); glColor3f(.7f, .2f, .7f); gluSphere(sphere, 5.f, 10, 10); gluDeleteQuadric(sphere); glEnable(GL_LIGHTING); glEndList(); /* 10 X 20; vary size with transforms */ /* one corner of house on origin; bottom on xz plane */ glNewList(HOUSE, GL_COMPILE); glBegin(GL_QUADS); /* walls of house */ glColor3f(1.f, 1.f, 0.f); /* front */ glNormal3f( 0.f, 0.f, 1.f); glVertex3i( 0, 0, 0); glVertex3i(10, 0, 0); glVertex3i(10,10, 0); glVertex3i( 0,10, 0); /* back */ glNormal3f( 0.f, 0.f, -1.f); glVertex3i( 0, 0, -20); glVertex3i( 0,10, -20); glVertex3i(10,10, -20); glVertex3i(10, 0, -20); /* left */ glNormal3f(-1, 0.f, 0.f); glVertex3i( 0, 0, 0); glVertex3i( 0, 10, 0); glVertex3i( 0, 10, -20); glVertex3i( 0, 0, -20); /* right */ glNormal3f( 1.f, 0.f, 0.f); glVertex3i(10, 0, 0); glVertex3i(10, 0, -20); glVertex3i(10, 10, -20); glVertex3i(10, 10, 0); /* roof of house */ glColor3f(.8f, .1f, .1f); /* left top */ glNormal3f(-.707f, .707f, 0.f); glVertex3i( 0, 10, 0); glVertex3i( 5, 15, 0); glVertex3i( 5, 15, -20); glVertex3i( 0, 10, -20); /* right top */ glNormal3f( .707f, .707f, 0.f); glVertex3i(10, 10, 0); glVertex3i(10, 10, -20); glVertex3i( 5, 15, -20); glVertex3i( 5, 15, 0); glEnd(); glBegin(GL_TRIANGLES); /* front */ glNormal3f( 0.f, 0.f, 1.f); glVertex3i( 0, 10, 0); glVertex3i(10, 10, 0); glVertex3i( 5, 15, 0); /* back */ glNormal3f( 0.f, 0.f, -1.f); glVertex3i( 0, 10, -20); glVertex3i( 5, 15, -20); glVertex3i(10, 10, -20); glEnd(); glEndList(); glEnable(GL_CULL_FACE); /* load pattern for current 2d texture */ cloud = read_texture("../../data/clouds.bw", &texwid, &texht, &texcomps); gluBuild2DMipmaps(GL_TEXTURE_2D, GL_LUMINANCE, texwid, texht, GL_RGBA, GL_UNSIGNED_BYTE, cloud); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND); free(cloud); initpart(&psys, begin, end, 200, 6000); updateptr = updatepart0; CHECK_ERROR("main()"); glutMainLoop(); return 0; }
//////////////////////////////////////////////////////////// /// Entry point of application /// /// \return Application exit code /// //////////////////////////////////////////////////////////// int main() { // Create the main window sf::RenderWindow window(sf::VideoMode(800, 600), "SFML OpenGL", sf::Style::Default, sf::ContextSettings(32)); window.setVerticalSyncEnabled(true); // Create a sprite for the background sf::Texture backgroundTexture; if (!backgroundTexture.loadFromFile("resources/background.jpg")) return EXIT_FAILURE; sf::Sprite background(backgroundTexture); // Load an OpenGL texture. // We could directly use a sf::Texture as an OpenGL texture (with its Bind() member function), // but here we want more control on it (generate mipmaps, ...) so we create a new one from an image GLuint texture = 0; { sf::Image image; if (!image.loadFromFile("resources/texture.jpg")) return EXIT_FAILURE; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, image.getSize().x, image.getSize().y, GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); } // Enable Z-buffer read and write glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glClearDepth(1.f); // Setup a perspective projection glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(90.f, 1.f, 1.f, 500.f); // Bind our texture glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture); glColor4f(1.f, 1.f, 1.f, 1.f); // Create a clock for measuring the time elapsed sf::Clock clock; // Start game loop while (window.isOpen()) { // Process events sf::Event event; while (window.pollEvent(event)) { // Close window : exit if (event.type == sf::Event::Closed) window.close(); // Escape key : exit if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape)) window.close(); // Adjust the viewport when the window is resized if (event.type == sf::Event::Resized) glViewport(0, 0, event.size.width, event.size.height); } // Draw the background window.pushGLStates(); window.draw(background); window.popGLStates(); // Activate the window before using OpenGL commands. // This is useless here because we have only one window which is // always the active one, but don't forget it if you use multiple windows window.setActive(); // Clear the depth buffer glClear(GL_DEPTH_BUFFER_BIT); // We get the position of the mouse cursor, so that we can move the box accordingly float x = sf::Mouse::getPosition(window).x * 200.f / window.getSize().x - 100.f; float y = -sf::Mouse::getPosition(window).y * 200.f / window.getSize().y + 100.f; // Apply some transformations glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(x, y, -100.f); glRotatef(clock.getElapsedTime().asSeconds() * 50.f, 1.f, 0.f, 0.f); glRotatef(clock.getElapsedTime().asSeconds() * 30.f, 0.f, 1.f, 0.f); glRotatef(clock.getElapsedTime().asSeconds() * 90.f, 0.f, 0.f, 1.f); // Draw a cube float size = 20.f; glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex3f(-size, -size, -size); glTexCoord2f(0, 1); glVertex3f(-size, size, -size); glTexCoord2f(1, 1); glVertex3f( size, size, -size); glTexCoord2f(1, 0); glVertex3f( size, -size, -size); glTexCoord2f(0, 0); glVertex3f(-size, -size, size); glTexCoord2f(0, 1); glVertex3f(-size, size, size); glTexCoord2f(1, 1); glVertex3f( size, size, size); glTexCoord2f(1, 0); glVertex3f( size, -size, size); glTexCoord2f(0, 0); glVertex3f(-size, -size, -size); glTexCoord2f(0, 1); glVertex3f(-size, size, -size); glTexCoord2f(1, 1); glVertex3f(-size, size, size); glTexCoord2f(1, 0); glVertex3f(-size, -size, size); glTexCoord2f(0, 0); glVertex3f(size, -size, -size); glTexCoord2f(0, 1); glVertex3f(size, size, -size); glTexCoord2f(1, 1); glVertex3f(size, size, size); glTexCoord2f(1, 0); glVertex3f(size, -size, size); glTexCoord2f(0, 1); glVertex3f(-size, -size, size); glTexCoord2f(0, 0); glVertex3f(-size, -size, -size); glTexCoord2f(1, 0); glVertex3f( size, -size, -size); glTexCoord2f(1, 1); glVertex3f( size, -size, size); glTexCoord2f(0, 1); glVertex3f(-size, size, size); glTexCoord2f(0, 0); glVertex3f(-size, size, -size); glTexCoord2f(1, 0); glVertex3f( size, size, -size); glTexCoord2f(1, 1); glVertex3f( size, size, size); glEnd(); // Draw some text on top of our OpenGL object window.pushGLStates(); sf::Text text("SFML / OpenGL demo"); text.setColor(sf::Color(255, 255, 255, 170)); text.setPosition(250.f, 450.f); window.draw(text); window.popGLStates(); // Finally, display the rendered frame on screen window.display(); } // Don't forget to destroy our texture glDeleteTextures(1, &texture); return EXIT_SUCCESS; }
/*! Loads a texture from a file and attaches it to an ITexture object. \param filename Path to an image file to load the texture. \param pTexture A valid pointer to an existing ITexture instance to attach the loaded texture. \note Currently only bitmap (using gluaux library) and tga files are supported. */ bool TextureLoaderGL::load(const std::string& filename, ITexture* pTexture) { if(!pTexture) return false; // make a format check and use base class pointer for loader ITextureFile* loader = 0; try { std::string namefile(filename); #ifdef WIN32 if(namefile.find_last_of(".bmp") == namefile.size() - 1) loader = new BmpFile; else #endif if(namefile.find_last_of(".tga") == namefile.size() - 1) loader = new TgaFile; else { return false; } if(!loader->load(filename)) { delete loader; return false; } GLenum mode = GL_RGB8; switch (loader->getNBits()) { case 8: mode = GL_ALPHA; break; case 24: mode = GL_RGB; break; case 32: mode = GL_RGBA; break; } // Generate a texture with the associative texture ID stored in the array glGenTextures(1, &pTexture->m_TexID); // This sets the alignment requirements for the start of each pixel row in memory. glPixelStorei (GL_UNPACK_ALIGNMENT, 1); // Bind the texture to the texture arrays index and init the texture glBindTexture(GL_TEXTURE_2D, pTexture->getTextureID()); glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // Lastly, we need to tell OpenGL the quality of our texture map. GL_LINEAR is the smoothest. // GL_NEAREST is faster than GL_LINEAR, but looks blochy and pixelated. Good for slower computers though. // Read more about the MIN and MAG filters at the bottom of main.cpp glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); // Build Mipmaps (builds different versions of the picture for distances - looks better) gluBuild2DMipmaps(GL_TEXTURE_2D, 3, loader->getWidth(), loader->getHeight(), mode, GL_UNSIGNED_BYTE, loader->getData()); m_TextureList.push_back(pTexture->getTextureID()); delete loader; return true; } catch(...) { delete loader; return false; } }
//////////////////////////////////////////////////////////// /// Entry point of application /// /// \return Application exit code /// //////////////////////////////////////////////////////////// int main() { // Create main window sf::RenderWindow App(sf::VideoMode(800, 600), "SFML OpenGL"); App.PreserveOpenGLStates(true); // Create a sprite for the background sf::Image BackgroundImage; if (!BackgroundImage.LoadFromFile("datas/opengl/background.jpg")) return EXIT_FAILURE; sf::Sprite Background(BackgroundImage); // Load an OpenGL texture. // We could directly use a sf::Image as an OpenGL texture (with its Bind() member function), // but here we want more control on it (generate mipmaps, ...) so we create a new one GLuint Texture = 0; { sf::Image Image; if (!Image.LoadFromFile("datas/opengl/texture.jpg")) return EXIT_FAILURE; glGenTextures(1, &Texture); glBindTexture(GL_TEXTURE_2D, Texture); gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, Image.GetWidth(), Image.GetHeight(), GL_RGBA, GL_UNSIGNED_BYTE, Image.GetPixelsPtr()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); } // Enable Z-buffer read and write glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glClearDepth(1.f); // Setup a perspective projection glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(90.f, 1.f, 1.f, 500.f); // Bind our texture glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, Texture); glColor4f(1.f, 1.f, 1.f, 1.f); // Create a clock for measuring the time elapsed sf::Clock Clock; // Start game loop while (App.IsOpened()) { // Process events sf::Event Event; while (App.GetEvent(Event)) { // Close window : exit if (Event.Type == sf::Event::Closed) App.Close(); // Escape key : exit if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Escape)) App.Close(); // Adjust the viewport when the window is resized if (Event.Type == sf::Event::Resized) glViewport(0, 0, Event.Size.Width, Event.Size.Height); } // Draw background App.Draw(Background); // Clear depth buffer glClear(GL_DEPTH_BUFFER_BIT); // Apply some transformations glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.f, 0.f, -200.f); glRotatef(Clock.GetElapsedTime() * 50, 1.f, 0.f, 0.f); glRotatef(Clock.GetElapsedTime() * 30, 0.f, 1.f, 0.f); glRotatef(Clock.GetElapsedTime() * 90, 0.f, 0.f, 1.f); // Draw a cube glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex3f(-50.f, -50.f, -50.f); glTexCoord2f(0, 1); glVertex3f(-50.f, 50.f, -50.f); glTexCoord2f(1, 1); glVertex3f( 50.f, 50.f, -50.f); glTexCoord2f(1, 0); glVertex3f( 50.f, -50.f, -50.f); glTexCoord2f(0, 0); glVertex3f(-50.f, -50.f, 50.f); glTexCoord2f(0, 1); glVertex3f(-50.f, 50.f, 50.f); glTexCoord2f(1, 1); glVertex3f( 50.f, 50.f, 50.f); glTexCoord2f(1, 0); glVertex3f( 50.f, -50.f, 50.f); glTexCoord2f(0, 0); glVertex3f(-50.f, -50.f, -50.f); glTexCoord2f(0, 1); glVertex3f(-50.f, 50.f, -50.f); glTexCoord2f(1, 1); glVertex3f(-50.f, 50.f, 50.f); glTexCoord2f(1, 0); glVertex3f(-50.f, -50.f, 50.f); glTexCoord2f(0, 0); glVertex3f(50.f, -50.f, -50.f); glTexCoord2f(0, 1); glVertex3f(50.f, 50.f, -50.f); glTexCoord2f(1, 1); glVertex3f(50.f, 50.f, 50.f); glTexCoord2f(1, 0); glVertex3f(50.f, -50.f, 50.f); glTexCoord2f(0, 1); glVertex3f(-50.f, -50.f, 50.f); glTexCoord2f(0, 0); glVertex3f(-50.f, -50.f, -50.f); glTexCoord2f(1, 0); glVertex3f( 50.f, -50.f, -50.f); glTexCoord2f(1, 1); glVertex3f( 50.f, -50.f, 50.f); glTexCoord2f(0, 1); glVertex3f(-50.f, 50.f, 50.f); glTexCoord2f(0, 0); glVertex3f(-50.f, 50.f, -50.f); glTexCoord2f(1, 0); glVertex3f( 50.f, 50.f, -50.f); glTexCoord2f(1, 1); glVertex3f( 50.f, 50.f, 50.f); glEnd(); // Draw some text on top of our OpenGL object sf::String Text("This is a rotating cube"); Text.SetPosition(250.f, 300.f); Text.SetColor(sf::Color(128, 0, 128)); App.Draw(Text); // Finally, display the rendered frame on screen App.Display(); } // Don't forget to destroy our texture glDeleteTextures(1, &Texture); return EXIT_SUCCESS; }
// posX, posY: posición relativa o absoluta // ( 0, 0): Esquina izquierda superior // (100, 100): Esquina derecha inferior // color : Color del texto // relative : TRUE = ubicación relativa, FALSE = ubicación absoluta void RenderText( char* text, TTF_Font* font, GLuint posX, GLuint posY, COLOR* color, GLboolean relative ) { /* Posición del texto */ if( relative ) { posX = (GLuint)(posX*screenWidth/100.0f); posY = (GLuint)(posY*screenHeight/100.0f); } /* Color del texto */ SDL_Color fontColor = { (Uint8)color->r*255, (Uint8)color->g*255, (Uint8)color->b*255 }; /* Surface del texto */ textSurface = TTF_RenderUTF8_Blended( font, text, fontColor ); /* Guardo los atributos */ glPushAttrib( GL_ENABLE_BIT ); /* Deshabilito la luz y habilito transparencia */ glDisable( GL_DEPTH_TEST ); glDisable( GL_LIGHTING ); glEnable( GL_TEXTURE_2D ); glEnable( GL_BLEND ); glColor3f( 1.0f, 1.0f, 1.0f ); /* Creo la textura del texto */ glBindTexture( GL_TEXTURE_2D, textTexture ); gluBuild2DMipmaps( GL_TEXTURE_2D, textSurface->format->BytesPerPixel, textSurface->w, textSurface->h, GL_BGRA, GL_UNSIGNED_BYTE, textSurface->pixels ); /* Proyección y Traslación */ glMatrixMode( GL_PROJECTION ); glPushMatrix(); glLoadIdentity(); gluOrtho2D( 0, screenWidth, screenHeight, 0 ); glMatrixMode( GL_MODELVIEW ); glPushMatrix(); glLoadIdentity(); /* Dibujo en un cuadro */ glBegin( GL_QUADS ); glTexCoord2i( 0, 0 ); glVertex2i( posX, posY ); glTexCoord2i( 1, 0 ); glVertex2i( posX + textSurface->w, posY ); glTexCoord2i( 1, 1 ); glVertex2i( posX + textSurface->w, posY + textSurface->h ); glTexCoord2i( 0, 1 ); glVertex2i( posX, posY + textSurface->h ); glEnd(); /* Proyección y Traslación */ glMatrixMode( GL_PROJECTION ); glPopMatrix(); glMatrixMode( GL_MODELVIEW ); glPopMatrix(); /* Restauro los atributos */ glPopAttrib(); /* Libero la superficie */ SDL_FreeSurface( textSurface ); }
/* init */ int init(void) { int i,num_vertex,width,height; float *vertex; unsigned char *data; float rmax; vec3 min,max; vec4 plane_s = { 1.0, 0.0, 0.0, 0.0 }; vec4 plane_t = { 0.0, 1.0, 0.0, 0.0 }; vec4 plane_r = { 0.0, 0.0, 1.0, 0.0 }; vec4 plane_q = { 0.0, 0.0, 0.0, 1.0 }; GLenum err; err = glewInit(); if (GLEW_OK != err) { fprintf(stderr, "glewInit() error: %s\n", glewGetErrorString(err)); } glClearDepth(1); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glEnable(GL_LIGHT0); glPointSize(4); glTexGenfv(GL_S,GL_EYE_PLANE,plane_s); glTexGenfv(GL_T,GL_EYE_PLANE,plane_t); glTexGenfv(GL_R,GL_EYE_PLANE,plane_r); glTexGenfv(GL_Q,GL_EYE_PLANE,plane_q); glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR); glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR); glTexGeni(GL_R,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR); glTexGeni(GL_Q,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP); glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,SIZE,SIZE,0,GL_RGB, GL_UNSIGNED_BYTE,NULL); glGenTextures(1,&texture_id); glBindTexture(GL_TEXTURE_2D,texture_id); if((data = load_jpeg("data/ground.jpg",&width,&height))) { glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); gluBuild2DMipmaps(GL_TEXTURE_2D,4,width,height,GL_RGBA, GL_UNSIGNED_BYTE,data); free(data); } vertex = load_3ds("data/mesh.3ds",&num_vertex); if(!vertex) return -1; v_set(999999,999999,999999,min); v_set(-999999,-999999,-999999,max); for(i = 0; i < num_vertex; i++) { int j; float *v = &vertex[i << 3]; for(j = 0; j < 3; j++) { if(min[j] > v[j]) min[j] = v[j]; if(max[j] < v[j]) max[j] = v[j]; } } v_add(min,max,min); v_scale(min,0.5,min); for(i = 0; i < num_vertex; i++) { v_sub(&vertex[i << 3],min,&vertex[i << 3]); } for(i = 0, rmax = 0; i < num_vertex; i++) { float r = sqrt(v_dot(&vertex[i << 3],&vertex[i << 3])); if(r > rmax) rmax = r; } rmax = 0.8 / rmax; for(i = 0; i < num_vertex; i++) { v_scale(&vertex[i << 3],rmax,&vertex[i << 3]); } mesh_id = glGenLists(1); glNewList(mesh_id,GL_COMPILE); glBegin(GL_TRIANGLES); for(i = 0; i < num_vertex; i++) { glNormal3fv((float*)&vertex[i << 3] + 3); glVertex3fv((float*)&vertex[i << 3]); } glEnd(); glEndList(); vertex = load_3ds("data/ground.3ds",&num_vertex); if(!vertex) return -1; ground_id = glGenLists(1); glNewList(ground_id,GL_COMPILE); glBegin(GL_TRIANGLES); for(i = 0; i < num_vertex; i++) { glTexCoord2fv((float*)&vertex[i << 3] + 6); glNormal3fv((float*)&vertex[i << 3] + 3); glVertex3fv((float*)&vertex[i << 3]); } glEnd(); glEndList(); image = malloc(SIZE * SIZE * 4); return 0; }
void PImage::updatePixels() { gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height, GL_RGBA, GL_UNSIGNED_BYTE, texturebuffer); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)texturebuffer); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); }
void texture(void) { texenv(); gluBuild2DMipmaps(GL_TEXTURE_2D, 3, iwidth, iheight, GL_RGB, GL_UNSIGNED_BYTE, image); }
static void init_gl(ModeInfo *mi) { cube21_conf *cp = &cube21[MI_SCREEN(mi)]; #ifdef MIPMAP int status; #endif parse_colmode(); cp->wire = MI_IS_WIREFRAME(mi); cp->cmat = !cp->wire && (colmode != CUBE21_COLOR_WHITE); if(MI_IS_MONO(mi)) { tex = False; cp->cmat = False; } # ifdef HAVE_JWZGLES /* #### glPolygonMode other than GL_FILL unimplemented */ cp->wire = 0; # endif if(cp->wire) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); return; } if(!tex) cp->color_inner[0] = cp->color_inner[1] = cp->color_inner[2] = 0.4; else cp->color_inner[0] = cp->color_inner[1] = cp->color_inner[2] = 1.0; glClearDepth(1.0); glDrawBuffer(GL_BACK); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glShadeModel(GL_FLAT); glDepthFunc(GL_LESS); glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT0, GL_POSITION, position0); glLightfv(GL_LIGHT1, GL_AMBIENT, ambient); glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT1, GL_POSITION, position1); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); glEnable(GL_LIGHTING); glEnable(GL_NORMALIZE); glEnable(GL_COLOR_MATERIAL); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, material_ambient); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material_diffuse); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material_specular); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess); if(!tex) return; glEnable(GL_TEXTURE_2D); #ifdef MIPMAP clear_gl_error(); status = gluBuild2DMipmaps(GL_TEXTURE_2D, 1, TEX_WIDTH, TEX_HEIGHT, GL_LUMINANCE, GL_UNSIGNED_BYTE, texture); if (status) { const char *s = gluErrorString(status); fprintf (stderr, "%s: error mipmapping texture: %s\n", progname, (s?s:"(unknown)")); exit (1); } check_gl_error("mipmapping"); #else glTexImage2D(GL_TEXTURE_2D, 0, 1, TEX_WIDTH, TEX_HEIGHT, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, cp->texture); #endif glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); #ifdef MIPMAP glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); #else glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); #endif }
GLuint platformLoadTextureFile(string theFilename, bool generateMipmaps, int *width, int *height) { #ifdef QuickTimeInstalled GLuint textureName; // the "name" by which OpenGL knows the texture unsigned char *pImageBuffer; // the buffer that contains the image data GWorldPtr pGWorld; // a gworld to load the image into int imageDepth; FSSpec fsspecImage; // FSSpec of the image to load #ifdef __APPLE__ CFURLRef imageURL; FSRef imagefsRef; #endif OSStatus err = noErr; // err return value long rowStride; // length, in bytes, of a pixel row in the image GraphicsImportComponent giComp; // component for importing image MatrixRecord matrix; Rect rectImage; // rectangle of source image PixMapHandle hPixMap; // handle to image pix map ImageDescriptionHandle hImageDesc; // handle to image description used to get image depth long imageWidth; long imageHeight; float imageAspect; long textureWidth; long textureHeight; // get the full path to the texture file string fileLocation; fileLocation = pathToResourceDirectory() + theFilename; #ifdef __APPLE__ // create a URL to the file from the C string imageURL = CFURLCreateWithBytes (kCFAllocatorDefault, (UInt8 *)fileLocation.c_str(), fileLocation.length(), kCFStringEncodingASCII, NULL); if (imageURL == NULL) { cout << "error getting URL for image file (image file may not exist): " << theFilename << endl; return 0; } // get a FSRef from the URL if (!CFURLGetFSRef(imageURL, &imagefsRef)) { cout << "error getting FSRef for image file:: " << theFilename << endl; CFRelease(imageURL); return 0; } // get the FSSpec from the FSRef if (FSGetCatalogInfo (&imagefsRef, kFSCatInfoNone, NULL, NULL, &fsspecImage, NULL)) { cout << "error getting FSSpec for image file: " << theFilename << endl; CFRelease(imageURL); return 0; } // release the URL (not needed any more) CFRelease(imageURL); #endif #ifdef _WIN32 // get an FSSpec from the pathname if (NativePathNameToFSSpec ((char *)fileLocation.c_str(), &fsspecImage, kErrorIfFileNotFound)) { cout << "error getting FSSpec for image file: " << fileLocation << endl; return 0; } #endif // save the onscreen graphics port GDHandle origDevice; CGrafPtr origPort; GetGWorld (&origPort, &origDevice); // get an importer for the file err = GetGraphicsImporterForFileWithFlags (&fsspecImage, &giComp, kDontUseValidateToFindGraphicsImporter); if (err != noErr) return 0; // get the image bounds err = GraphicsImportGetNaturalBounds (giComp, &rectImage); if (err != noErr) return 0; // create a handle for the image description and lock it hImageDesc = (ImageDescriptionHandle) NewHandle (sizeof (ImageDescriptionHandle)); HLock ((Handle) hImageDesc); // retrieve the image description err = GraphicsImportGetImageDescription (giComp, &hImageDesc); if (err != noErr) return 0; // find width and height imageWidth = (int) (rectImage.right - rectImage.left); imageHeight = (int) (rectImage.bottom - rectImage.top); // now calculate the aspect ratio (width/height), used to restore image correctly imageAspect = ((float) imageWidth) / ((float) imageHeight); // get the image's pixel depth imageDepth = (**hImageDesc).depth; // find nearest acceptable texture size (width and height) for the image textureWidth = GetTextureDimFromImageDim (imageWidth); textureHeight = GetTextureDimFromImageDim (imageHeight); // pass the optimised (and scaled) size back out to the caller *width = textureWidth; *height = textureHeight; // set texture rectangle for creation of GWorld #ifdef __APPLE__ SetRect (&rectImage, 0, 0, (int) textureWidth, (int) textureHeight); #endif #ifdef _WIN32 MacSetRect (&rectImage, 0, 0, (int) textureWidth, (int) textureHeight); #endif // set stride in bytes width of image * 4 bytes per pixel rowStride = textureWidth * 4; // build new buffer exact size of image (stride * height) pImageBuffer = (unsigned char *) NewPtr (rowStride * textureHeight); // check we got the buffer we wanted if (pImageBuffer == NULL) { // failed - release the component and return an error CloseComponent(giComp); return 0; } // create a new gworld using our unpadded buffer, setting the pixel type correctly for the expected image depth #ifdef __BIG_ENDIAN__ QTNewGWorldFromPtr (&(pGWorld), k32ARGBPixelFormat, &rectImage, NULL, NULL, 0, pImageBuffer, rowStride); #else QTNewGWorldFromPtr (&(pGWorld), k32RGBAPixelFormat, &rectImage, NULL, NULL, 0, pImageBuffer, rowStride); #endif // could we allocate the GWorld? if (pGWorld == NULL) { // failed - release the buffer, component and return an error DisposePtr ((Ptr) pImageBuffer); CloseComponent(giComp); return 0; } // build a transformation matrix to scale the image to the texture size // this also flips the image horizontally, so that texture coordinates map correctly float horizontalScale = (float) textureWidth / (float) imageWidth; float verticalScale = (float) textureHeight / (float) imageHeight; SetIdentityMatrix (&matrix); ScaleMatrix (&matrix, X2Fix(horizontalScale), X2Fix(-verticalScale), 0, 0); TranslateMatrix (&matrix, 0, X2Fix((float)textureHeight)); // set the matrix as the importer matrix err = GraphicsImportSetMatrix(giComp, &matrix); // set the destination of the importer component if (err == noErr) err = GraphicsImportSetGWorld (giComp, pGWorld, NULL); // ensure lossless decompression (if the CODEC supports this) if (err == noErr) err = GraphicsImportSetQuality(giComp, codecLosslessQuality); if (err != noErr) { // failed - release the GWorld, buffer, component and return an error DisposeGWorld (pGWorld); DisposePtr ((Ptr) pImageBuffer); CloseComponent(giComp); return 0; } // get the address of the GWorld's pixmap hPixMap = GetGWorldPixMap (pGWorld); // if everything looks good draw the image to the locked pixmap if ((hPixMap) && (LockPixels (hPixMap))) GraphicsImportDraw (giComp); else { // the pixmap doesn't exist, or we couldn't lock it // release the GWorld, buffer, component and return an error DisposeGWorld (pGWorld); DisposePtr ((Ptr) pImageBuffer); CloseComponent(giComp); return 0; } // for images without an alpha channel, initialise the alpha bytes since QuickTime won't if (imageDepth < 32) { #ifdef __BIG_ENDIAN__ for( unsigned char *p = pImageBuffer; p < pImageBuffer + (rowStride * textureHeight); p+=4) *p = 0xFF; #else for( unsigned char *p = pImageBuffer+3; p < pImageBuffer + (rowStride * textureHeight) +3; p+=4) *p = 0xFF; #endif } // unlock the pixmap UnlockPixels (hPixMap); // dump the component CloseComponent(giComp); // set image width in groups (pixels), accounts for border this ensures proper image alignment row to row glPixelStorei (GL_UNPACK_ROW_LENGTH, textureWidth); // generate a "name" for the texture glGenTextures (1, &textureName); // create the texture in OpenGL glBindTexture(GL_TEXTURE_2D, textureName); // tell OpenGL about the texture and have GLU build mipmaps #ifdef __BIG_ENDIAN__ glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pImageBuffer); #else glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pImageBuffer); #endif if (generateMipmaps) #ifdef __BIG_ENDIAN__ if (gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, textureWidth, textureHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pImageBuffer) != 0) #else if (gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, textureWidth, textureHeight, GL_RGBA, GL_UNSIGNED_BYTE, pImageBuffer) != 0) #endif // good time to check for errors? openGLCheckError(); // finished with the GWorld but not the image buffer (it's used by OpenGL as the "live" image buffer) DisposeGWorld (pGWorld); // restore the current graphics port we saved earlier SetGWorld(origPort, origDevice); // all done - return the texture name return textureName; #endif // QuickTimeInstalled }
unsigned int CTextureManager::LoadTexture( char *filename ) { unsigned int id = 0; unsigned char *texels = 0; bool success; //int width, height; for( TListItor itor = m_texlist.begin(); itor != m_texlist.end(); ++itor ) { if( strcmp( (*itor)->GetName(), filename ) == 0 ) return (*itor)->GetTexId(); } Small::Image *imagen; imagen = new Small::Image(); success = imagen->Load(filename); if( success == true ) { // imagen->FlipVertically(); glGenTextures( 1, &id ); glPixelStorei (GL_UNPACK_ALIGNMENT, 1); glBindTexture( GL_TEXTURE_2D, id ); int textureType = GL_RGB; if(imagen->bpp == 32) textureType = GL_RGBA; gluBuild2DMipmaps(GL_TEXTURE_2D, imagen->bpp/8, imagen->width, imagen->height, textureType ,GL_UNSIGNED_BYTE, imagen->data); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // PENDIENTE: Si hacemos esto las texturas del BSP se ven mal. //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // PENDIENTE: pero si hacemos esto se ve mal el bitmap del mouse glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // create a new CTexture object and push it at the end of the linked list CTexture *tex = new CTexture( id, filename ); m_texlist.push_back( tex ); } else { Small::Log::Instance().Write("Textura %s no encontrada", filename); // No podemos cargar la textura. Usamos la textura por defecto. id = (*m_texlist.begin())->GetTexId(); } //if( texels ) // delete [] texels; delete imagen; return id; }
void EnemyFireball::sprite() { texturePos = 0; // Mac environment variable for home directory char *cHomeDir = NULL; cHomeDir = getenv("HOME"); // I think Windows uses HOMEPATH if (!cHomeDir) { cHomeDir = getenv("HOMEPATH"); } std::string homeDir = cHomeDir; std::string iName; homeDir += "/CS330/sprites/fireball"; std::string pos; for (int i = 0; i<4; ++i) { std::stringstream out; //Generates Filename iName = homeDir; out<<i; pos = out.str(); iName += pos; iName += ".tex"; //Read in the texture file FILE *fp = fopen(iName.c_str(), "r"); unsigned char *texture = new unsigned char[4 * 16 * 16]; if (fread(texture, sizeof(unsigned char), 4 * 16 * 16, fp) != 4* 16 *16) { fprintf(stderr, "error reading %s", iName.c_str()); } fclose(fp); //Bind Texture to a GLuint glGenTextures(1, &texture_[i]); glBindTexture(GL_TEXTURE_2D, texture_[i]); //Set parameters for how the texture is displayed glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); //Build Mipmap gluBuild2DMipmaps(GL_TEXTURE_2D, 4, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, texture); delete [] texture; } }
int gld_BuildTexture(GLTexture *gltexture, void *data, dboolean readonly, int width, int height) { int result = false; int tex_width, tex_height, tex_buffer_size; unsigned char *tex_buffer = NULL; tex_width = gld_GetTexDimension(width); tex_height = gld_GetTexDimension(height); tex_buffer_size = tex_width * tex_height * 4; //your video is modern if (gl_arb_texture_non_power_of_two) { qglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, ((gltexture->flags & GLTEXTURE_MIPMAP) ? GL_TRUE : GL_FALSE)); qglTexImage2D( GL_TEXTURE_2D, 0, gl_tex_format, tex_width, tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); gld_RecolorMipLevels(data); gld_SetTexFilters(gltexture); result = true; goto l_exit; } #ifdef USE_GLU_MIPMAP if (gltexture->flags & GLTEXTURE_MIPMAP) { gluBuild2DMipmaps(GL_TEXTURE_2D, gl_tex_format, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); gld_RecolorMipLevels(data); gld_SetTexFilters(gltexture); result = true; goto l_exit; } else #endif // USE_GLU_MIPMAP { #ifdef USE_GLU_IMAGESCALE if ((width != tex_width) || (height != tex_height)) { tex_buffer = malloc(tex_buffer_size); if (!tex_buffer) { goto l_exit; } gluScaleImage(GL_RGBA, width, height, GL_UNSIGNED_BYTE, data, tex_width, tex_height, GL_UNSIGNED_BYTE, tex_buffer); qglTexImage2D( GL_TEXTURE_2D, 0, gl_tex_format, tex_width, tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_buffer); } else #endif // USE_GLU_IMAGESCALE { if ((width != tex_width) || (height != tex_height)) { if (width == tex_width) { tex_buffer = malloc(tex_buffer_size); memcpy(tex_buffer, data, width * height * 4); } else { int y; tex_buffer = calloc(1, tex_buffer_size); for (y = 0; y < height; y++) { memcpy(tex_buffer + y * tex_width * 4, ((unsigned char*)data) + y * width * 4, width * 4); } } } else { tex_buffer = data; } if (gl_paletted_texture) { gld_SetTexturePalette(GL_TEXTURE_2D); qglTexImage2D( GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, tex_width, tex_height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, tex_buffer); } else { qglTexImage2D( GL_TEXTURE_2D, 0, gl_tex_format, tex_width, tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_buffer); } } gltexture->flags &= ~GLTEXTURE_MIPMAP; gld_SetTexFilters(gltexture); result = true; } l_exit: if (result) { qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); } if (tex_buffer && tex_buffer != data) { free(tex_buffer); tex_buffer = NULL; } if (!readonly) { free(data); data = NULL; } return result; }
/////////////////////////////////////////////////////////////////////////////// // Setup. Create font/bitmaps, load textures, create display lists void SetupRC(HDC hDC) { M3DVector3f vPoints[3] = {{ 0.0f, -0.4f, 0.0f }, { 10.0f, -0.4f, 0.0f }, { 5.0f, -0.4f, -5.0f } }; int iSphere; int i; // Setup the Font characteristics HFONT hFont; LOGFONT logfont; logfont.lfHeight = -20; logfont.lfWidth = 0; logfont.lfEscapement = 0; logfont.lfOrientation = 0; logfont.lfWeight = FW_BOLD; logfont.lfItalic = FALSE; logfont.lfUnderline = FALSE; logfont.lfStrikeOut = FALSE; logfont.lfCharSet = ANSI_CHARSET; logfont.lfOutPrecision = OUT_DEFAULT_PRECIS; logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS; logfont.lfQuality = DEFAULT_QUALITY; logfont.lfPitchAndFamily = DEFAULT_PITCH; strcpy(logfont.lfFaceName,"Arial"); // Create the font and display list hFont = CreateFontIndirect(&logfont); SelectObject (hDC, hFont); //Create display lists for glyphs 0 through 128 nFontList = glGenLists(128); wglUseFontBitmaps(hDC, 0, 128, nFontList); DeleteObject(hFont); // Don't need original font anymore // Grayish background glClearColor(fLowLight[0], fLowLight[1], fLowLight[2], fLowLight[3]); // Clear stencil buffer with zero, increment by one whenever anybody // draws into it. When stencil function is enabled, only write where // stencil value is zero. This prevents the transparent shadow from drawing // over itself glStencilOp(GL_INCR, GL_INCR, GL_INCR); glClearStencil(0); glStencilFunc(GL_EQUAL, 0x0, 0x01); // Cull backs of polygons glCullFace(GL_BACK); glFrontFace(GL_CCW); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); // Setup light parameters glLightModelfv(GL_LIGHT_MODEL_AMBIENT, fNoLight); glLightfv(GL_LIGHT0, GL_AMBIENT, fLowLight); glLightfv(GL_LIGHT0, GL_DIFFUSE, fBrightLight); glLightfv(GL_LIGHT0, GL_SPECULAR, fBrightLight); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); // Calculate shadow matrix M3DVector4f pPlane; m3dGetPlaneEquation(pPlane, vPoints[0], vPoints[1], vPoints[2]); m3dMakePlanarShadowMatrix(mShadowMatrix, pPlane, fLightPos); // Mostly use material tracking glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); glMateriali(GL_FRONT, GL_SHININESS, 128); // Randomly place the sphere inhabitants for(iSphere = 0; iSphere < NUM_SPHERES; iSphere++) { // Pick a random location between -20 and 20 at .1 increments spheres[iSphere].SetOrigin((float)((rand() % 400) - 200) * 0.1f, 0.0f, (float)((rand() % 400) - 200) * 0.1f); } // Set up texture maps glEnable(GL_TEXTURE_2D); glGenTextures(NUM_TEXTURES, textureObjects); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // Load teach texture for(i = 0; i < NUM_TEXTURES; i++) { GLbyte *pBytes; GLint iWidth, iHeight, iComponents; GLenum eFormat; glBindTexture(GL_TEXTURE_2D, textureObjects[i]); // Load this texture map pBytes = gltLoadTGA(szTextureFiles[i], &iWidth, &iHeight, &iComponents, &eFormat); gluBuild2DMipmaps(GL_TEXTURE_2D, iComponents, iWidth, iHeight, eFormat, GL_UNSIGNED_BYTE, pBytes); free(pBytes); // Trilinear mipmapping glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } // Get window position function pointer if it exists glWindowPos2i = (PFNGLWINDOWPOS2IPROC)wglGetProcAddress("glWindowPos2i"); // Get swap interval function pointer if it exists wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); if(wglSwapIntervalEXT != NULL && startupOptions.bVerticalSync == TRUE) wglSwapIntervalEXT(1); // If multisampling was available and was selected, enable if(startupOptions.bFSAA == TRUE && startupOptions.nPixelFormatMS != 0) glEnable(GL_MULTISAMPLE_ARB); // If sepearate specular color is available, make torus shiney if(gltIsExtSupported("GL_EXT_separate_specular_color")) glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); // Initialize the timers QueryPerformanceFrequency(&CounterFrequency); QueryPerformanceCounter(&FPSCount); CameraTimer = FPSCount; // Build display lists for the torus and spheres // (You could do one for the ground as well) lTorusList = glGenLists(2); lSphereList = lTorusList + 1; glNewList(lTorusList, GL_COMPILE); gltDrawTorus(0.35f, 0.15f, 61, 37); glEndList(); glNewList(lSphereList, GL_COMPILE); gltDrawSphere(0.3f, 31, 16); glEndList(); }
void DebuggingView::drawCamera() { glDisable(GL_LIGHTING); int bufWidth, bufHeight; unsigned char *buffer; raytracer->getBuffer( buffer, bufWidth, bufHeight ); static GLuint texName = 0; if( texName == 0 ) glGenTextures(1, &texName); if( m_dirty && raytracer->isReady() ) { m_dirty = false; glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glBindTexture(GL_TEXTURE_2D, texName); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, bufWidth, bufHeight, GL_RGB, GL_UNSIGNED_BYTE, buffer ); } glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glShadeModel(GL_FLAT); glPushMatrix(); const Camera& sceneCamera = raytracer->getScene().getCamera(); glTranslated( (sceneCamera.getEye())[0], (sceneCamera.getEye())[1], (sceneCamera.getEye())[2] ); glColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); // Now need to draw the camera. glBegin( GL_LINES ); glVertex3d(0,0,0); glVertex3dv( (sceneCamera.getLook() + 0.5*sceneCamera.getU() + 0.5*sceneCamera.getV()).getPointer() ); glVertex3d(0,0,0); glVertex3dv( (sceneCamera.getLook() + 0.5*sceneCamera.getU() - 0.5*sceneCamera.getV()).getPointer() ); glVertex3d(0,0,0); glVertex3dv( (sceneCamera.getLook() - 0.5*sceneCamera.getU() + 0.5*sceneCamera.getV()).getPointer() ); glVertex3d(0,0,0); glVertex3dv( (sceneCamera.getLook() - 0.5*sceneCamera.getU() - 0.5*sceneCamera.getV()).getPointer() ); glEnd(); glTranslated( (sceneCamera.getLook())[0], (sceneCamera.getLook())[1], (sceneCamera.getLook())[2] ); if( !m_dirty || raytracer->isReady() ) { glColor4f( 1.0f, 1.0f, 1.0f, 0.7f ); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texName); } else { glColor4f( 0.0f, 0.0f, 0.0f, 0.7f ); } glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBegin( GL_QUADS ); glTexCoord2f(0.0, 0.0); glVertex3dv((-0.5*sceneCamera.getU() - 0.5*sceneCamera.getV()).getPointer()); glTexCoord2f(0.0, 1.0); glVertex3dv((-0.5*sceneCamera.getU() + 0.5*sceneCamera.getV()).getPointer()); glTexCoord2f(1.0, 1.0); glVertex3dv((0.5*sceneCamera.getU() + 0.5*sceneCamera.getV()).getPointer()); glTexCoord2f(1.0, 0.0); glVertex3dv((0.5*sceneCamera.getU() - 0.5*sceneCamera.getV()).getPointer()); glEnd(); glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); glColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); glBegin( GL_LINE_STRIP ); glVertex3dv((-0.51*sceneCamera.getU() - 0.51*sceneCamera.getV()).getPointer()); glVertex3dv((-0.51*sceneCamera.getU() + 0.51*sceneCamera.getV()).getPointer()); glVertex3dv((0.51*sceneCamera.getU() + 0.51*sceneCamera.getV()).getPointer()); glVertex3dv((0.51*sceneCamera.getU() - 0.51*sceneCamera.getV()).getPointer()); glVertex3dv((-0.51*sceneCamera.getU() - 0.51*sceneCamera.getV()).getPointer()); glEnd(); glPopMatrix(); glEnable( GL_LIGHTING ); }
textureBMP::textureBMP(const char *filename, const int textureId) { byte *fileData; BMFH fileHeader; BMIH infoHeader; // Open file int hTextureFile = open(filename, O_RDONLY); // if (hTextureFile == INVALID_HANDLE_VALUE) // { // std::cout << "[BMP] ERROR: Could not open '" << filename << "'" << // std::endl; // return; // } struct stat filestat; fstat(hTextureFile, &filestat); if (filestat.st_size == 0) { std::cout << "[BMP] ERROR: Texture '" << filename << "' is empty" << std::endl; close(hTextureFile); return; } // Create file mapping void *hTextureFileMapping = mmap(NULL, filestat.st_size, PROT_READ, MAP_SHARED, hTextureFile, 0); if (hTextureFileMapping == NULL) { std::cout << "[TGA] ERROR: Could not map '" << filename << "' in memory" << std::endl; close(hTextureFile); return; } fileData = (byte *) hTextureFileMapping; // (byte *) MapViewOfFile(hTextureFileMapping, FILE_MAP_READ, 0, 0, 0); // Read BMP header memcpy(&fileHeader, fileData, sizeof(fileHeader)); memcpy(&infoHeader, fileData + sizeof(fileHeader), sizeof(infoHeader)); m_width = infoHeader.biWidth; m_height = infoHeader.biHeight; m_bpp = infoHeader.biBitCount; // We only support uncompressed 24 or 32 bits per pixel BMPs if (fileHeader.bfType != 19778) { std::cout << "[BMP] ERROR: '" << filename << "' is an texture invalid format\n[BMP] ERROR: It should be an uncompressed 24/32bpp BMP" << std::endl; munmap(fileData, filestat.st_size); close(hTextureFile); return; } if (m_bpp != 32 && m_bpp != 24) { std::cout << "[BMP] ERROR: Invalid texture color depth, '" << filename << "' must be uncompressed 24/32bpp BMP" << std::endl; munmap(fileData, filestat.st_size); close(hTextureFile); return; } // Determine format int fileFormat, internalFormat; switch (m_bpp) { case 24: fileFormat = GL_BGR_EXT; internalFormat = GL_RGB; break; case 32: fileFormat = GL_BGRA_EXT; internalFormat = GL_RGBA; break; default: std::cout << "[BMP] ERROR: Invalid texture color depth, '" << filename << "' must be uncompressed 24/32bpp BMP" << std::endl; munmap(fileData, filestat.st_size); close(hTextureFile); return; break; } // Bind texture ID to load glBindTexture(GL_TEXTURE_2D, textureId); // Set texture parameters 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_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // Upload texture to card with bound texture ID gluBuild2DMipmaps(GL_TEXTURE_2D, internalFormat, m_width, m_height, fileFormat, GL_UNSIGNED_BYTE, &fileData[fileHeader.bfOffBits]); // Texture's uploaded, don't need data any more munmap(fileData, filestat.st_size); close(hTextureFile); std::cout << "[BMP] Texture '" << filename << "' loaded" << std::endl; }
// Using auxDIBImageLoad's Own Error-Handler! int LoadGLTextures(){ // Load Bitmaps And Convert To Textures bool status=true; // Status Indicator SDL_Surface *Image=NULL; // Create Storage Space For The Texture char *alpha=NULL; unsigned char *data; int a; // Load The Tile-Bitmap For Base-Texture if (Image=SDL_LoadBMP("Data/Base.bmp")) { Image=torgb(Image); glGenTextures(3, texture); // Create Three Textures // Create Nearest Filtered Texture glBindTexture(GL_TEXTURE_2D, texture[0]); 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, GL_RGB8, Image->w, Image->h, 0, GL_RGB, GL_UNSIGNED_BYTE, Image->pixels); // ======== // Use GL_RGB8 Instead Of "3" In glTexImage2D. Also Defined By GL: GL_RGBA8 Etc. // NEW: Now Creating GL_RGBA8 Textures, Alpha Is 1.0f Where Not Specified By Format. // Create Linear Filtered Texture glBindTexture(GL_TEXTURE_2D, texture[1]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, Image->w, Image->h, 0, GL_RGB, GL_UNSIGNED_BYTE, Image->pixels); // Create MipMapped Texture glBindTexture(GL_TEXTURE_2D, texture[2]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB8, Image->w, Image->h, GL_RGB, GL_UNSIGNED_BYTE, Image->pixels); if (Image) SDL_FreeSurface(Image); //free surface memory } else status=false; // Load The Bumpmaps if (Image=SDL_LoadBMP("Data/Bump.bmp")) { Image=torgb(Image); // convert from grayscale to rgb glPixelTransferf(GL_RED_SCALE,0.5f); // Scale RGB By 50%, So That We Have Only glPixelTransferf(GL_GREEN_SCALE,0.5f); // Half Intenstity glPixelTransferf(GL_BLUE_SCALE,0.5f); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP); // No Wrapping, Please! glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP); glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_BORDER_COLOR,Gray); glGenTextures(3, bump); // Create Three Textures // Create Nearest Filtered Texture glBindTexture(GL_TEXTURE_2D, bump[0]); 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, GL_RGB8, Image->w, Image->h, 0, GL_RGB, GL_UNSIGNED_BYTE, Image->pixels); // Create Linear Filtered Texture glBindTexture(GL_TEXTURE_2D, bump[1]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, Image->w, Image->h, 0, GL_RGB, GL_UNSIGNED_BYTE, Image->pixels); // Create MipMapped Texture glBindTexture(GL_TEXTURE_2D, bump[2]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB8, Image->w, Image->h, GL_RGB, GL_UNSIGNED_BYTE, Image->pixels); data = (unsigned char *)Image->pixels; for (int i=0; i < 3 * Image->w * Image->h; i++) // Invert The Bumpmap data[i]=255-data[i]; glGenTextures(3, invbump); // Create Three Textures // Create Nearest Filtered Texture glBindTexture(GL_TEXTURE_2D, invbump[0]); 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, GL_RGB8, Image->w, Image->h, 0, GL_RGB, GL_UNSIGNED_BYTE, Image->pixels); // Create Linear Filtered Texture glBindTexture(GL_TEXTURE_2D, invbump[1]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, Image->w, Image->h, 0, GL_RGB, GL_UNSIGNED_BYTE, Image->pixels); // Create MipMapped Texture glBindTexture(GL_TEXTURE_2D, invbump[2]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB8, Image->w, Image->h, GL_RGB, GL_UNSIGNED_BYTE, Image->pixels); glPixelTransferf(GL_RED_SCALE,1.0f); // Scale RGB Back To 100% Again glPixelTransferf(GL_GREEN_SCALE,1.0f); glPixelTransferf(GL_BLUE_SCALE,1.0f); if (Image) SDL_FreeSurface(Image); //free surface memory } else status=false; // Load The Logo-Bitmaps if (Image=SDL_LoadBMP("Data/opengl_alpha.bmp")) { Image=torgb(Image); // convert from grayscale to rgb alpha=new char[4*Image->w*Image->h]; // Create Memory For RGBA8-Texture data = (unsigned char *)Image->pixels; for (a=0; a<Image->w*Image->h; a++) alpha[4*a+3]=data[a*3]; // Pick Only Red Value As Alpha! if (Image) SDL_FreeSurface(Image); if (!(Image=SDL_LoadBMP("Data/opengl.bmp"))) status=false; Image=torgb(Image); data = (unsigned char *)Image->pixels; for (a=0; a<Image->w*Image->h; a++) { alpha[4*a]=data[a*3]; // R alpha[4*a+1]=data[a*3+1]; // G alpha[4*a+2]=data[a*3+2]; // B } glGenTextures(1, &glLogo); // Create One Textures // Create Linear Filtered RGBA8-Texture glBindTexture(GL_TEXTURE_2D, glLogo); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Image->w, Image->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, alpha); delete alpha; if (Image) SDL_FreeSurface(Image); //free surface memory } else status=false; // Load The "Extension Enabled"-Logo if (Image=SDL_LoadBMP("Data/multi_on_alpha.bmp")) { Image=torgb(Image); // convert from grayscale to rgb alpha=new char[4*Image->w*Image->h]; // Create Memory For RGBA8-Texture data = (unsigned char *)Image->pixels; for (a=0; a<Image->w*Image->h; a++) alpha[4*a+3]=data[a*3]; // Pick Only Red Value As Alpha! if (Image) SDL_FreeSurface(Image); //free surface memory if (!(Image=SDL_LoadBMP("Data/multi_on.bmp"))) status=false; Image=torgb(Image); data = (unsigned char *)Image->pixels; for (a=0; a<Image->w*Image->h; a++) { alpha[4*a]=data[a*3]; // R alpha[4*a+1]=data[a*3+1]; // G alpha[4*a+2]=data[a*3+2]; // B } glGenTextures(1, &multiLogo); // Create One Textures // Create Linear Filtered RGBA8-Texture glBindTexture(GL_TEXTURE_2D, multiLogo); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Image->w, Image->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, alpha); delete alpha; if (Image) SDL_FreeSurface(Image); //free surface memory } else status=false; return status; // Return The Status }
GtaStyle::GtaStyle(std::string filename) { std::cout << "opening map: " << filename << std::endl; std::ifstream f(filename.c_str()); f.seekg(0, std::ios::end); int size = f.tellg(); f.seekg(0, std::ios::beg); std::cout << "allocating " << size << " bytes for map" << std::endl; _data = new char[size]; f.read(_data, size); f.close(); char* offset = _data; FileHeader* file_header = reinterpret_cast<FileHeader*>(offset); std::string hdr(file_header->name, 0, 4); if(hdr != "GBST") throw std::runtime_error("wrong header: \"" + hdr + "\""); if(file_header->version != 700) throw std::runtime_error("wrong version: " + boost::lexical_cast<std::string>(file_header->version)); offset += sizeof(FileHeader); while(offset < _data + size) { ChunkHeader* chunk_header = reinterpret_cast<ChunkHeader*>(offset); offset += sizeof(ChunkHeader); std::string chunk_hdr(chunk_header->type, 0, 4); std::cout << "Found: " << chunk_hdr << " at " << offset - _data << ", size: " << chunk_header->size << std::endl; if(chunk_hdr == "PALX") // palette index { _palette_index.phys_palette = reinterpret_cast<uint16_t*>(offset); offset += chunk_header->size; } else if(chunk_hdr == "PPAL") // physical palettes { _palette_data = reinterpret_cast<uint32_t*>(offset); offset += chunk_header->size; } else if(chunk_hdr == "PALB") // palette base { _palette_base = reinterpret_cast<PaletteBase*>(offset); offset += sizeof(PaletteBase); } else if(chunk_hdr == "TILE") { _tiles = reinterpret_cast<uint8_t*>(offset); offset += chunk_header->size; } else { std::cout << "skipping " << chunk_header->size << " bytes on \"" << chunk_hdr << "\" offset: " << (int)(offset - _data) << std::endl; offset += chunk_header->size; } } _textures.reserve(992); const int page_size = 256 * 256; for(int page_num = 0; page_num < 62; page_num++) { uint8_t* page = _tiles + page_size * page_num; for(int y = 0; y < 4; y++) { for(int x = 0; x < 4; x++) { uint32_t tile[64*64]; const int tile_index = page_num * 16 + y * 4 + x; int palette_index = _palette_index.phys_palette[tile_index]; bool has_transparency = false; for(int tile_y = 0; tile_y < 64; tile_y++) { for(int tile_x = 0; tile_x < 64; tile_x++) { uint8_t c = page[(y * 64 + tile_y) * 256 + x * 64 + tile_x]; if(c == 0) { has_transparency = true; tile[tile_y * 64 + tile_x] = 0x00000000; } else { tile[tile_y * 64 + tile_x] = getPaletteValue(palette_index, c) | 0xff000000; } } } boost::shared_ptr<Texture> texture(new Texture); texture->hasTransparency(has_transparency); texture->bind(); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, 64, 64, GL_BGRA, GL_UNSIGNED_BYTE, tile); //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_BGRA, GL_UNSIGNED_BYTE, tile); _textures.push_back(texture); } } } }
/* ======================================================================================================================= * TODO: ======================================================================================================================= */ GLuint cTexture::LoadTexturePNG (char const *const szFilename) { GLuint unTextureName; png_structp psPng; png_infop psInfo; unsigned int uSigRead; png_uint_32 uWidth; png_uint_32 uHeight; int nBitDepth; int nColourType; int nInterlaceType; png_byte acTestBuffer[PNG_BYTES_TO_CHECK]; void* cData; FILE* hFile; float fScreenGamma; /* Apparently a good guess for a PC monitors in a dimly lit room */ int nIntent; double fImageGamma; unsigned int uRow; png_bytep* apRowPointers; unTextureName = 0; psPng = NULL; psInfo = NULL; uSigRead = 0; fScreenGamma = 2.2; hFile = fopen (szFilename, "rb"); if (hFile) { acTestBuffer[0] = 0; uSigRead = (unsigned int) fread (acTestBuffer, 1, PNG_BYTES_TO_CHECK, hFile); /* Check if this is a PNG file */ if (png_sig_cmp (acTestBuffer, (png_size_t) 0, uSigRead) == 0) { /* Set up the PNG structure */ psPng = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (psPng) { /* Set up image information structure */ psInfo = png_create_info_struct (psPng); } /* Check the structures have been set up and set the error handler */ if (psPng && psInfo && (!setjmp (png_jmpbuf (psPng)))) { /* Use standard C stream as I/O method */ png_init_io (psPng, hFile); /* Skip the bit we already read in */ png_set_sig_bytes (psPng, uSigRead); /* Read all of the info about the PNG from the file */ png_read_info (psPng, psInfo); png_get_IHDR (psPng, psInfo, &uWidth, &uHeight, &nBitDepth, &nColourType, &nInterlaceType, NULL, NULL); /* Reduce 16 bits per colour down to 8 bits per colour if necessary */ png_set_strip_16 (psPng); /* Expand paletted colours to RGB if necessary */ if (nColourType == PNG_COLOR_TYPE_PALETTE) { png_set_palette_to_rgb (psPng); } /* Expand greyscale images to 8 bits per colour if necessary */ if ((nColourType == PNG_COLOR_TYPE_GRAY) && (nBitDepth < 8)) { png_set_gray_to_rgb (psPng); } /* Expand image to be in RGBA quartets if necessary */ if (png_get_valid (psPng, psInfo, PNG_INFO_tRNS)) { png_set_tRNS_to_alpha (psPng); } /* Deal with Gamma correction and stuff like that */ if (png_get_sRGB (psPng, psInfo, &nIntent)) { png_set_gamma (psPng, fScreenGamma, 0.45455); } else { if (png_get_gAMA (psPng, psInfo, &fImageGamma)) { png_set_gamma (psPng, fScreenGamma, fImageGamma); } else { png_set_gamma (psPng, fScreenGamma, 0.45455); } } png_read_update_info (psPng, psInfo); /* Allocate memory for the row pointers */ apRowPointers = (png_bytep*) malloc (uHeight * sizeof (png_bytep)); /* Allocate memory for the pixel data */ cData = png_malloc (psPng, (uHeight * png_get_rowbytes (psPng, psInfo))); if (cData) { /* Set up row data pointers to allocated memory */ for (uRow = 0; uRow < uHeight; uRow++) { apRowPointers[uRow] = (png_bytep) cData + (uRow * png_get_rowbytes (psPng, psInfo)); } /* Read the image into the memory */ png_read_image (psPng, apRowPointers); /* Read anything left over */ png_read_end (psPng, psInfo); /* We don't need the row pointers anymore */ free (apRowPointers); /* Now convert the data into an OpenGL texture */ glGenTextures (1, &unTextureName); glBindTexture (GL_TEXTURE_2D, unTextureName); glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 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_MIN_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); gluBuild2DMipmaps (GL_TEXTURE_2D, 4, uWidth, uHeight, GL_RGBA, GL_UNSIGNED_BYTE, cData); /* Don't need the pixel data anymore */ png_free (psPng, cData); } } /* Clean things up and free allocated memory */ png_destroy_read_struct (&psPng, &psInfo, NULL); } fclose (hFile); } return unTextureName; }
PreviewLayoutLinesTool::PreviewLayoutLinesTool(ToolHelper *helper) : Tool(helper), m_holdOnNear(false), m_updateStatistics(true), m_nearestLine(-1), m_useNearestLine(false) { helper->GetPanoramaPtr()->addObserver(this); // make the textures. We have a circle border and a square one. // the textures are white with a the alpha chanel forming a border. glGenTextures(1, (GLuint*) &m_rectangleBorderTex); // we only want to specify alpha, but using just alpha in opengl attaches 0 // for the luminosity. I tried biasing the red green and blue values to get // them to 1.0, but it didn't work under OS X for some reason. Instead we // use a luminance alpha pair, and use 1.0 for luminance all the time. // In the rectangle texture, the middle is 1/8 opaque, the outer pixels // are completely transparent, and one pixel in from the edges is // a completly opaque line. unsigned char rect_tex_data[rect_ts][rect_ts][2]; // make everything white for (unsigned int x = 0; x < rect_ts; x++) { for (unsigned int y = 0; y < rect_ts; y++) { rect_tex_data[x][y][0] = 255; } } // now set the middle of the mask semi transparent for (unsigned int x = 2; x < rect_ts - 2; x++) { for (unsigned int y = 2; y < rect_ts - 2; y++) { rect_tex_data[x][y][1] = 31; } } // make an opaque border for (unsigned int d = 1; d < rect_ts - 1; d++) { rect_tex_data[d][1][1] = 255; rect_tex_data[d][rect_ts - 2][1] = 255; rect_tex_data[1][d][1] = 255; rect_tex_data[rect_ts - 2][d][1] = 255; } // make a transparent border around that for (unsigned int d = 0; d < rect_ts; d++) { rect_tex_data[d][0][1] = 0; rect_tex_data[d][rect_ts - 1][1] = 0; rect_tex_data[0][d][1] = 0; rect_tex_data[rect_ts - 1][d][1] = 0; } glBindTexture(GL_TEXTURE_2D, m_rectangleBorderTex); gluBuild2DMipmaps(GL_TEXTURE_2D, GL_LUMINANCE_ALPHA, rect_ts, rect_ts, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, rect_tex_data); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // clamp texture so it won't wrap over the border of the cropped region. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); }
void Texture::setup_texture_data( int dim, Image::ColorEncoding encoding_in, Memory::pointer base_mem_in, Texture::FilteringMode mode, int width, int height, int depth) { const int static_buffer_size = 1024*1024 ; static Memory::byte static_buffer[static_buffer_size * 4] ; Memory::pointer dynamic_buffer = nil ; Memory::pointer base_mem = base_mem_in ; Image::ColorEncoding encoding = encoding_in ; mipmap_ = (mode == Texture::MIPMAP) ; linear_filter_ = (mode != Texture::NO_FILTERING) ; if(height == 0) { height++ ; } if(depth == 0) { depth++ ; } int size = width * height * depth ; if(encode_indexed_to_rgb_ && (encoding == Image::GRAY || encoding == Image::INDEXED)) { if(dim == 3 && encoding == Image::GRAY) { } else { encoding = Image::RGBA ; if(size <= static_buffer_size) { base_mem = static_buffer ; } else { dynamic_buffer = new Memory::byte[size*4] ; base_mem = dynamic_buffer ; } indexed_to_rgb(size, base_mem_in, Image::RGBA, base_mem) ; } } switch(dim) { case 1: switch(encoding) { case Image::GRAY : case Image::INDEXED : gluBuild1DMipmaps( GL_TEXTURE_1D, GL_RGBA, width, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, base_mem ) ; break ; case Image::RGB : gluBuild1DMipmaps( GL_TEXTURE_1D, GL_RGB, width, GL_RGB, GL_UNSIGNED_BYTE, base_mem ) ; break ; case Image::RGBA : gluBuild1DMipmaps( GL_TEXTURE_1D, GL_RGBA, width, GL_RGBA, GL_UNSIGNED_BYTE, base_mem ) ; break ; case Image::FLOAT32 : { Memory::pointer colormapped_texture_values = new Memory::byte[4 * width]; float32_to_rgb(size, base_mem_in, Image::RGBA, colormapped_texture_values); gluBuild1DMipmaps( GL_TEXTURE_1D, GL_RGBA, width, GL_RGBA, GL_UNSIGNED_BYTE, colormapped_texture_values ) ; delete[] colormapped_texture_values; break ; } default: { bool implemented = false ; ogf_assert(implemented) ; } } break ; case 2: switch(encoding) { case Image::GRAY : case Image::INDEXED : if(mipmap_) { gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, width, height, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, base_mem ) ; } else { glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, base_mem ) ; } break ; case Image::RGB : if(mipmap_) { gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, width, height, GL_RGB, GL_UNSIGNED_BYTE, base_mem ) ; } else { glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, base_mem ) ; } break ; case Image::RGBA : if(mipmap_) { gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, width, height, GL_RGBA, GL_UNSIGNED_BYTE, base_mem ) ; } else { glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, base_mem ) ; } break ; case Image::RGB_FLOAT32: glTexImage2D( GL_TEXTURE_RECTANGLE_NV, 0, GL_FLOAT_RGB32_NV, width, height, 0, GL_RGB, GL_FLOAT, base_mem ) ; break ; case Image::RGBA_FLOAT32: glTexImage2D( GL_TEXTURE_RECTANGLE_NV, 0, GL_FLOAT_RGBA32_NV, width, height, 0, GL_RGBA, GL_FLOAT, base_mem ) ; break ; case Image::FLOAT32 : { Memory::pointer colormapped_texture_values = new Memory::byte[4 * width * height]; float32_to_rgb(size, base_mem_in, Image::RGBA, colormapped_texture_values); if(mipmap_) { gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, width, height, GL_RGBA, GL_UNSIGNED_BYTE, colormapped_texture_values ) ; } else { glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, colormapped_texture_values ) ; } delete[] colormapped_texture_values; break ; } default: { bool implemented = false ; ogf_assert(implemented) ; } break ; } break ; case 3: // Note: gluBuild3DMipmaps does not seem to exist under Windows #ifdef WIN32 mipmap_ = false ; #endif switch(encoding) { case Image::GRAY : if(mipmap_) { #ifndef WIN32 gluBuild3DMipmaps( GL_TEXTURE_3D, GL_LUMINANCE, width, height, depth, GL_LUMINANCE, GL_UNSIGNED_BYTE, base_mem ) ; #endif } else { glTexImage3DEXT( GL_TEXTURE_3D, 0, GL_LUMINANCE, width, height, depth, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, base_mem ) ; } break ; case Image::INDEXED : if(mipmap_) { #ifndef WIN32 gluBuild3DMipmaps( GL_TEXTURE_3D, GL_RGBA, width, height, depth, GL_RGB, GL_UNSIGNED_BYTE, base_mem ) ; #endif } else { glTexImage3DEXT( GL_TEXTURE_3D, 0, GL_RGB, width, height, depth, 0, GL_RGB, GL_UNSIGNED_BYTE, base_mem ) ; } break ; case Image::RGB : if(mipmap_) { #ifndef WIN32 gluBuild3DMipmaps( GL_TEXTURE_3D, GL_RGB, width, height, depth, GL_RGB, GL_UNSIGNED_BYTE, base_mem ) ; #endif } else { glTexImage3DEXT( GL_TEXTURE_3D, 0, GL_RGB, width, height, depth, 0, GL_RGB, GL_UNSIGNED_BYTE, base_mem ) ; } break ; case Image::RGBA : if(mipmap_) { #ifndef WIN32 gluBuild3DMipmaps( GL_TEXTURE_3D, GL_RGBA, width, height, depth, GL_RGBA, GL_UNSIGNED_BYTE, base_mem ) ; #endif } else { glTexImage3DEXT( GL_TEXTURE_3D, 0, GL_RGBA, width, height, depth, 0, GL_RGBA, GL_UNSIGNED_BYTE, base_mem ) ; } break ; case Image::FLOAT32 : { Memory::pointer colormapped_texture_values = new Memory::byte[4 * width * height * depth]; float32_to_rgb(size, base_mem_in, Image::RGBA, colormapped_texture_values); if(mipmap_) { #ifndef WIN32 gluBuild3DMipmaps( GL_TEXTURE_3D, GL_RGBA, width, height, depth, GL_RGBA, GL_UNSIGNED_BYTE, colormapped_texture_values ) ; #endif } else { glTexImage3DEXT( GL_TEXTURE_3D, 0, GL_RGBA, width, height, depth, 0, GL_RGBA, GL_UNSIGNED_BYTE, colormapped_texture_values ) ; } delete[] colormapped_texture_values; break ; } default: { bool implemented = false ; ogf_assert(implemented) ; } } break ; } delete[] dynamic_buffer ; }
/************************************************************************* LoadTGATexture() Loads a Targa, extracts the data from it, and places it in a texture object associated with textureID. *************************************************************************/ bool LoadTGATexture(GLuint& textureID, char* filename, GLenum wrapMode) { // open the TGA file FILE* pFile = fopen(filename, "rb"); if (!pFile) return false; // read in the image type TGAHEADER tga; fread(&tga, 1, sizeof(TGAHEADER), pFile); // see if the type is one that we support if ((tga.imageType != TGA_RGB) && (tga.imageType != TGA_GRAYSCALE)) { fclose(pFile); return false; } // store texture information tga.width; tga.height; // if colorMode is 3, there is no alpha channel int colorMode = tga.bpp / 8; int imageSize = tga.width * tga.height * colorMode; // allocate memory for TGA image data LPBYTE pData = new BYTE[imageSize]; // read image data fread(pData, 1, imageSize, pFile); // close the file fclose(pFile); // choose the proper data formats depending on whether or not there's an // alpha channel; GLenum dataFormat = colorMode == 3 ? GL_BGR_EXT : GL_BGRA_EXT; GLenum internalFormat; if (colorMode == 3) { if (g_useTextureCompression) internalFormat = GL_COMPRESSED_RGB_ARB; else internalFormat = GL_RGB; } else { if (g_useTextureCompression) internalFormat = GL_COMPRESSED_RGBA_ARB; else internalFormat = GL_RGBA; } glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_2D, textureID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // This is a terrible hack, but there seems to be an issue with using // the generate mipmap extension with texture compression on ATI cards if (g_useSGISMipmapGeneration && strncmp((char*)glGetString(GL_VENDOR), "ATI", 3) != 0) { glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, tga.width, tga.height, 0, dataFormat, GL_UNSIGNED_BYTE, pData); } else { gluBuild2DMipmaps(GL_TEXTURE_2D, internalFormat, tga.width, tga.height, dataFormat, GL_UNSIGNED_BYTE, pData); } delete [] pData; return true; } // end LoadTGATexture()
//------------------------------------------------------------- //- LoadTGA //- Loads an uncompressed or RLE TGA image (24 or 32 bit) //------------------------------------------------------------- bool CImage::LoadTGA(bool bCompressed) { unsigned int uiBpp = 0; unsigned int uiType = 0; //GL_RGB or GL_RGBA unsigned int uiImageSize = 0; unsigned char * ucpPtr = m_ucpBuffer; unsigned char * ucpData = 0; //skip 12 bytes for the already-compared header ucpPtr += 12; //Calculate the width and height m_uiWidth = (ucpPtr[1] << 8) + ucpPtr[0]; m_uiHeight = (ucpPtr[3] << 8) + ucpPtr[2]; uiBpp = ucpPtr[4]; ucpPtr += 6; if(uiBpp == 24) uiType = GL_RGB; else if(uiBpp == 32) uiType = GL_RGBA; else { APP->Log(COLOR_RED, "%s is an invalid TGA file", m_szFilename); delete [] m_ucpBuffer; return false; } uiImageSize = m_uiHeight * m_uiWidth * (uiBpp / 8); ucpData = new unsigned char[uiImageSize]; if(!ucpData) { APP->Log(COLOR_RED, "Out of memory"); delete [] m_ucpBuffer; return false; } //If its uncompressed if(!bCompressed) { for(unsigned int i = 0; i < uiImageSize; i+= (uiBpp / 8)) { //Swap red and blue bytes ucpData[i] = ucpPtr[i+2]; ucpData[i+1] = ucpPtr[i+1]; ucpData[i+2] = ucpPtr[i]; if(uiBpp == 32) ucpData[i+3] = ucpPtr[i+3]; } } //The image is RLE compressed else { unsigned int uiDataPos = 0; do { //Raw data if(ucpPtr[0] < 128) { unsigned int uiCount = ucpPtr[0] * (uiBpp / 8) + 1; ucpPtr++; for(unsigned int i = 0; i < uiCount; i+=(uiBpp/8)) { ucpData[uiDataPos] = ucpPtr[i+2]; ucpData[uiDataPos+1] = ucpPtr[i+1]; ucpData[uiDataPos+2] = ucpPtr[i]; ucpPtr += 3; uiDataPos += 3; if(uiBpp == 32) { ucpData[uiDataPos] = ucpPtr[i]; ucpPtr ++; uiDataPos ++; } } } else { unsigned int uiCount = (ucpPtr[0] -= 127) * (uiBpp / 8); ucpPtr++; for(unsigned int i = 0; i < uiCount; i+=(uiBpp/8)) { ucpData[uiDataPos] = ucpPtr[2]; ucpData[uiDataPos+1] = ucpPtr[1]; ucpData[uiDataPos+2] = ucpPtr[0]; uiDataPos += 3; if(uiBpp == 32) { ucpData[uiDataPos] = ucpPtr[3]; uiDataPos ++; } } ucpPtr += 3; if(uiBpp == 32) ucpPtr++; } } while(uiDataPos < uiImageSize); } glGenTextures(1, &m_uiImage); glBindTexture(GL_TEXTURE_2D, m_uiImage); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); if(m_bMipMap) { gluBuild2DMipmaps(GL_TEXTURE_2D, uiType, m_uiWidth, m_uiHeight, uiType, GL_UNSIGNED_BYTE, ucpData); } else { glTexImage2D(GL_TEXTURE_2D, 0, uiType, m_uiWidth, m_uiHeight, 0, uiType, GL_UNSIGNED_BYTE, ucpData); } delete [] ucpData; delete [] m_ucpBuffer; APP->Log(COLOR_GREEN, "TGA Image: %s Loaded", m_szFilename); return true; }
// Initializer. Returns false if something went wrong, like not being able to // load the texture. bool Ground::Initialize(void) { //setupTexDefault("tex/grass.tga", texture_obj); ubyte *image_data; int image_height, image_width; // Load the image for the texture. The texture file has to be in // a place where it will be found. if ( ! ( image_data = (ubyte*)tga_load("tex/grass.tga", &image_width, &image_height, TGA_TRUECOLOR_24) ) ) { fprintf(stderr, "Ground::Initialize: Couldn't load grass.tga\n"); return false; } // This creates a texture object and binds it, so the next few operations // apply to this texture. glGenTextures(1, &texture_obj); glBindTexture(GL_TEXTURE_2D, texture_obj); // This sets a parameter for how the texture is loaded and interpreted. // basically, it says that the data is packed tightly in the image array. glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // This sets up the texture with high quality filtering. First it builds // mipmaps from the image data, then it sets the filtering parameters // and the wrapping parameters. We want the grass to be repeated over the // ground. gluBuild2DMipmaps(GL_TEXTURE_2D,3, image_width, image_height, GL_RGB, GL_UNSIGNED_BYTE, image_data); 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_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); // This says what to do with the texture. Modulate will multiply the // texture by the underlying color. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); delete[] image_data; // Now do the geometry. Create the display list. display_list = glGenLists(1); glNewList(display_list, GL_COMPILE); // Use white, because the texture supplies the color. glColor3f(1.0, 1.0, 1.0); // The surface normal is up for the ground. glNormal3f(0.0, 0.0, 1.0); // Turn on texturing and bind the grass texture. glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture_obj); // Draw the ground as a quadrilateral, specifying texture coordinates. glBegin(GL_QUADS); glTexCoord2f(20.0, 20.0); glVertex3f(160.0, 160.0, 0.0); glTexCoord2f(0.0, 20.0); glVertex3f(-160.0, 160.0, 0.0); glTexCoord2f(0.0, 0.0); glVertex3f(-160.0, -160.0, 0.0); glTexCoord2f(20.0, 0.0); glVertex3f(160.0, -160.0, 0.0); glEnd(); // Turn texturing off again, because we don't want everything else to // be textured. glDisable(GL_TEXTURE_2D); glEndList(); // We only do all this stuff once, when the GL context is first set up. initialized = true; return true; }
//------------------------------------------------------------- //- LoadBMP //- Loads a windows bitmap (24 bit) //------------------------------------------------------------- bool CImage::LoadBMP() { unsigned char * ucpPtr = m_ucpBuffer; unsigned char * ucpData = 0; //BMP File header struct SBMPFHeader { unsigned char m_ucType[2]; //Identifier, must be BM unsigned int m_uiSize; //Size of BMP file unsigned int m_uiReserved; //0 unsigned int m_uiOffset; }; //BMP Information Header struct SBMPIHeader { unsigned int m_uiSize; //Number of bytes in structure unsigned int m_uiWidth; //Width of Image unsigned int m_uiHeight; //Height of Image unsigned short m_uiPlanes; //Always 1 unsigned short m_uiBpp; //Bits Per Pixel (must be 24 for now) unsigned int m_uiCompression; //Must be 0 (uncompressed) unsigned int m_uiXPPM; //X Pels Per Meter unsigned int m_uiYPPM; //Y Pels Per Meter unsigned int m_uiClrUsed; //0 for 24 bpp bmps unsigned int m_uiClrImp; //0 }; SBMPFHeader * pFileHeader = (SBMPFHeader *)ucpPtr; ucpPtr += 14; //Skip the file header SBMPIHeader * pInfoHeader = (SBMPIHeader *)(ucpPtr); ucpPtr += 40; //make sure its 24 bpp and contains data if(pInfoHeader->m_uiBpp != 24 || pInfoHeader->m_uiHeight == 0 || pInfoHeader->m_uiWidth == 0) { delete [] m_ucpBuffer; APP->Log(COLOR_RED, "%s is an invalid BMP file", m_szFilename); return false; } //Fill in data for later use m_uiWidth = pInfoHeader->m_uiWidth; m_uiHeight = pInfoHeader->m_uiHeight; m_uiFileLen = pFileHeader->m_uiSize; //Fill in the data ucpData = new unsigned char[m_uiHeight * m_uiWidth * 3]; if(!ucpData) { APP->Log(COLOR_RED, "Out of memory"); return false; } //Swap red and blue values to get RGB instead of BGR for(unsigned int i = 0; i < m_uiHeight * m_uiWidth * 3; i+=3) { ucpData[i] = ucpPtr[i+2]; ucpData[i+1] = ucpPtr[i+1]; ucpData[i+2] = ucpPtr[i]; } VFlip(ucpData, m_uiWidth, m_uiHeight, 3); glGenTextures(1, &m_uiImage); glBindTexture(GL_TEXTURE_2D, m_uiImage); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); if(m_bMipMap) { gluBuild2DMipmaps(GL_TEXTURE_2D, 3, m_uiWidth, m_uiHeight, GL_RGB, GL_UNSIGNED_BYTE, ucpData); } else { glTexImage2D(GL_TEXTURE_2D, 0, 3, m_uiWidth, m_uiHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, ucpData); } delete [] ucpData; delete [] m_ucpBuffer; APP->Log(COLOR_GREEN, "BMP Image: %s Loaded", m_szFilename); return true; }
/* * tdDraw() * * mode - primitive drawing mode. Can be one of the following: * TD_POINTS - vertexes only only * TD_LINES - lines drawn around each polygon * TD_LINE_LOOP - line loop drawn around each polygon * TD_LINE_STRIP - line strip drawn around each polygon * TD_TRIANGLES - triangles (must use tdGenTriangles()) * TD_TRIANGLE_STRIP - triangle strips (UNIMPLEMENTED) * TD_TRIANGLE_FAN - triangle fan * TD_QUADS - quadrilaterals (must use tdGenQuads()) * TD_QUAD_STRIP - quad strips (UNIMPLEMENTED) * TD_POLYGON - polygons * mask - a mask indicating what type(s) of data to use to draw with. * A bitwise OR of one or more of the following: * TD_VERTEX - send vertex data (default) * TD_NORMAL - send normal data * TD_TEXVERTEX - send texture vertex data * TD_MATERIAL - send material data * TD_ALL - send all of the above * * RETURNs TD_TRUE if all went well, TD_FALSE if an error occurred */ TDboolean tdDraw(TDobject *object, TDprimitive mode, int mask) { register int i; static TDmaterial *material; static TDgroup *group; static TDface *face; /* check for some errors */ if(!object) { _tdPrintf(TD_ERROR, "can't draw a null object!"); return(TD_FALSE); } if(!object->vertices) { _tdPrintf(TD_ERROR, "no vertex data in object `%s'!", object->name); return(TD_FALSE); } /* check for invalid masks */ if((mode & TD_TEXVERTEX) && !object->texvertices) { _tdPrintf(TD_WARNING, "no texture vertices in object `%s'!", object->name); mask &= ~TD_TEXVERTEX; } if((mode & TD_NORMAL) && !object->normals) { _tdPrintf(TD_WARNING, "no normals in object `%s'!", object->name); mask &= ~TD_NORMAL; } switch(mode) { case TD_POINTS: glBegin(TD_POINTS); /* TODO - need to figure out materials for points */ for(i = 1; i <= object->num_vertices; i++) { /* send texture coordinate */ if(mask & TD_TEXVERTEX) glTexCoord2fv((float *)&(object->texvertices[i])); /* send normal */ if(mask & TD_NORMAL) glNormal3fv((float *)&(object->normals[i])); /* send vertex */ glVertex3fv((float *)&(object->vertices[i])); } glEnd(); break; case TD_TRIANGLES: glBegin(TD_TRIANGLES); group = object->groups; while(group) { material = group->material; if((mask & TD_MATERIAL) && material) { glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (GLfloat *)&(material->diffuse)); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (GLfloat *)&(material->ambient)); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (GLfloat *)&(material->specular)); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material->shininess); if(mask & TD_TEXVERTEX && material->teximage) { glEnable(GL_TEXTURE_2D); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); gluBuild2DMipmaps(GL_TEXTURE_2D, 3, material->teximage->width, material->teximage->height, GL_RGB, GL_UNSIGNED_BYTE, material->teximage->data); } } face = group->triangles; while(face) { for(i = 0; i < 3; i++) { /* send texture vertex */ if(mask & TD_TEXVERTEX) tdTexCoord(object, face, i); /* send normal */ if(mask & TD_NORMAL) tdNormal(object, face, i); /* send vertex */ tdVertex(object, face, i); } face = face->next; } group = group->next; } glEnd(); break; #if 0 case TD_TRIANGLE_STRIP: group = object->groups; while(group) { face = group->tristrips; while(face) { glBegin(mode); for(i = 0; i < face->num_vertices; i++) { /* send texture vertex */ if(mask & TD_TEXVERTEX) tdTexCoord(object, face, i); /* send normal */ if(mask & TD_NORMAL) tdNormal(object, face, i); /* send vertex */ tdVertex(object, face, i); } glEnd(); face = face->next; } group = group->next; } break; #endif case TD_LINES: group = object->groups; while(group) { material = group->material; if((mask & TD_MATERIAL) && material) { glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (GLfloat *)&(material->diffuse)); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (GLfloat *)&(material->ambient)); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (GLfloat *)&(material->specular)); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material->shininess); if(mask & TD_TEXVERTEX && material->teximage) { glEnable(GL_TEXTURE_2D); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); gluBuild2DMipmaps(GL_TEXTURE_2D, 3, material->teximage->width, material->teximage->height, GL_RGB, GL_UNSIGNED_BYTE, material->teximage->data); } } face = group->faces; while(face) { glBegin(TD_LINES); for(i = 0; i < face->num_vertices; i++) { /* send texture vertex */ if(mask & TD_TEXVERTEX) tdTexCoord(object, face, i); /* send normal */ if(mask & TD_NORMAL) tdNormal(object, face, i); /* send vertex */ tdVertex(object, face, i); /* send texture vertex */ if(mask & TD_TEXVERTEX) tdTexCoord(object, face, (i == face->num_vertices - 1 ? 0 : (i + 1))); /* send normal */ if(mask & TD_NORMAL) tdNormal(object, face, (i == face->num_vertices - 1 ? 0 : (i + 1))); /* send vertex */ tdVertex(object, face, (i == face->num_vertices - 1 ? 0 : (i + 1))); } glEnd(); face = face->next; } group = group->next; } break; case TD_LINE_LOOP: group = object->groups; while(group) { material = group->material; if((mask & TD_MATERIAL) && material) { glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (GLfloat *)&(material->diffuse)); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (GLfloat *)&(material->ambient)); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (GLfloat *)&(material->specular)); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material->shininess); if(mask & TD_TEXVERTEX && material->teximage) { glEnable(GL_TEXTURE_2D); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); gluBuild2DMipmaps(GL_TEXTURE_2D, 3, material->teximage->width, material->teximage->height, GL_RGB, GL_UNSIGNED_BYTE, material->teximage->data); } } face = group->faces; while(face) { glBegin(mode); for(i = 0; i < face->num_vertices; i++) { /* send texture vertex */ if(mask & TD_TEXVERTEX) tdTexCoord(object, face, i); /* send normal */ if(mask & TD_NORMAL) tdNormal(object, face, i); /* send vertex */ tdVertex(object, face, i); } /* finish the loop */ /* send texture vertex */ if(mask & TD_TEXVERTEX) tdTexCoord(object, face, 0); /* send normal */ if(mask & TD_NORMAL) tdNormal(object, face, 0); /* send vertex */ tdVertex(object, face, 0); glEnd(); face = face->next; } group = group->next; } break; case TD_LINE_STRIP: case TD_TRIANGLE_FAN: case TD_POLYGON: group = object->groups; while(group) { material = group->material; if((mask & TD_MATERIAL) && material) { glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (GLfloat *)&(material->diffuse)); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (GLfloat *)&(material->ambient)); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (GLfloat *)&(material->specular)); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material->shininess); if(mask & TD_TEXVERTEX && material->teximage) { glEnable(GL_TEXTURE_2D); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); gluBuild2DMipmaps(GL_TEXTURE_2D, 3, material->teximage->width, material->teximage->height, GL_RGB, GL_UNSIGNED_BYTE, material->teximage->data); /* TODO - figure some way to get all the textures in a dlist */ #if 0 if(material->dlist) { glCallList(material->dlist); printf("called list\n"); } else { material->dlist = glGenLists(1); glNewList(material->dlist, GL_COMPILE_AND_EXECUTE); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); gluBuild2DMipmaps(GL_TEXTURE_2D, 3, material->teximage->width, material->teximage->height, GL_RGB, GL_UNSIGNED_BYTE, material->teximage->data); glEndList(); printf("built list %d\n", material->dlist); } #endif } } face = group->faces; while(face) { glBegin(mode); for(i = 0; i < face->num_vertices; i++) { /* send texture vertex */ if(mask & TD_TEXVERTEX) tdTexCoord(object, face, i); /* send normal */ if(mask & TD_NORMAL) tdNormal(object, face, i); /* send vertex */ tdVertex(object, face, i); } glEnd(); face = face->next; } if(material) { if(mask & TD_TEXVERTEX && material->teximage) glDisable(GL_TEXTURE_2D); } group = group->next; } break; case TD_QUADS: glBegin(TD_QUADS); group = object->groups; while(group) { material = group->material; if((mask & TD_MATERIAL) && material) { glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (GLfloat *)&(material->diffuse)); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (GLfloat *)&(material->ambient)); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (GLfloat *)&(material->specular)); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material->shininess); if(mask & TD_TEXVERTEX && material->teximage) { glEnable(GL_TEXTURE_2D); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); gluBuild2DMipmaps(GL_TEXTURE_2D, 3, material->teximage->width, material->teximage->height, GL_RGB, GL_UNSIGNED_BYTE, material->teximage->data); } } face = group->quads; while(face) { for(i = 0; i < 4; i++) { /* send texture vertex */ if(mask & TD_TEXVERTEX) tdTexCoord(object, face, i); /* send normal */ if(mask & TD_NORMAL) tdNormal(object, face, i); /* send vertex */ tdVertex(object, face, i); } face = face->next; } group = group->next; } glEnd(); break; #if 0 case TD_QUAD_STRIP: break; #endif default: /* none of the above */ return(TD_FALSE); break; } return(TD_TRUE); }