// Copyright NVIDIA Corporation 2007 -- Ignacio Castano // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, // copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. #include #include #include #include #define GLEW_STATIC #include #if NV_OS_DARWIN #include #else #include #endif #include "cmdline.h" GLuint tex0, tex1; float scale = 1.0f; float target_scale = 1.0f; float x = 0, y = 0; float target_x = 0, target_y = 0; int level = 0; int max_level = 0; int win_w, win_h; int w, h; bool keys[256]; void initOpengl() { glewInit(); if (!glewIsSupported( "GL_VERSION_2_0 " "GL_ARB_vertex_program " "GL_ARB_fragment_program " )) { printf("Unable to load required extension\n"); exit(-1); } glEnable(GL_DEPTH_TEST); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glEnable(GL_TEXTURE_2D); glutReportErrors(); } GLuint createTexture(nv::DirectDrawSurface & dds) { GLuint tex; glGenTextures(1, &tex); if (dds.isTexture2D()) { glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_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); const uint count = dds.mipmapCount(); max_level = count - 1; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, max_level); for (uint i = 0; i < count; i++) { nv::Image img; dds.mipmap(&img, 0, i); // face, mipmap glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, img.width(), img.height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, img.pixels()); } } else { // Add support for cubemaps. } return tex; } void drawQuad() { //glColor3f(1, 0, 0); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex2f(-w, h); glTexCoord2f(1.0, 0.0); glVertex2f(w, h); glTexCoord2f(1.0, 1.0); glVertex2f(w, -h); glTexCoord2f(0.0, 1.0); glVertex2f(-w, -h); glEnd(); } void glutKeyboardCallback(unsigned char key, int x, int y) { keys[key] = true; glutPostRedisplay(); } void glutKeyboardUpCallback(unsigned char key, int x, int y) { keys[key] = false; glutPostRedisplay(); } void glutSpecialCallback(int key, int x, int y) { if (key >= 0 && key < 256) { keys[key] = true; } glutPostRedisplay(); } void glutSpecialUpCallback(int key, int x, int y) { if (key >= 0 && key < 256) { keys[key] = false; } glutPostRedisplay(); } void glutReshapeCallback(int w, int h) { win_w = w; win_h = h; glViewport(0, 0, w, h); } void processKeys() { // Process keys. if (keys['q']) { exit(0); } if (keys['='] || keys['+']) { target_scale += target_scale / 16; } if (keys['-'] || keys['_']) { target_scale -= target_scale / 16; } if (keys['r']) { target_scale = 1.0; target_x = target_y = 0.0; } if (keys[GLUT_KEY_RIGHT]) { target_x -= 1 / scale; if (target_x < -w) target_x = -w; } if (keys[GLUT_KEY_LEFT]) { target_x += 1 / scale; if (target_x > w) target_x = w; } if (keys[GLUT_KEY_DOWN]) { target_y += 1 / scale; if (target_y > h) target_y = h; } if (keys[GLUT_KEY_UP]) { target_y -= 1 / scale; if (target_y < -h) target_y = -h; } if (keys[GLUT_KEY_PAGE_DOWN]) { if (level < max_level) level++; } if (keys[GLUT_KEY_PAGE_UP]) { if (level > 0) level--; } // Update parameters. /*if (scale < target_scale) { scale *= 1.001; // if (scale > target_scale) scale = target_scale; } else if (scale > target_scale) { scale *= 0.999; // if (scale < target_scale) scale = target_scale; }*/ if (scale != target_scale) { glutPostRedisplay(); } } void glutDisplayCallback(void) { processKeys(); // Draw texture. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindTexture(GL_TEXTURE_2D, tex0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glScalef(target_scale/win_w, target_scale/win_h, 1); glTranslatef(target_x, target_y, 0); drawQuad(); glutSwapBuffers(); } void glutIdleCallback(void) { //processKeys(); glutPostRedisplay(); } // View options: // - Display RGB // - Display RGBA // - Display Alpha // - Zoom in/out // - Wrap around or clamp // - View mipmaps. // - View cube faces. // - View cube map. int main(int argc, char *argv[]) { MyAssertHandler assertHandler; MyMessageHandler messageHandler; if (argc != 2 && argc != 3) { printf("NVIDIA Texture Tools - Copyright NVIDIA Corporation 2007\n\n"); printf("usage: nvddsview file0 [file1]\n\n"); return 1; } // Load surface. nv::DirectDrawSurface dds; if (!dds.load(argv[1]) || !dds.isValid()) { printf("The file '%s' is not a valid DDS file.\n", argv[1]); return 1; } win_w = w = dds.width(); win_h = h = dds.height(); // @@ Clamp window size if texture larger than desktop? glutInit(&argc, argv); glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH ); glutInitWindowSize( win_w, win_h ); glutCreateWindow( "DDS View" ); glutReshapeFunc( glutReshapeCallback ); glutKeyboardFunc( glutKeyboardCallback ); glutKeyboardUpFunc( glutKeyboardUpCallback ); glutSpecialFunc( glutSpecialCallback ); glutSpecialUpFunc( glutSpecialUpCallback ); glutDisplayFunc( glutDisplayCallback ); glutIdleFunc( glutIdleCallback ); initOpengl(); tex0 = createTexture(dds); // @@ Add IMGUI, fade in and out when mouse over. glutMainLoop(); return 0; }