void Texture::initRGBFile(const char* imgFile) { static GLubyte *texData; GLfloat borderColor[4] = { 1.0, 1.0, 1.0, 1.0 }; int width, height; int w, h; GLubyte *image, *img, *p; int i, j, components; image = (GLubyte *)read_rgb_texture(imgFile, &width, &height, &components); //w = width + 2 * 2; //h = height + 2 * 2; w = width; h = height; img = (GLubyte *)calloc(w * h, 4 * sizeof(unsigned char)); p = img; // for (j = -2; j < height + 2; ++j) { // for (i = -2; i < width + 2; ++i) { for (j = 0; j < height; ++j) { for (i = 0; i < width; ++i) { if (0 <= j && j <= height - 1 && 0 <= i && i <= width - 1) { p[0] = image[4 * (j * width + i) + 0]; p[1] = image[4 * (j * width + i) + 1]; p[2] = image[4 * (j * width + i) + 2]; p[3] = 0xff; } else { p[0] = borderColor[0] * 0xff; p[1] = borderColor[1] * 0xff; p[2] = borderColor[2] * 0xff; p[3] = borderColor[3] * 0xff; } p += 4; } } free(image); glGenTextures(1, texture); glBindTexture(GL_TEXTURE_2D, texture[0]); 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); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); //gluBuild2DMipmaps(GL_TEXTURE_2D, 4, w, h, // GL_RGBA, GL_UNSIGNED_BYTE, img); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, img); glBindTexture(GL_TEXTURE_2D, 0); }
int main(int argc, char **argv) { int width, height; int i; GLubyte *imageData; glutInit(&argc, argv); for (i=1; i<argc; i++) { if (!strcmp("-lesstex", argv[i])) { /* Only use 16 caustic textures. Saves texture memory and works better on slow machines. */ causticIncrement = 2; } else if (!strcmp("-evenlesstex", argv[i])) { /* Only use 8 caustic textures. Saves even more texture memory for slow machines. Temporal rippling suffers. */ causticIncrement = 4; } else if (!strcmp("-nomipmap", argv[i])) { /* Don't use linear mipmap linear texture filtering; instead use linear filtering. */ useMipmaps = 0; } else if (!strcmp("-fullscreen", argv[i])) { fullscreen = 1; } else { fprintf(stderr, "usage: caustics [-lesstex]\n"); fprintf(stderr, " -lesstex uses half the caustic textures.\n"); fprintf(stderr, " -evenlesstex uses one fourth of the caustic textures.\n"); exit(1); } } glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE); if (fullscreen) { glutGameModeString("800x600:16@60"); glutEnterGameMode(); } else { glutCreateWindow("underwater"); } /* Check that renderer has the GL_EXT_texture_object extension or supports OpenGL 1.1 */ #ifdef TEXTURE_OBJECT { char *version = (char *) glGetString(GL_VERSION); if (glutExtensionSupported("GL_EXT_texture_object") || strncmp(version, "1.1", 3) == 0) { HaveTexObj = GL_TRUE; } } #endif glEnable(GL_TEXTURE_2D); #ifdef TEXTURE_OBJECT /* Replace texture environment not in OpenGL 1.0. */ if (HaveTexObj) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); #endif /* Load the caustic ripple textures. */ printf("loading caustics:"); for (i=0; i<NUM_PATTERNS; i += causticIncrement) { char filename[80]; sprintf(filename, "caust%02d.bw", i); printf(" %d", i); fflush(stdout); imageData = read_alpha_texture(filename, &width, &height); if (imageData == NULL) { fprintf(stderr, "\n%s: could not load image file\n", filename); exit(1); } if (HaveTexObj) glBindTexture(GL_TEXTURE_2D, i+1); else glNewList(i+101, GL_COMPILE); if (useMipmaps) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gluBuild2DMipmaps(GL_TEXTURE_2D, GL_LUMINANCE, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, imageData); } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, height, width, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, imageData); } free(imageData); if (!HaveTexObj) glEndList(); } printf(".\n"); /* Load an RGB file for the floor texture. */ printf("loading RGB textures: floor"); fflush(stdout); imageData = read_rgb_texture(FLOOR_FILE, &width, &height); if (imageData == NULL) { fprintf(stderr, "%s: could not load image file\n", FLOOR_FILE); exit(1); } printf(".\n"); if (HaveTexObj) glBindTexture(GL_TEXTURE_2D, 100); else glNewList(100, GL_COMPILE); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); if (useMipmaps) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height, GL_RGB, GL_UNSIGNED_BYTE, imageData); } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, imageData); } free(imageData); if (!HaveTexObj) glEndList(); glMatrixMode(GL_MODELVIEW); gluLookAt(0.0, 8.0, 60.0, /* eye is at (0,8,60) */ 0.0, 8.0, 0.0, /* center is at (0,8,0) */ 0.0, 1.0, 0.); /* up is in postivie Y direction */ /* Setup initial OpenGL rendering state. */ glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuseColor); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); /* Register assorted GLUT callback routines. */ glutDisplayFunc(display); glutReshapeFunc(reshape); glutVisibilityFunc(visible); glutMouseFunc(mouse); glutMotionFunc(motion); glutKeyboardFunc(keyboard); /* Create a pop-up menu. */ if (!fullscreen) { glutCreateMenu(menuSelect); glutAddMenuEntry("Positional light", M_POSITIONAL); glutAddMenuEntry("Directional light", M_DIRECTIONAL); glutAddMenuEntry("Greenish light", M_GREENISH_LIGHT); glutAddMenuEntry("White light", M_WHITE_LIGHT); glutAddMenuEntry("With caustics", M_WITH_CAUSTICS); glutAddMenuEntry("No caustics", M_NO_CAUSTICS); glutAddMenuEntry("Switch model", M_SWITCH_MODEL); glutAddMenuEntry("Increase ripple size", M_INCREASE_RIPPLE_SIZE); glutAddMenuEntry("Decrease ripple size", M_DECREASE_RIPPLE_SIZE); glutAttachMenu(GLUT_RIGHT_BUTTON); } /* For rendering the MODEL_DINO object. */ dinoDisplayList = makeDinosaur(); /* Enter GLUT's main loop; callback dispatching begins. */ glutMainLoop(); return 0; /* ANSI C requires main to return int. */ }