diff --git a/src/nvtt/tools/CMakeLists.txt b/src/nvtt/tools/CMakeLists.txt index f6e13d8..4272c53 100644 --- a/src/nvtt/tools/CMakeLists.txt +++ b/src/nvtt/tools/CMakeLists.txt @@ -19,12 +19,12 @@ TARGET_LINK_LIBRARIES(nvzoom nvcore nvmath nvimage) SET(TOOLS nvcompress nvdecompress nvddsinfo nvassemble nvzoom) -#IF(GLEW_FOUND AND GLUT_FOUND) -# INCLUDE_DIRECTORIES(${GLEW_INCLUDE_PATH} ${GLUT_INCLUDE_DIR}) -# ADD_EXECUTABLE(nvddsview ddsview.cpp cmdline.h) -# TARGET_LINK_LIBRARIES(nvddsview nvcore nvmath nvimage ${GLEW_LIBRARY} ${GLUT_LIBRARY}) -# SET(TOOLS ${TOOLS} nvddsview) -#ENDIF(GLEW_FOUND AND GLUT_FOUND) +IF(GLEW_FOUND AND GLUT_FOUND AND OPENGL_FOUND) + INCLUDE_DIRECTORIES(${GLEW_INCLUDE_PATH} ${GLUT_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR}) + ADD_EXECUTABLE(nvddsview ddsview.cpp cmdline.h) + TARGET_LINK_LIBRARIES(nvddsview nvcore nvmath nvimage ${GLEW_LIBRARY} ${GLUT_LIBRARY} ${OPENGL_LIBRARY}) + SET(TOOLS ${TOOLS} nvddsview) +ENDIF(GLEW_FOUND AND GLUT_FOUND AND OPENGL_FOUND) ADD_EXECUTABLE(nv-gnome-thumbnailer thumbnailer.cpp cmdline.h) diff --git a/src/nvtt/tools/ddsview.cpp b/src/nvtt/tools/ddsview.cpp index 7153f3e..3296d62 100644 --- a/src/nvtt/tools/ddsview.cpp +++ b/src/nvtt/tools/ddsview.cpp @@ -27,20 +27,32 @@ #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 tx = 0, ty = 0; +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() { @@ -59,152 +71,234 @@ void initOpengl() glEnable(GL_DEPTH_TEST); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glEnable(GL_TEXTURE_2D); + glutReportErrors(); } -GLuint createTexture(GLenum target, GLint internalformat, GLenum format, GLenum type, int w, int h) +GLuint createTexture(nv::DirectDrawSurface & dds) { GLuint tex; glGenTextures(1, &tex); - glBindTexture(target, tex); - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(target, 0, internalformat, w, h, 0, format, type, 0); - return 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. + } } void drawQuad() { + //glColor3f(1, 0, 0); glBegin(GL_QUADS); - glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, -1.0); - glTexCoord2f(1.0, 0.0); glVertex2f(1.0, -1.0); - glTexCoord2f(1.0, 1.0); glVertex2f(1.0, 1.0); - glTexCoord2f(0.0, 1.0); glVertex2f(-1.0, 1.0); + 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) { - switch(key) { - case 27: - case 'q': - exit(0); - break; - - case '=': - case '+': - scale *= 1.5; - break; - - case '-': - case '_': - scale /= 1.5; - break; - - case 'r': - scale = 1.0; - tx = ty = 0.0; - break; - } + keys[key] = true; + glutPostRedisplay(); } void glutKeyboardUpCallback(unsigned char key, int x, int y) { + keys[key] = false; + glutPostRedisplay(); } -void special(int key, int x, int y) +void glutSpecialCallback(int key, int x, int y) { - switch(key) { - case GLUT_KEY_RIGHT: - tx -= 0.1; - break; - case GLUT_KEY_LEFT: - tx += 0.1; - break; - case GLUT_KEY_DOWN: - ty += 0.1; - break; - case GLUT_KEY_UP: - ty -= 0.1; - break; + 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) { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + processKeys(); - drawQuad(); + // Draw texture. + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glutSwapBuffers(); + 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) { - //glutPostRedisplay(); + //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; + 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; - } + 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(argv[1]); - if (!dds.isValid()) - { - printf("The file '%s' is not a valid DDS file.\n", argv[1]); - return 1; - } - - uint w = dds.width(); - uint h = dds.height(); + // Load surface. + nv::DirectDrawSurface dds; - // @@ Clamp window size if texture larger than desktop? + 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); + glutInit(&argc, argv); - glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH ); - glutInitWindowSize( w, h ); - glutCreateWindow( "DDS View" ); - glutKeyboardFunc( glutKeyboardCallback ); - glutKeyboardUpFunc( glutKeyboardUpCallback ); - glutDisplayFunc( glutDisplayCallback ); - glutIdleFunc( glutIdleCallback ); + 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(); + initOpengl(); - /* - glGenTextures(1, &tex0); - glBindTexture(GL_TEXTURE_2D, tex0); - 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, img_w, img_h, 0, image.getFormat(), image.getType(), image.getLevel(0)); - */ - //tex0 = createTexture(GL_TEXTURE_2D, GL_RGBA, GL_RGBA, type, w, h,); + tex0 = createTexture(dds); - // @@ Add IMGUI, fade in and out depending on mouse movement. + // @@ Add IMGUI, fade in and out when mouse over. - glutMainLoop(); + glutMainLoop(); - return 0; + return 0; }