/* * Demonstration of GL_ARB_texture_env_combine */ #include #include #include #include #include #include #ifdef WIN32 PFNGLACTIVETEXTUREPROC glActiveTexture; PFNGLMULTITEXCOORD2FPROC glMultiTexCoord2f; #endif /* Minimum stack space */ static USED const char *stack = "$STACK:65535"; GLubyte *LoadPPM(char *name, GLint *w, GLint *h) { int i; unsigned long x,y; FILE *f; GLubyte *where; f = fopen(name, "rb"); if (!f) { printf("PPM open failed\n"); *w = 0; *h=0; return NULL; } i = fscanf(f, "P6\n"); if(fgetc(f) == '#'){ while(fgetc(f) != '\n' && !ferror(f)){ ; } if(ferror(f)){ printf("PPM open failed\n"); *w = 0; *h=0; return NULL; } } else{ fseek(f, -1, SEEK_CUR); } i += fscanf(f,"%ld %ld\n255\n", &x, &y); *w = x; *h = y; where = (GLubyte *)malloc(x*y*3); if (!where) { printf("Error out of Memory\n"); fclose(f); *w = 0; *h = 0; return NULL; } i = fread(where, 1, x*y*3, f); fclose(f); if (i != x*y*3) { printf("Error while reading file\n"); free(where); *w = 0; *h = 0; return NULL; } return where; } /* GLUT callback Handlers */ static void resize(int width, int height) { const float ar = (float) width / (float) height; glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity() ; } static void display(void) { static float t = 0.0f; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(1.0f, 1.0f, 1.0f); t += 0.01f; glPushMatrix(); glTranslated(0, 0, -6); glRotated(-190+8.0*t,1,0,0); glScalef(2.0f, 2.0f, 2.0f); glBegin(GL_QUADS); glColor3f(1.0f, 0.0f, 0.0f); glMultiTexCoord2f(GL_TEXTURE0, 0.0f, 0.0f); glMultiTexCoord2f(GL_TEXTURE1, t+0.0f, t+0.0f); glVertex2f(-1.0f, -1.0f); glColor3f(1.0f, 1.0f, 1.0f); glMultiTexCoord2f(GL_TEXTURE0, 0.0f, 1.0f); glMultiTexCoord2f(GL_TEXTURE1, t+0.0f, t+1.0f); glVertex2f(-1.0f, 1.0f); glColor3f(1.0f, 1.0f, 1.0f); glMultiTexCoord2f(GL_TEXTURE0, 1.0f, 1.0f); glMultiTexCoord2f(GL_TEXTURE1, t+1.0f, t+1.0f); glVertex2f(1.0f, 1.0f); glColor3f(0.0f, 0.0f, 0.0f); glMultiTexCoord2f(GL_TEXTURE0, 1.0f, 0.0f); glMultiTexCoord2f(GL_TEXTURE1, t+1.0f, t+0.0f); glVertex2f(1.0f, -1.0f); glEnd(); glPopMatrix(); glutSwapBuffers(); } static void key(unsigned char key, int x, int y) { switch (key) { case 27 : case 'q': exit(0); break; case '1': glActiveTexture(GL_TEXTURE0); break; case '2': glActiveTexture(GL_TEXTURE1); break; case 'a': glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD); break; case 's': glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD_SIGNED); break; case 'm': glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); break; case 'n': glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_SUBTRACT); break; case 'r': glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); break; case 'd': glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); break; case 'o': glEnable(GL_TEXTURE_2D); break; case 'p': glDisable(GL_TEXTURE_2D); break; case '9': glEnable(GL_CULL_FACE); glFrontFace(GL_CCW); glCullFace(GL_BACK); break; case '8': glDisable(GL_CULL_FACE); glFrontFace(GL_CCW); glCullFace(GL_BACK); break; } glutPostRedisplay(); } static void idle(void) { glutPostRedisplay(); } void MakeTextures(void) { GLint w,h; GLubyte *tex; GLuint t1,t2; tex = LoadPPM("data/door.ppm", &w, &h); assert(tex != NULL); glGenTextures(1, &t1); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, t1); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, tex); free(tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); tex = LoadPPM("data/wall.ppm", &w, &h); assert(tex != NULL); glGenTextures(1, &t2); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, t2); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, tex); free(tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glActiveTexture(GL_TEXTURE0); glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_PREVIOUS); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); glActiveTexture(GL_TEXTURE1); glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); glActiveTexture(GL_TEXTURE0); assert(glGetError() == GL_NO_ERROR); } /* Program entry point */ int main(int argc, char *argv[]) { const char *extensions; glutInit(&argc, argv); glutInitWindowSize(640,480); glutInitWindowPosition(10,10); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutCreateWindow("GL_ARB_texture_env_combine Demo"); glutReshapeFunc(resize); glutDisplayFunc(display); glutKeyboardFunc(key); glutIdleFunc(idle); extensions = (char *)glGetString(GL_EXTENSIONS); if (strstr(extensions, "GL_ARB_texture_env_combine") == 0) { printf("Sorry, your graphics card does not support the extension" \ "\"GL_ARB_texture_env_combine\" required for this demo\n"); return 0; } #ifdef WIN32 glActiveTexture = (PFNGLACTIVETEXTUREPROC) glutGetProcAddress("glActiveTexture"); glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC) glutGetProcAddress("glMultiTexCoord2f"); #endif MakeTextures(); glClearColor(1,1,1,1); glDisable(GL_CULL_FACE); glCullFace(GL_BACK); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glutMainLoop(); return EXIT_SUCCESS; }