home *** CD-ROM | disk | FTP | other *** search
- //------------------------------ GRTeapotApplication.cpp ------------------------------
-
- // --------------------------------------------------------
- // ⌐ 2004-2005 Graphic Remedy. All Rights Reserved.
- // --------------------------------------------------------
-
-
- // Standard C:
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
-
- // Win32:
- #include <Windows.h>
-
- // OpenGL:
- #include <GL/gl.h>
- #include <GL/glext.h>
-
- // Free image:
- #include <FreeImage.h>
-
- // Local:
- #include <res/resource.h>
-
-
- // --- Strings definitions ---
-
- #define TP_HEADS_UP_DISPLAY_MESSAGE "Press H for help"
- #define TP_DRAWING_TEAPOT_MARKER_STR "Drawing a teapot: grid = %d, scale = %d"
- #define TP_SETTING_UP_MATERIAL_MARKER_STR "Setting up material"
- #define TP_SETTING_UP_LIGHTS_MARKER_STR "Setting up lights"
- #define TP_GENERAL_INIT_MARKER_STR "Performing general OpenGL intializations"
- #define TO_CREATION_GLSL_OBJECTS_MARKER_STR "Creating GLSL programs and shaders"
- #define TP_DRAWING_SCENE_MARKER_STR "Drawing scene objects"
- #define TP_MAIN_WINDOW_CAPTION_STR " Graphic Remedy teapot"
- #define TP_MAIN_WINDOW_CLASS_NAME_STR "GRTeapotApplication main window class name";
- #define TP_HELP_DIALOG_CAPTION_STR "Graphic Remedy teapot help"
- #define TP_OPEN_GL_ERROR_EXAMPLE_STR "Example of an OpenGL error"
- #define TP_CRASH_EXAMPLE_STR "Example of an application crash"
- #define TP_BREAK_POINT_EXAMPLE_STR "Example of a breakpoint exception"
- #define TP_DEBUG_STRING_EXAMPLE_STR "A sample output debug string"
- #define TP_ERROR_SRT "Error"
- #define TP_CHOOSE_PIXEL_FORMAT_ERR_SRT "ChoosePixelFormat failed"
- #define TP_SET_PIXEL_FORMAT_ERR_SRT "SetPixelFormat failed"
- #define TP_CREATE_WINDOW_ERR_SRT "Failed to create the application window"
- #define TP_CREATE_RENDER_CONTEXT_ERR_SRT "Failed to create the OpenGL render context"
- #define TP_HELP_MESSAGE_STR \
- "Press the mouse left button and drag to rotate the image.\n\n\
- Available keyboard commands are: \n\n\
- b - Toggle background color\n\
- c - Make this application crash\n\
- d - Output a sample debug string\n\
- e - Generate an OpenGL Error\n\
- h - Display this help message\n\
- p - Generate a break point event\n\
- s - Toggle shading program use (on / off)\n\
- t - Generate a detected error\n\
- w - Toggle wire-frame mode.\n\
- - / + - Increases / decrease texture influence\n\
- esc - Exit the application"
-
- // Vertex and fragment shader code file paths:
- #define TP_VETEX_SHADER_CODE_FILE_PATH "./tpVertexShader.glsl"
- #define TP_FRAGMENT_SHADER_CODE_FILE_PATH "./tpFragmentShader.glsl"
-
- // Texture file path:
- #define TP_TEXTURE_FILE_PATH "./tpLogo-white.png"
-
- // The amount of glyphs in the system font:
- #define TP_SYSTEM_FONT_SIZE 256
-
- // The continues movement timer interval (ms):
- #define TP_TIMER_INTERVAL 10
-
- // --- Global static variables ---
-
- // Window position and size:
- static int stat_windowXPosition = 0;
- static int stat_windowYPosition = 0;
- static int stat_windowWidth = 400;
- static int stat_windowHeight = 400 + 30; // 30 is the height of the windows application bar.
-
- // Graphics view-port:
- static int stat_viewPortX = 0;
- static int stat_viewPortY = 0;
- static int stat_viewWidth = 0;
- static int stat_viewHeight = 0;
-
- // Heads up message raster position:
- static float stat_headsUpRasterPosX = 0.0f;
- static float stat_headsUpRasterPosY = 0.0f;
-
- // Window name and window class name:
- static char *stat_windowName = TP_MAIN_WINDOW_CAPTION_STR;
- static char *stat_windowClassName = TP_MAIN_WINDOW_CLASS_NAME_STR;
-
- // Device context and render context handle:
- static HDC stat_hWindowDC = NULL;
- static HGLRC stat_hWindowGLRC = NULL;
-
- // The initial mouse position:
- static GLint stat_mouseInitialPosX = 0;
- static GLint stat_mouseInitialPosY = 0;
-
- // The difference in mouse position from the last observed mouse position:
- GLint stat_mouseDeltaY = 0;
- GLint stat_mouseDeltaX = 1;
-
- // Contains true iff we are in viewing mode:
- // (when the user manipulates the object using the mouse)
- static bool stat_isInViewingMode = false;
-
- // The object rotation (degrees around the X Y and Z axis):
- static GLfloat stat_objectXRot = 45.0f;
- static GLfloat stat_objectYRot = 45.0f;
- static GLfloat stat_objectZRot = 0.0f;
-
- // The object translation:
- static GLfloat stat_objectXTran = 0.0f;
- static GLfloat stat_objectYTran = 0.0f;
- static GLfloat stat_objectZTran = 0.0f;
-
- // The id of a timer used for the continues movement:
- UINT stat_timerId = 0;
-
- // The background color index:
- static int stat_backgroundColorIndex = 1;
-
- // Set object material:
- GLfloat stat_ambient[4] = {1.0f, 0.0f, 0.0f ,1.0f };
- GLfloat stat_diffuse[4] = { 0.8f, 0.0f, 0.0f, 1.0f };
- GLfloat stat_specular[4] = { 0.8f, 0.8f, 0.8f, 1.0f };
- GLfloat stat_shininess = 20.0F;
-
- // Display lists indices:
- static GLuint stat_teaPotDisplayListIndex = 0;
- static GLuint stat_systemFontFirstDisplayList = 0;
-
- // The name of the used texture object:
- static GLuint stat_textureObjName = 0;
-
- // Average system font glyph width:
- static int stat_systemFontGlyphWidth = 8;
-
- // The used raster mode:
- static GLenum stat_rasterMode = GL_FILL;
-
- // Shaders and Programs names:
- GLhandleARB stat_vertexShaderName = 0;
- GLhandleARB stat_fragmentShaderName = 0;
- GLhandleARB stat_shadingProgramName = 0;
-
- // Controls texture influence [0,10]:
- int stat_textureInfluenceAsInt = 7;
-
- // textureInfluence uniform location in stat_shadingProgramName:
- GLint stat_textureInfluenceUniformLocation = -1;
-
- // Contains true iff the shading program was created successfully:
- bool stat_shadingProgramExists = false;
-
- // Contains true iff the shading program is currently used:
- bool stat_shadingProgramInUse = false;
-
- // String marker extension function pointer:
- PFNGLSTRINGMARKERGREMEDYPROC glStringMarkerGREMEDY = NULL;
-
- // GL_ARB_shader_objects extension functions:
- static bool stat_isGL_ARB_shader_objectsSupported = false;
- PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB = NULL;
- PFNGLSHADERSOURCEARBPROC glShaderSourceARB = NULL;
- PFNGLCOMPILESHADERARBPROC glCompileShaderARB = NULL;
- PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB = NULL;
- PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB = NULL;
- PFNGLATTACHOBJECTARBPROC glAttachObjectARB = NULL;
- PFNGLLINKPROGRAMARBPROC glLinkProgramARB = NULL;
- PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB = NULL;
- PFNGLGETINFOLOGARBPROC glGetInfoLogARB = NULL;
- PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB = NULL;
- PFNGLUNIFORM1FARBPROC glUniform1fARB = NULL;
- PFNGLDELETEOBJECTARBPROC glDeleteObjectARB = NULL;
- PFNGLDETACHOBJECTARBPROC glDetachObjectARB = NULL;
-
- // OpenGL 1.3 extension functions:
- PFNGLACTIVETEXTUREPROC glActiveTexture = NULL;
-
- // --- The teapot patch data ---
-
- static int stat_teaPotPatchData[][16] =
- {
- // Rim:
- {102, 103, 104, 105, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
-
- // Body:
- {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27},
- {24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40},
-
- // Lid:
- {96, 96, 96, 96, 97, 98, 99, 100, 101, 101, 101, 101, 0, 1, 2, 3,},
- {0, 1, 2, 3, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117},
-
- // Bottom:
- {118, 118, 118, 118, 124, 122, 119, 121, 123, 126, 125, 120, 40, 39, 38, 37},
-
- // Handle:
- {41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56},
- {53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 28, 65, 66, 67},
-
- // Spout:
- {68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83},
- {80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95}
- };
-
-
- static float stat_teaPotCPData[][3] =
- {
- {0.2f, 0.0f, 2.7f}, {0.2f, -0.112f, 2.7f}, {0.112f, -0.2f, 2.7f},
- {0.0f, -0.2f, 2.7f}, {1.3375f, 0.0f, 2.53125f}, {1.3375f, -0.749f, 2.53125f},
- {0.749f, -1.3375f, 2.53125f}, {0.0f, -1.3375f, 2.53125f}, {1.4375f, 0.0f, 2.53125f},
- {1.4375f, -0.805f, 2.53125f}, {0.805f, -1.4375f, 2.53125f}, {0.0f, -1.4375f, 2.53125f},
- {1.5f, 0.0f, 2.4f}, {1.5f, -0.84f, 2.4f}, {0.84f, -1.5f, 2.4f},
- {0.0f, -1.5f, 2.4f}, {1.75f, 0.0f, 1.875f}, {1.75f, -0.98f, 1.875f},
- {0.98f, -1.75f, 1.875f}, {0.0f, -1.75f, 1.875f}, {2.0f, 0.0f, 1.35f},
- {2.0f, -1.12f, 1.35f}, {1.12f, -2.0f, 1.35f}, {0.0f, -2.0f, 1.35f},
- {2.0f, 0.0f, 0.9f}, {2.0f, -1.12f, 0.9f}, {1.12f, -2.0f, 0.9f},
- {0.0f, -2.0f, 0.9f}, {-2.0f, 0.0f, 0.9f}, {2.0f, 0.0f, 0.45f},
- {2.0f, -1.12f, 0.45f}, {1.12f, -2.0f, 0.45f}, {0.0f, -2.0f, 0.45f},
- {1.5f, 0.0f, 0.225f}, {1.5f, -0.84f, 0.225f}, {0.84f, -1.5f, 0.225f},
- {0.0f, -1.5f, 0.225f}, {1.5f, 0.0f, 0.15f}, {1.5f, -0.84f, 0.15f},
- {0.84f, -1.5f, 0.15f}, {0.0f,-1.5f, 0.15f}, {-1.6f, 0.0f, 2.025f},
- {-1.6f, -0.3f, 2.025f}, {-1.5f, -0.3f, 2.25f}, {-1.5f, 0.0f, 2.25f},
- {-2.3f, 0.0f, 2.025f}, {-2.3f, -0.3f, 2.025f}, {-2.5f, -0.3f, 2.25f},
- {-2.5f, 0.0f, 2.25f}, {-2.7f, 0.0f, 2.025f}, {-2.7f, -0.3f, 2.025f},
- {-3.0f, -0.3f, 2.25f}, {-3.0f, 0.0f, 2.25f}, {-2.7f, 0.0f, 1.8f},
- {-2.7f, -0.3f, 1.8f}, {-3.0f, -0.3f, 1.8f},{-3.0f, 0.0f, 1.8f},
- {-2.7f, 0.0f, 1.575f}, {-2.7f, -0.3f, 1.575f}, {-3.0f, -0.3f, 1.35f},
- {-3.0f, 0.0f, 1.35f}, {-2.5f, 0.0f, 1.125f}, {-2.5f, -0.3f, 1.125f},
- {-2.65f, -0.3f, 0.9375f}, {-2.65f, 0.0f, 0.9375f}, {-2.0f, -0.3f, 0.9f},
- {-1.9f, -0.3f, 0.6f}, {-1.9f, 0.0f, 0.6f}, {1.7f, 0.0f, 1.425f},
- {1.7f, -0.66f, 1.425f}, {1.7f, -0.66f, 0.6f}, {1.7f, 0.0f, 0.6f},
- {2.6f, 0.0f, 1.425f}, {2.6f, -0.66f, 1.425f}, {3.1f, -0.66f, 0.825f},
- {3.1f, 0.0f, 0.825f}, {2.3f, 0.0f, 2.1f}, {2.3f, -0.25f, 2.1f},
- {2.4f, -0.25f, 2.025f}, {2.4f, 0.0f, 2.025f}, {2.7f, 0.0f, 2.4f},
- {2.7f, -0.25f, 2.4f}, {3.3f, -0.25f, 2.4f}, {3.3f, 0.0f, 2.4f},
- {2.8f, 0.0f, 2.475f}, {2.8f, -0.25f, 2.475f}, {3.525f, -0.25f, 2.49375f},
- {3.525f, 0.0f, 2.49375f}, {2.9f, 0.0f, 2.475f}, {2.9f, -0.15f, 2.475f},
- {3.45f, -0.15f, 2.5125f}, {3.45f, 0.0f, 2.5125f}, {2.8f, 0.0f, 2.4f},
- {2.8f, -0.15f, 2.4f}, {3.2f, -0.15f, 2.4f}, {3.2f, 0.0f, 2.4f},
- {0.0f, 0.0f, 3.15f}, {0.8f, 0.0f, 3.15f}, {0.8f, -0.45f, 3.15f},
- {0.45f, -0.8f, 3.15f}, {0.0f, -0.8f, 3.15f}, {0.0f, 0.0f, 2.85f},
- {1.4f, 0.0f, 2.4f}, {1.4f,-0.784f, 2.4f}, {0.784f, -1.4f, 2.4f},
- {0.0f, -1.4f, 2.4f}, {0.4f, 0.0f, 2.55f}, {0.4f, -0.224f, 2.55f},
- {0.224f, -0.4f, 2.55f}, {0.0f, -0.4f, 2.55f}, {1.3f, 0.0f, 2.55f},
- {1.3f, -0.728f, 2.55f}, {0.728f, -1.3f, 2.55f}, {0.0f, -1.3f, 2.55f},
- {1.3f, 0.0f, 2.4f}, {1.3f, -0.728f, 2.4f}, {0.728f, -1.3f, 2.4f},
- {0.0f, -1.3f, 2.4f}, {0.0f, 0.0f, 0.0f}, {1.425f, -0.798f, 0.0f},
- {1.5f, 0.0f, 0.075f}, {1.425f, 0.0f, 0.0f}, {0.798f, -1.425f, 0.0f},
- {0.0f, -1.5f, 0.075f}, {0.0f, -1.425f, 0.0f}, {1.5f, -0.84f, 0.075f},
- {0.84f, -1.5f, 0.075f}
- };
-
- static float tex[2][2][2] =
- {
- { {0, 0}, {1, 0}},
- { {0, 1}, {1, 1}}
- };
-
-
- // ---------------------------------------------------------------------------
- // Name: tpCycleRasterModes
- // Description: Replace the raster mode to the next raster mode.
- // ---------------------------------------------------------------------------
- void tpCycleRasterModes()
- {
- if (stat_rasterMode == GL_FILL)
- {
- stat_rasterMode = GL_LINE;
- }
- else
- {
- stat_rasterMode = GL_FILL;
- }
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpCycleBackgroundColor
- // Description: Replace the background color with the next background color
- // in the background colors cycle.
- // ---------------------------------------------------------------------------
- void tpCycleBackgroundColor()
- {
- if (stat_backgroundColorIndex == 0)
- {
- stat_backgroundColorIndex = 1;
- }
- else
- {
- stat_backgroundColorIndex = 0;
- }
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpIncreaseTextureInfluence
- // Description: Increases texture influence (over the shaded material color)
- // ---------------------------------------------------------------------------
- void tpIncreaseTextureInfluence()
- {
- if (stat_shadingProgramInUse)
- {
- if (stat_textureInfluenceAsInt < 10)
- {
- stat_textureInfluenceAsInt += 1;
- GLfloat textureInfluence = ((float)stat_textureInfluenceAsInt / 10.0f);
- glUniform1fARB(stat_textureInfluenceUniformLocation, textureInfluence);
- }
- }
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpDecreaseTextureInfluence
- // Description: Decreases texture influence (over the shaded material color)
- // ---------------------------------------------------------------------------
- void tpDecreaseTextureInfluence()
- {
- if (stat_shadingProgramInUse)
- {
- if (stat_textureInfluenceAsInt > 0)
- {
- stat_textureInfluenceAsInt -= 1;
- GLfloat textureInfluence = ((float)stat_textureInfluenceAsInt / 10.0f);
- glUniform1fARB(stat_textureInfluenceUniformLocation, textureInfluence);
- }
- }
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpGenerateOpenGLError
- // Description: Generates an OpenGL error
- // ---------------------------------------------------------------------------
- void tpGenerateOpenGLError()
- {
- // Send a debug string into the debugger:
- OutputDebugString(TP_OPEN_GL_ERROR_EXAMPLE_STR);
-
- // Generate an OpenGL error:
- //(Calling glEnable with NULL results with a GL_INVALID_ENUM error):
- glEnable(NULL);
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpGenerateDetectedError
- // Description: Generates a detected error.
- // ---------------------------------------------------------------------------
- void tpGenerateDetectedError()
- {
- if (glActiveTexture)
- {
- // Generate a detected error:
- // (Valid active textures are GL_TEXTURE0, GL_TEXTURE1, ...)
- glActiveTexture(GL_TEXTURE0 - 10);
- }
- }
-
- // ---------------------------------------------------------------------------
- // Name: tpCrashThisApplication
- // Description: Crashes this application.
- // ---------------------------------------------------------------------------
- void tpCrashThisApplication()
- {
- // Send a debug string into the debugger:
- OutputDebugString(TP_CRASH_EXAMPLE_STR);
-
- // Crash this application (by causing an access violation exception):
- int* i = NULL;
- *i = 3;
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpThrowBreakPointException
- // Description: Throws a breakpoint exception.
- // ---------------------------------------------------------------------------
- void tpThrowBreakPointException()
- {
- // Send a debug string into the debugger:
- OutputDebugString(TP_BREAK_POINT_EXAMPLE_STR);
-
- // Throw a breakpoint exception:
- DebugBreak();
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpChangeObjectShininess
- // Description:
- // Odd calls to this function makes the object shininess wrong.
- // Even calls to this function restores the object shininess.
- // ---------------------------------------------------------------------------
- void tpChangeObjectShininess()
- {
- static bool shouldChangeShininess = true;
- if (shouldChangeShininess)
- {
- stat_shininess = 0.1f;
- }
- else
- {
- stat_shininess = 20.0f;
- }
-
- shouldChangeShininess = !shouldChangeShininess;
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpOutputDebugStringExample
- // Description: Send a debug string to the debugger that debugs this application.
- // ---------------------------------------------------------------------------
- void tpOutputDebugStringExample()
- {
- OutputDebugString(TP_DEBUG_STRING_EXAMPLE_STR);
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpDisplayHelpMessage
- // Description: Displays the GRTeapotApplication help message in a message box.
- // Arguments: hWnd - The message parent window handle.
- // ---------------------------------------------------------------------------
- void tpDisplayHelpMessage(HWND hWnd)
- {
- MessageBox(hWnd, TP_HELP_MESSAGE_STR, TP_HELP_DIALOG_CAPTION_STR, MB_OK | MB_ICONINFORMATION);
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpMoveObjectOutOfView
- // Description:
- // Odd calls to this function makes the model view matrix render the
- // teapot out of the graphic view.
- // Even calls to this function restores the model view matrix.
- // ---------------------------------------------------------------------------
- void tpMoveObjectOutOfView()
- {
- static bool shouldChangeMatrix = true;
- if (shouldChangeMatrix)
- {
- stat_objectXTran = 99999.0;
- }
- else
- {
- stat_objectXTran = 0.0;
- }
-
- shouldChangeMatrix = !shouldChangeMatrix;
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpDrawTeaPot
- // Description: Draws a teapot.
- // Arguments: grid - The number of partitions in the grid.
- // scale - Scaling (size) of the teapot.
- // type - OpenGL draw style (GL_FILL / GL_LINE / etc).
- // ---------------------------------------------------------------------------
- void tpDrawTeaPot(GLint grid, GLfloat scale, GLenum type)
- {
- float p[4][4][3], q[4][4][3], r[4][4][3], s[4][4][3];
- long i, j, k, l;
-
- // Add a string marker:
- if (glStringMarkerGREMEDY != NULL)
- {
- char buff[512];
- sprintf(buff, TP_DRAWING_TEAPOT_MARKER_STR, grid, scale);
- glStringMarkerGREMEDY(0, buff);
- }
-
- glPushAttrib(GL_ENABLE_BIT | GL_EVAL_BIT);
-
- // Enable automatic normals calculations:
- glEnable(GL_AUTO_NORMAL);
- glEnable(GL_NORMALIZE);
-
-
- // Use a two-dimensional evaluator to generate the teapot vertices, normals
- // and texture coordinates:
- glEnable(GL_MAP2_VERTEX_3);
- glEnable(GL_MAP2_TEXTURE_COORD_2);
- glPushMatrix();
- glRotatef(270.0, 1.0, 0.0, 0.0);
- glScalef(0.5f * scale, 0.5f * scale, 0.5f * scale);
- glTranslatef(0.0, 0.0, -1.5);
- for (i = 0; i < 10; i++)
- {
- for (j = 0; j < 4; j++)
- {
- for (k = 0; k < 4; k++)
- {
- for (l = 0; l < 3; l++)
- {
- p[j][k][l] = stat_teaPotCPData[stat_teaPotPatchData[i][j * 4 + k]][l];
- q[j][k][l] = stat_teaPotCPData[stat_teaPotPatchData[i][j * 4 + (3 - k)]][l];
-
- if (l == 1)
- {
- q[j][k][l] *= -1.0;
- }
-
- if (i < 6)
- {
- r[j][k][l] = stat_teaPotCPData[stat_teaPotPatchData[i][j * 4 + (3 - k)]][l];
-
- if (l == 0)
- {
- r[j][k][l] *= -1.0;
- }
-
- s[j][k][l] = stat_teaPotCPData[stat_teaPotPatchData[i][j * 4 + k]][l];
-
- if (l == 0)
- {
- s[j][k][l] *= -1.0;
- }
-
- if (l == 1)
- {
- s[j][k][l] *= -1.0;
- }
- }
- }
- }
- }
-
- glMap2f(GL_MAP2_TEXTURE_COORD_2, 0, 1, 2, 2, 0, 1, 4, 2, &tex[0][0][0]);
-
- glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, &p[0][0][0]);
- glMapGrid2f(grid, 0.0, 1.0, grid, 0.0, 1.0);
- glEvalMesh2(type, 0, grid, 0, grid);
- glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, &q[0][0][0]);
- glEvalMesh2(type, 0, grid, 0, grid);
-
- if (i < 6)
- {
- glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, &r[0][0][0]);
- glEvalMesh2(type, 0, grid, 0, grid);
- glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, &s[0][0][0]);
- glEvalMesh2(type, 0, grid, 0, grid);
- }
- }
-
- glPopMatrix();
- glPopAttrib();
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpSetMaterial
- // Description: Sets the current OpenGL material
- // ---------------------------------------------------------------------------
- void tpSetMaterial()
- {
- // Add a string marker:
- if (glStringMarkerGREMEDY != NULL)
- {
- glStringMarkerGREMEDY(0, TP_SETTING_UP_MATERIAL_MARKER_STR);
- }
-
- glShadeModel(GL_SMOOTH);
-
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, stat_ambient);
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, stat_diffuse);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, stat_specular);
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, stat_shininess);
-
- // Set the polygon raster mode:
- glPolygonMode(GL_FRONT_AND_BACK, stat_rasterMode);
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpSetupLights
- // Description: Setups a single OpenGL directional white light.
- // ---------------------------------------------------------------------------
- void tpSetupLights()
- {
- // Add a string marker:
- if (glStringMarkerGREMEDY != NULL)
- {
- glStringMarkerGREMEDY(0, TP_SETTING_UP_LIGHTS_MARKER_STR);
- }
-
- GLfloat ambient[] = {0.2f, 0.2f, 0.2f, 1.0f};
- GLfloat position[] = {0.0f, 0.0f, 1.0f, 1.0f};
-
- glEnable(GL_LIGHTING);
- glEnable(GL_LIGHT0);
-
- glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
- glLightfv(GL_LIGHT0, GL_POSITION, position);
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpCreateFontDisplayLists
- // Description:
- // Creates TP_SYSTEM_FONT_SIZE display lists, each containing a bitmap that
- // represents a glyph of the system font.
- // ---------------------------------------------------------------------------
- void tpCreateFontDisplayLists()
- {
- // Make the system font the device context's selected font:
- SelectObject(stat_hWindowDC, GetStockObject(SYSTEM_FONT));
-
- // Create TP_SYSTEM_FONT_SIZE display lists:
- stat_systemFontFirstDisplayList = glGenLists(256);
-
- // Fill the display lists with bitmaps that will represent the system font
- // glyphs 0 .. TP_SYSTEM_FONT_SIZE - 1:
- wglUseFontBitmaps(stat_hWindowDC, 0, (TP_SYSTEM_FONT_SIZE - 1), stat_systemFontFirstDisplayList);
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpConvertBitmapFromBGRAToRGBA
- // Description:
- // Converts a BGRA image to an RGBA image.
- // We currently support only 32 bit pixels images.
- // ---------------------------------------------------------------------------
- bool tpConvertBitmapFromBGRAToRGBA(FIBITMAP* pFreeImageBitmap)
- {
- bool retVal = false;
-
- // Sanity check:
- if (pFreeImageBitmap)
- {
- // We currently support only 32 bit pixels images:
- int bitsPerPixel = FreeImage_GetBPP(pFreeImageBitmap);
- if (bitsPerPixel == 32)
- {
- retVal = true;
-
- // Get the image attributes:
- int imageHeight = FreeImage_GetHeight(pFreeImageBitmap);
- int imageWidth = FreeImage_GetWidth(pFreeImageBitmap);
- int bytesPerPixel = bitsPerPixel / 8;
-
- // Iterate the image lines:
- for(int y=0; y<imageHeight; y++)
- {
- // Iterate the current line pixels:
- BYTE* pLineData = FreeImage_GetScanLine(pFreeImageBitmap, y);
- for(int x = 0; x < imageWidth; x++)
- {
- // Replace the Red and blue pixels:
- BYTE redValue = pLineData[2];
- pLineData[2] = pLineData[0];
- pLineData[0] = redValue;
-
- // pLineData[3] = 125;
-
- // jump to next pixel
- pLineData += bytesPerPixel;
- }
- }
- }
- }
-
- return retVal;
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpCreateAndLoadTexture
- // Description: Creates a texture object and loads the image into it.
- // ---------------------------------------------------------------------------
- void tpCreateAndLoadTexture()
- {
- // Load the texture image from a file into a free image bitmap:
- FIBITMAP* pFreeImageBitmap = pFreeImageBitmap = FreeImage_Load(FIF_PNG, TP_TEXTURE_FILE_PATH, PNG_DEFAULT);
- if (pFreeImageBitmap)
- {
- // Convert the image into 32 bit image:
- FIBITMAP* pFreeImage32BitsBitmap = FreeImage_ConvertTo32Bits(pFreeImageBitmap);
- FreeImage_Unload(pFreeImageBitmap);
- pFreeImageBitmap = NULL;
-
- // Flip it horizontally:
- FreeImage_FlipHorizontal(pFreeImage32BitsBitmap);
-
- // On Win32 - we need to convert from BGRA to RGBA pixels:
- #if OS_BUILD_TARGET == OS_WIN32
- tpConvertBitmapFromBGRAToRGBA(pFreeImage32BitsBitmap);
- #endif
-
- // Get the image attributes:
- int width = FreeImage_GetWidth(pFreeImage32BitsBitmap);
- int height = FreeImage_GetHeight(pFreeImage32BitsBitmap);
- int scan_width = FreeImage_GetPitch(pFreeImage32BitsBitmap);
-
- // Allocate a memory buffer that will hold the pixels as OpenGL expects them to be:
- BYTE* pImageBuffer = (BYTE*)malloc(height * scan_width);
-
- // Convert the free image bitmap to "OpenGL pixels":
- FreeImage_ConvertToRawBits(pImageBuffer, pFreeImage32BitsBitmap, scan_width, 32,
- FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, FALSE);
- FreeImage_Unload(pFreeImage32BitsBitmap);
- pFreeImage32BitsBitmap = NULL;
-
- // Create a texture object and make it the bound texture:
- glGenTextures(1, &stat_textureObjName);
- glBindTexture(GL_TEXTURE_2D, stat_textureObjName);
-
- // Load the image into it:
- glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pImageBuffer);
-
- // Delete the raw memory buffer:
- free(pImageBuffer);
-
- // Set the texture parameters:
- 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_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- }
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpReadStringFromFile
- // Description: Reads a string from a file into a buffer.
- // Arguments:
- // filePath - The input file path.
- // bufferLength - The buffer length.
- // pBuffer - The buffer that will receive the string.
- // Return Val: bool - Success / failure.
- // ---------------------------------------------------------------------------
- bool tpReadStringFromFile(const char* filePath, int bufferLength, char* pBuffer)
- {
- bool retVal = false;
-
- // Sanity check:
- if (bufferLength > 0)
- {
- // Open the text input file for reading:
- FILE* fileHandle = fopen(filePath,"rt");
- if (fileHandle != NULL)
- {
- // Read the file content into the buffer:
- int amountOfCharsRead = fread(pBuffer, sizeof(char), bufferLength - 1, fileHandle);
-
- // NULL terminate the read string:
- pBuffer[amountOfCharsRead] = '\0';
-
- // Close the file:
- fclose(fileHandle);
-
- retVal = true;
- }
- }
-
- return retVal;
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpIsExtensionSupported
- // Description: Inputs an extension name and returns true iff the extension is
- // supported in the render context that is the current context of
- // the calling thread.
- // ---------------------------------------------------------------------------
- bool tpIsExtensionSupported(char* extensionName, const char* extensionsString)
- {
- bool retVal = false;
-
- // Search for extensionName in the extensions string. Use of strstr()
- // is not sufficient because extension names can be prefixes of
- // other extension names. Could use strtok() but the constant
- // string returned by glGetString can be in read-only memory.
- char* pCurrentPos = (char*)extensionsString;
- char* pEndPos;
- int extensionNameLen = strlen(extensionName);
- pEndPos = pCurrentPos + strlen(pCurrentPos);
-
- while (pCurrentPos < pEndPos)
- {
- int n = strcspn(pCurrentPos, " ");
- if ((extensionNameLen == n) && (strncmp(extensionName, pCurrentPos, n) == 0))
- {
- retVal = true;
- break;
- }
-
- pCurrentPos += (n + 1);
- }
-
- return retVal;
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpInitializeExtensions
- // Description: Initialized pointers to OpenGL extension functions that will
- // be used.
- // ---------------------------------------------------------------------------
- void tpInitializeExtensions()
- {
- // Get the extensions string of the this thread current render context:
- const char* extensionsString = (const char*)glGetString(GL_EXTENSIONS);
-
- // If the string marker extension is supported:
- if (tpIsExtensionSupported("GL_GREMEDY_string_marker", extensionsString))
- {
- // Get a pointer to the glStringMarkerGREMEDY function:
- glStringMarkerGREMEDY = (PFNGLSTRINGMARKERGREMEDYPROC)wglGetProcAddress("glStringMarkerGREMEDY");
- }
-
- // If GL_ARB_shader_objects is supported:
- if (tpIsExtensionSupported("GL_ARB_shader_objects", extensionsString))
- {
- glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)wglGetProcAddress("glCreateShaderObjectARB");
- glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)wglGetProcAddress("glShaderSourceARB");
- glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)wglGetProcAddress("glCompileShaderARB");
- glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)wglGetProcAddress("glGetObjectParameterivARB");
- glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)wglGetProcAddress("glCreateProgramObjectARB");
- glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)wglGetProcAddress("glAttachObjectARB");
- glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)wglGetProcAddress("glLinkProgramARB");
- glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)wglGetProcAddress("glUseProgramObjectARB");
- glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)wglGetProcAddress("glGetInfoLogARB");
- glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC)wglGetProcAddress("glGetUniformLocationARB");
- glUniform1fARB = (PFNGLUNIFORM1FARBPROC)wglGetProcAddress("glUniform1fARB");
- glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC)wglGetProcAddress("glDeleteObjectARB");
- glDetachObjectARB = (PFNGLDETACHOBJECTARBPROC)wglGetProcAddress("glDetachObjectARB");
-
- // We consider the extension as supported only when we managed to get all its
- // function pointers:
- stat_isGL_ARB_shader_objectsSupported =
- ((glCreateShaderObjectARB != NULL) && (glShaderSourceARB != NULL) &&
- (glCompileShaderARB != NULL) && (glGetObjectParameterivARB != NULL) &&
- (glCreateProgramObjectARB != NULL) && (glAttachObjectARB != NULL) &&
- (glLinkProgramARB != NULL) && (glUseProgramObjectARB != NULL) &&
- (glGetInfoLogARB != NULL) && (glGetUniformLocationARB != NULL) &&
- (glUniform1fARB != NULL) && (glDeleteObjectARB != NULL) &&
- (glDetachObjectARB != NULL));
- }
-
- // Get OpenGL 1.3 function pointers:
- glActiveTexture = (PFNGLACTIVETEXTUREPROC)wglGetProcAddress("glActiveTexture");
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpSetShadersSourceCodes
- // Description: Sets the fragment and vertex shaders source codes.
- // Return Val: bool - Success / failure.
- // ---------------------------------------------------------------------------
- bool tpSetShadersSourceCodes(GLhandleARB vertexShaderName, GLhandleARB fragmentShaderName)
- {
- bool retVal = false;
-
- // Allocate space for the shaders source codes:
- int sourceCodeBuffLength = 16384;
- char* vertexShaderCode = new char[sourceCodeBuffLength];
- char* fragmentShaderCode = new char[sourceCodeBuffLength];
- if ((vertexShaderCode != NULL) && (fragmentShaderCode != NULL))
- {
- // Read the shaders source codes:
- bool vsSourceRead = tpReadStringFromFile(TP_VETEX_SHADER_CODE_FILE_PATH, sourceCodeBuffLength, vertexShaderCode);
- bool fsSourceRead = tpReadStringFromFile(TP_FRAGMENT_SHADER_CODE_FILE_PATH, sourceCodeBuffLength, fragmentShaderCode);
-
- if (vsSourceRead && fsSourceRead)
- {
- // Load the source code into the OpenGL shaders:
- glShaderSourceARB(stat_vertexShaderName, 1, (const char**)(&vertexShaderCode), NULL);
- glShaderSourceARB(stat_fragmentShaderName, 1, (const char**)(&fragmentShaderCode), NULL);
-
- retVal = true;
- }
-
- // Clean up:
- delete[] vertexShaderCode;
- delete[] fragmentShaderCode;
- }
-
- return retVal;
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpCreateProgramsAndShaders
- // Description: Creates the required shading programs and shaders.
- // ---------------------------------------------------------------------------
- bool tpCreateProgramsAndShaders()
- {
- bool retVal = false;
-
- // If the GL_ARB_shader_objects extension is supported:
- if (stat_isGL_ARB_shader_objectsSupported)
- {
- // Add a string marker:
- if (glStringMarkerGREMEDY != NULL)
- {
- glStringMarkerGREMEDY(0, TO_CREATION_GLSL_OBJECTS_MARKER_STR);
- }
-
- // Create the vertex and fragment shaders:
- stat_vertexShaderName = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
- stat_fragmentShaderName = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
-
- // Set their source code:
- bool rc = tpSetShadersSourceCodes(stat_vertexShaderName, stat_fragmentShaderName);
-
- if (rc)
- {
- // Compile the shaders:
- glCompileShaderARB(stat_vertexShaderName);
- glCompileShaderARB(stat_fragmentShaderName);
-
- // Verify successful compilation:
- GLint wasVSCompilationSuccessful = false;
- GLint wasFSCompilationSuccessful = false;
- glGetObjectParameterivARB(stat_vertexShaderName, GL_OBJECT_COMPILE_STATUS_ARB, &wasVSCompilationSuccessful);
- glGetObjectParameterivARB(stat_fragmentShaderName, GL_OBJECT_COMPILE_STATUS_ARB, &wasFSCompilationSuccessful);
-
- if ((wasVSCompilationSuccessful == 1) && (wasFSCompilationSuccessful == 1))
- {
- // Create the program object:
- stat_shadingProgramName = glCreateProgramObjectARB();
-
- // Attach the shaders to the program:
- glAttachObjectARB(stat_shadingProgramName, stat_vertexShaderName);
- glAttachObjectARB(stat_shadingProgramName, stat_fragmentShaderName);
-
- // Link the program:
- glLinkProgramARB(stat_shadingProgramName);
-
- // Verify that the link succeeded:
- GLint wasLinkSuccesful = 0;
- glGetObjectParameterivARB(stat_shadingProgramName, GL_OBJECT_LINK_STATUS_ARB, &wasLinkSuccesful);
- if (wasLinkSuccesful == 1)
- {
- // Get the textureInfluence uniform location:
- stat_textureInfluenceUniformLocation = glGetUniformLocationARB(stat_shadingProgramName, "textureInfluence");
- if (stat_textureInfluenceUniformLocation != -1)
- {
- retVal = true;
- }
- }
- }
- }
- }
-
- return retVal;
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpUseShadingProgram
- // Description: Use / don't use the shading program (if exists).
- // ---------------------------------------------------------------------------
- void tpUseShadingProgram(bool isShadingProgramUsed)
- {
- // If the shading program does not exist:
- if (!stat_shadingProgramExists)
- {
- stat_shadingProgramInUse = false;
- }
- else
- {
- if (isShadingProgramUsed)
- {
- // Use the shading program (install it into the pipeline):
- glUseProgramObjectARB(stat_shadingProgramName);
-
- // Set the textureInfluence uniform value:
- GLfloat textureInfluence = ((float)stat_textureInfluenceAsInt / 10.0f);
- glUniform1fARB(stat_textureInfluenceUniformLocation, textureInfluence);
- }
- else
- {
- // Un-install the program (use the fixed OpenGL pipeline):
- glUseProgramObjectARB(0);
- }
-
- // Log the use of the shading program:
- stat_shadingProgramInUse = isShadingProgramUsed;
- }
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpPerformGeneralOpenGLInitializations
- // Description: Performs general initializations.
- // ---------------------------------------------------------------------------
- void tpPerformGeneralOpenGLInitializations()
- {
- // Initialize the OpenGL extensions that will be used:
- tpInitializeExtensions();
-
- // Add a string marker:
- if (glStringMarkerGREMEDY != NULL)
- {
- glStringMarkerGREMEDY(0, TP_GENERAL_INIT_MARKER_STR);
- }
-
- // Set the projection transformation:
- glMatrixMode(GL_PROJECTION);
- glFrustum(-0.5F, 0.5F, -0.5F, 0.5F, 1.0F, 3.0F);
-
- // Set the viewing transformation:
- glMatrixMode(GL_MODELVIEW);
- glTranslatef(0.0F, 0.0F, -2.0F);
-
- // Enable depth test:
- glEnable(GL_DEPTH_TEST);
-
- // Create a display list that will contains the tea pot geometry:
- stat_teaPotDisplayListIndex = glGenLists(1);
-
- // Fill the display list with a solid (raster filled) tea pot:
- glNewList(stat_teaPotDisplayListIndex, GL_COMPILE);
- tpDrawTeaPot(7, 0.5, GL_FILL);
- glEndList();
-
- // Create display lists that represent the system font:
- tpCreateFontDisplayLists();
-
- // Generate the used texture:
- tpCreateAndLoadTexture();
-
- // Create the shading programs and shaders:
- stat_shadingProgramExists = tpCreateProgramsAndShaders();
-
- // If the shading program was created successfully:
- if (stat_shadingProgramExists)
- {
- // Use the shading program (install it into the pipeline):
- tpUseShadingProgram(true);
- }
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpPerformGeneralOpenCleanups
- // Description: Performs general OpenGL cleanups (delete allocated objects, etc).
- // ---------------------------------------------------------------------------
- void tpPerformGeneralOpenCleanups()
- {
- // Delete the display list that contains the tea pot geometry:
- if (stat_teaPotDisplayListIndex != 0)
- {
- glDeleteLists(stat_teaPotDisplayListIndex, 1);
- }
-
- // Delete the display lists that contains the system font glyphs:
- if (stat_systemFontFirstDisplayList)
- {
- glDeleteLists(stat_systemFontFirstDisplayList, TP_SYSTEM_FONT_SIZE);
- }
-
- // Delete the teapot texture:
- if (stat_textureObjName != 0)
- {
- glDeleteTextures(1, &stat_textureObjName);
- }
-
- if (stat_shadingProgramExists && stat_isGL_ARB_shader_objectsSupported)
- {
- // Remove the used program (if any):
- glUseProgramObjectARB(0);
-
- // Detach shaders from the shading program:
- glDetachObjectARB(stat_shadingProgramName, stat_vertexShaderName);
- glDetachObjectARB(stat_shadingProgramName, stat_fragmentShaderName);
-
- // Delete shaders:
- glDeleteObjectARB(stat_vertexShaderName);
- glDeleteObjectARB(stat_fragmentShaderName);
-
- // Delete the shading program:
- glDeleteObjectARB(stat_shadingProgramName);
- }
-
- // Delete the OpenGL render context:
- wglMakeCurrent(NULL, NULL);
- wglDeleteContext(stat_hWindowGLRC);
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpOnWindowSizeChanged
- // Description: Is called when the window size is changed.
- // Adjusts the view port to the new window size.
- // Arguments:
- // width, height - The new window width and height.
- // ---------------------------------------------------------------------------
- void tpOnWindowSizeChanged(int width, int height)
- {
- // Save the new window size in the static global variables:
- stat_windowWidth = width;
- stat_windowHeight = height;
-
- // Make sure that the view port is always a rectangle:
- GLsizei minValue = stat_windowWidth;
- if (stat_windowHeight < stat_windowWidth)
- {
- minValue = minValue = stat_windowHeight;
- }
-
- // Set the view port:
- stat_viewPortX = 0;
- stat_viewPortY = 0;
- stat_viewWidth = minValue;
- stat_viewHeight = minValue;
- glViewport(stat_viewPortX, stat_viewPortY, stat_viewWidth, stat_viewHeight);
-
- // Calculate the heads up display raster position:
- int headsUpMessageLength = strlen(TP_HEADS_UP_DISPLAY_MESSAGE);
- float headsUpMessageWidth = float(stat_systemFontGlyphWidth * headsUpMessageLength);
- float leftWidth = stat_viewWidth - headsUpMessageWidth;
- if (leftWidth < 0)
- {
- leftWidth = 0;
- }
- stat_headsUpRasterPosX = ((leftWidth / 2.0f) / stat_viewWidth);
- stat_headsUpRasterPosY = 0.05f;
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpClearGraphicBuffers
- // Description: Clears the color and depth buffers
- // ---------------------------------------------------------------------------
- void tpClearGraphicBuffers()
- {
- // Set the background color;
- if (stat_backgroundColorIndex == 0)
- {
- glClearColor(1,1,1,1);
- }
- else
- {
- glClearColor(0,0,0,1);
- }
-
- // Clear the background (using the above color):
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpDrawScene
- // Description: Draws the graphic scene.
- // ---------------------------------------------------------------------------
- void tpDrawScene()
- {
- // Set the current material:
- tpSetMaterial();
-
- // Set the current lights:
- tpSetupLights();
-
- // Add a string marker:
- if (glStringMarkerGREMEDY != NULL)
- {
- glStringMarkerGREMEDY(0, TP_DRAWING_SCENE_MARKER_STR);
- }
-
- // Set the used texture:
- glBindTexture(GL_TEXTURE_2D, stat_textureObjName);
-
- // Set textures environment parameters:
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
-
- // Enable 2D textures:
- glEnable(GL_TEXTURE_2D);
-
- // Place the object to be drawn (model transformation):
- glPushMatrix();
- glTranslatef(stat_objectXTran, stat_objectYTran, stat_objectZTran);
- glRotatef(stat_objectXRot, 1.0F, 0.0F, 0.0F);
- glRotatef(stat_objectYRot, 0.0F, 1.0F, 0.0F);
- glRotatef(stat_objectZRot, 0.0F, 0.0F, 1.0F);
-
- // Draw the object:
- glCallList(stat_teaPotDisplayListIndex);
-
- // Clean up - remove the model transformation and disable 2D texturing:
- glPopMatrix();
- glDisable(GL_TEXTURE_2D);
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpSetupOpenGLForHeadsUpDraw
- // Description: Setup OpenGL states for heads up 2D drawing
- // ---------------------------------------------------------------------------
- void tpSetupOpenGLForHeadsUpDraw()
- {
- // Setup a simple projection matrix:
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- glOrtho(0.0f, 1.0f, 0.0f, 1.0f, -1.0, 1.0);
-
- // Setup identity model view matrix:
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
-
- // Disable the "Z" buffer test (gain an "always on top" effect):
- glDisable(GL_DEPTH_TEST);
-
- // Disable the use of the shading program:
- if (stat_shadingProgramExists && stat_shadingProgramInUse)
- {
- glUseProgramObjectARB(0);
- }
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpRestoreOpenGLFromHeadsUpDraw
- // Description:
- // Restores OpenGL states to the state they were before the heads up 2D drawing
- // ---------------------------------------------------------------------------
- void tpRestoreOpenGLFromHeadsUpDraw()
- {
- // Restore OpenGL states:
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
-
- // Restore the "Z" buffer test:
- glEnable(GL_DEPTH_TEST);
-
- // Restore the used of shading program:
- if (stat_shadingProgramExists && stat_shadingProgramInUse)
- {
- glUseProgramObjectARB(stat_shadingProgramName);
- }
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpDrawHeadsUpMessage
- // Description: Draw an heads up message on the screen.
- // ---------------------------------------------------------------------------
- void tpDrawHeadsUpMessage()
- {
- // Setup OpenGL for heads up 2D drawing:
- tpSetupOpenGLForHeadsUpDraw();
-
- // Set current color to yellow:
- GLfloat stat_HeadsUpTextAmbient[4] = {1.0f, 1.0f, 0.0f ,1.0f };
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, stat_HeadsUpTextAmbient);
-
- // Set the raster position:
- glRasterPos2f(stat_headsUpRasterPosX, stat_headsUpRasterPosY);
-
- // Set the display lists base to the first system font display list:
- glListBase(stat_systemFontFirstDisplayList);
-
- // Draw the text message:
- glCallLists(16, GL_UNSIGNED_BYTE, TP_HEADS_UP_DISPLAY_MESSAGE);
-
- // Restore OpenGL states:
- tpRestoreOpenGLFromHeadsUpDraw();
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpSwapBuffers
- // Description: Swaps the back and the front buffer.
- // ---------------------------------------------------------------------------
- void tpSwapBuffers()
- {
- SwapBuffers(stat_hWindowDC);
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpPaintWindow
- // Description: Paint the graphic window (redraw it).
- // ---------------------------------------------------------------------------
- void tpPaintWindow()
- {
- // Clear the graphic buffers:
- tpClearGraphicBuffers();
-
- // Draw the scene into the back buffer:
- tpDrawScene();
-
- // Draw the heads up message:
- tpDrawHeadsUpMessage();
-
- // Swap the back and the front buffer:
- tpSwapBuffers();
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpSetupPixelFormat
- // Description: Sets up a given device context pixel format to be a double
- // buffer RGBA pixel format.
- // Arguments: hWindowDC - The input device context handle.
- // ---------------------------------------------------------------------------
- void tpSetupPixelFormat(HDC hWindowDC)
- {
- // Get the device context window:
- HWND hWindow = WindowFromDC(hWindowDC);
-
- // Define the requested pixel format descriptor:
- PIXELFORMATDESCRIPTOR pfd =
- {
- sizeof(PIXELFORMATDESCRIPTOR), // This struct size.
- 1, // Struct version.
- PFD_SUPPORT_OPENGL | // OpenGL Double buffer support.
- PFD_DRAW_TO_WINDOW |
- PFD_DOUBLEBUFFER,
- PFD_TYPE_RGBA, // RGBA pixel format.
- 16, // Requested color depth.
- 0, 0, 0, 0, 0, 0, // Color bits (ignored).
- 0, // No alpha buffer.
- 0, // Alpha bits (ignored).
- 0, // No accumulation buffer.
- 0, 0, 0, 0, // Accumulation buffer bits (ignored).
- 16, // Depth buffer bits.
- 0, // No stencil buffer.
- 0, // No auxiliary buffers.
- PFD_MAIN_PLANE, // Main layer (ignored).
- 0, // Number of overlay and underlay planes.
- 0, // No Layer mask.
- 0, // No visibility mask.
- 0 // No damage masks.
- };
-
- // Choose the pixel format that best match the above requested pixel format:
- int pixelFormat = ChoosePixelFormat(hWindowDC, &pfd);
-
- // If we failed to find a matching pixel format:
- if (pixelFormat == 0)
- {
- // Display an error message and exit the application:
- MessageBox(hWindow, TP_CHOOSE_PIXEL_FORMAT_ERR_SRT, TP_ERROR_SRT, MB_ICONERROR | MB_OK);
- exit(1);
- }
-
- // Set the chosen pixel format to be the active pixel format:
- BOOL rc = SetPixelFormat(hWindowDC, pixelFormat, &pfd);
-
- // If we failed to set the active pixel format:
- if (rc != TRUE)
- {
- // Display an error message and exit the application:
- MessageBox(hWindow, TP_SET_PIXEL_FORMAT_ERR_SRT, TP_ERROR_SRT, MB_ICONERROR | MB_OK);
- exit(1);
- }
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpCreateOpenGLRenderContext
- // Description:
- // Inputs a device context and creates an OpenGL render context that can
- // draw into it.
- //
- // Arguments:
- // hDeviceContext - The input device context handle.
- //
- // Return Val:
- // HGLRC - A handle to the created OpenGL render context.
- // ---------------------------------------------------------------------------
- HGLRC tpCreateOpenGLRenderContext(HDC hDeviceContext)
- {
- // Create an OpenGL render context for the application window device context:
- HGLRC retVal = wglCreateContext(stat_hWindowDC);
-
- if (retVal == NULL)
- {
- // Display an error message and exit the application:
- HWND hWindow = WindowFromDC(hDeviceContext);
- MessageBox(hWindow, TP_CREATE_RENDER_CONTEXT_ERR_SRT, TP_ERROR_SRT, MB_ICONERROR | MB_OK);
- exit(1);
- }
-
- // Make it the current render context:
- wglMakeCurrent(stat_hWindowDC, retVal);
-
- return retVal;
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpTimerProc
- // Description: Is called by the timer on each timer interval end.
- // Arguments: hwnd - The window associated with the timer.
- // uMsg - WM_TIMER message.
- // idEvent - The timer id.
- // dwTime - The number of milliseconds that have elapsed since the system was started
- // ---------------------------------------------------------------------------
- void tpTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
- {
- // If we are not in viewing mode:
- if (!stat_isInViewingMode)
- {
- // Calculate the rotation that needs to be performed on the displayed object:
- stat_objectXRot += 360.0F * stat_mouseDeltaY / stat_windowHeight;
- stat_objectYRot += 360.0F * stat_mouseDeltaX / stat_windowWidth;
-
- // Repaint the window:
- tpPaintWindow();
- }
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpOnKeyPressed
- // Description: Is called when the user press a keyboard key.
- // Arguments: hWindow - The window in which the key was pressed.
- // pressedKey - The pressed key.
- // shouldCallDefaultWinProc - Will get true iff the default win procedure
- // should be called after the call to this function.
- // Return Val: LRESULT - The result of the message processing.
- // ---------------------------------------------------------------------------
- LRESULT tpOnKeyPressed(HWND hWindow, int pressedKey, bool& shouldCallDefaultWinProc)
- {
- // Will get the return value of this function:
- LRESULT retVal = 0;
-
- // Unless specified otherwise - pass the key press handling also to the windows
- // default procedure:
- shouldCallDefaultWinProc = true;
-
- switch (pressedKey)
- {
- case VK_ESCAPE:
- {
- // Destroy the window:
- // (If this is the main window - the application will exit)
- DestroyWindow(hWindow);
-
- // Do not call the windows default procedure:
- shouldCallDefaultWinProc = false;
- }
- break;
-
- case 'b':
- {
- // Set the next background color to be the active one:
- tpCycleBackgroundColor();
- }
- break;
-
- case 'c':
- {
- // Crash the application:
- tpCrashThisApplication();
- }
- break;
-
- case 'd':
- {
- // Output a debug string to the debugged that debugs this
- // program:
- tpOutputDebugStringExample();
- }
- break;
-
- case 'e':
- {
- // Generate an OpenGL error:
- tpGenerateOpenGLError();
- }
- break;
-
- case 't':
- {
- // Generate a detected error:
- tpGenerateDetectedError();
- }
- break;
-
- case 'h':
- {
- // Display the help message in a dialog:
- tpDisplayHelpMessage(hWindow);
- }
- break;
-
- case 'm':
- {
- // Make the teapot disappear from the screen:
- tpMoveObjectOutOfView();
- }
- break;
-
- case 'o':
- {
- // Change the object shininess:
- tpChangeObjectShininess();
- }
- break;
-
- case 'p':
- {
- // Generate a breakpoint exception:
- tpThrowBreakPointException();
- }
- break;
-
- case 's':
- {
- if (stat_shadingProgramExists)
- {
- // Toggle shading program use on / off:
- if (!stat_shadingProgramInUse)
- {
- tpUseShadingProgram(true);
- }
- else
- {
- tpUseShadingProgram(false);
- }
- }
- }
- break;
-
- case 'w':
- {
- // Set the next drawn object to be the active one:
- tpCycleRasterModes();
- }
- break;
-
- case '+':
- {
- // Increase texture influence:
- tpIncreaseTextureInfluence();
- }
- break;
-
- case '-':
- {
- // Decrease texture influence:
- tpDecreaseTextureInfluence();
- }
- break;
- }
-
- return retVal;
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpWindowsMessagesHandlingProcedure
- // Description:
- // Receives and handles the application windows messages.
- //
- // Arguments:
- // hWnd - A handle to the window to which the message was sent.
- // message - The id of the sent message.
- // wParam, lParam - Message parameters (depends on the message sent).
- //
- // Return Val:
- // The result of the message processing (depends on the message sent).
- // ---------------------------------------------------------------------------
- LRESULT APIENTRY tpWindowsMessagesHandlingProcedure(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- // Will get the return value of this function:
- LRESULT retVal = 0;
-
- // Contains true iff we should call the default window procedure for the input message:
- bool shouldCallDefaultWinProc = false;
-
- switch (message)
- {
- case WM_CREATE: // Window is created:
- {
- // Create a timer that will call tpTimerProc every TP_TIMER_INTERVAL ms:
- stat_timerId = ::SetTimer(NULL, 1, TP_TIMER_INTERVAL, (TIMERPROC)tpTimerProc);
- }
- break;
-
- case WM_DESTROY: // Window is destroyed:
- {
- // Delete the timer:
- ::KillTimer(NULL, stat_timerId);
-
- // Notity the system that this thread is about to terminate:
- PostQuitMessage(0);
- }
- break;
-
- case WM_SIZE: // Window size is changed:
- {
- // Do we have a render context?
- if (stat_hWindowGLRC != NULL)
- {
- // Get the window new size:
- int windowWidth = (int) LOWORD(lParam);
- int windowHeight = (int) HIWORD(lParam);
-
- // Adjust the view port to the new window size:
- tpOnWindowSizeChanged(windowWidth, windowHeight);
- }
- else
- {
- // We don't have a render context - use the default behavior:
- shouldCallDefaultWinProc = true;
- }
- }
- break;
-
- case WM_PAINT: // Window needs to be repainted:
- {
- // Prepare the window for painting:
- PAINTSTRUCT ps;
- BeginPaint(hWnd, &ps);
-
- // Sanity test - do we have a render context?
- if (stat_hWindowGLRC != NULL)
- {
- // Repaint the window:
- tpPaintWindow();
- }
-
- // Window painting was ended:
- EndPaint(hWnd, &ps);
- }
- break;
-
- case WM_CHAR: // Keyboard key was pressed:
- {
- // Get the pressed key (as a char)
- int pressedKey = wParam;
-
- // Handle the key event:
- retVal = tpOnKeyPressed(hWnd, pressedKey, shouldCallDefaultWinProc);
- }
- break;
-
- case WM_LBUTTONDOWN: // Mouse left button was pressed:
- {
- // If we are not in viewing mode (if the button was not already pressed):
- if (!stat_isInViewingMode)
- {
- // Capture mouse events while the mouse is over the input window:
- SetCapture(hWnd);
-
- // Get into viewing mode:
- stat_isInViewingMode = true;
-
- // Store the mouse initial position:
- stat_mouseInitialPosX = ((int) LOWORD(lParam) << 16) >> 16;
- stat_mouseInitialPosY = ((int) HIWORD(lParam) << 16) >> 16;
-
- // Initialize the mouse delta recording:
- stat_mouseDeltaX = 0;
- stat_mouseDeltaY = 0;
- }
-
- shouldCallDefaultWinProc = true;
- }
- break;
-
- case WM_RBUTTONDOWN: // Mouse right button was pressed:
- {
- shouldCallDefaultWinProc = true;
- }
- break;
-
- case WM_LBUTTONUP: // Mouse left button was released:
- {
- // If we are in viewing mode:
- if (stat_isInViewingMode)
- {
- // Release the mouse events capture:
- ReleaseCapture();
-
- // Exit viewing mode:
- stat_isInViewingMode = false;
- }
-
- shouldCallDefaultWinProc = true;
- }
- break;
-
- case WM_RBUTTONUP: // Mouse right button was released:
- {
- shouldCallDefaultWinProc = true;
- }
- break;
-
- case WM_MOUSEMOVE: // The mouse was moved:
- {
- // If we are in viewing mode:
- if (stat_isInViewingMode)
- {
- // Get the mouse current position (after the movement):
- GLint mouseCurrentPosX = ((int) LOWORD(lParam) << 16) >> 16;
- GLint mouseCurrentPosY = ((int) HIWORD(lParam) << 16) >> 16;
-
- // Calculate the delta in mouse position from the place where
- // it was observed last:
- stat_mouseDeltaY = mouseCurrentPosY - stat_mouseInitialPosY;
- stat_mouseDeltaX = mouseCurrentPosX - stat_mouseInitialPosX;
-
- // Calculate the rotation that needs to be performed on the
- // displayed object:
- stat_objectXRot += 360.0F * stat_mouseDeltaY / stat_windowHeight;
- stat_objectYRot += 360.0F * stat_mouseDeltaX / stat_windowWidth;
-
- // Update the mouse "last observed" position to contain the current position:
- stat_mouseInitialPosX = mouseCurrentPosX;
- stat_mouseInitialPosY = mouseCurrentPosY;
-
- // Repaint the window:
- tpPaintWindow();
- }
-
- shouldCallDefaultWinProc = true;
- }
- break;
-
- default:
- {
- shouldCallDefaultWinProc = true;
- }
- break;
- }
-
- if (shouldCallDefaultWinProc)
- {
- // Call the default window procedure:
- retVal = DefWindowProc(hWnd, message, wParam, lParam);
- }
-
- return retVal;
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpCreateApplicationWindow
- // Description: Creates the application window.
- // Arguments: hCurrentApplicationInst - The current application instance handle.
- // Return Val: HWND - The created window handle.
- // ---------------------------------------------------------------------------
- HWND tpCreateApplicationWindow(HINSTANCE hCurrentApplicationInst)
- {
- HWND retVal = NULL;
-
- HINSTANCE hInstance = GetModuleHandle(NULL);
-
- // Register the application window class:
- WNDCLASSEX wndClass;
-
- wndClass.cbSize = sizeof(WNDCLASSEX);
- wndClass.style = CS_HREDRAW | CS_VREDRAW;
- wndClass.lpfnWndProc = tpWindowsMessagesHandlingProcedure;
- wndClass.cbClsExtra = 0;
- wndClass.cbWndExtra = 0;
- wndClass.hInstance = hCurrentApplicationInst;
- wndClass.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_TP_APPLICATION_ICON_32);
- wndClass.hIconSm = LoadIcon(hInstance, (LPCTSTR)IDI_TP_APPLICATION_ICON);
- wndClass.hCursor = LoadCursor(NULL, IDC_HAND);
- wndClass.hbrBackground = NULL;
- wndClass.lpszMenuName = NULL;
- wndClass.lpszClassName = stat_windowClassName;
- RegisterClassEx(&wndClass);
-
- // Create the application window:
- retVal = CreateWindow(stat_windowClassName, stat_windowName, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
- stat_windowXPosition, stat_windowYPosition, stat_windowWidth, stat_windowHeight,
- NULL, NULL, hCurrentApplicationInst, NULL);
-
- if (retVal == NULL)
- {
- // Display an error message and exit the application:
- MessageBox(retVal, TP_CREATE_WINDOW_ERR_SRT, TP_ERROR_SRT, MB_ICONERROR | MB_OK);
- exit(1);
- }
-
- return retVal;
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: tpApplicationMessageLoop
- // Description:
- // Performs the application message loop - Wait for windows messages and
- // handles them.
- //
- // Return Val:
- // int - The last message parameter (usually the WM_QUIT message param.
- // ---------------------------------------------------------------------------
- int tpApplicationMessageLoop()
- {
- // An infinite loop that process windows messages:
- MSG msg;
- while (1)
- {
- // Wait for messages that are posted into this thread message queue:
- if (::GetMessage(&msg, NULL, 0, 0) == TRUE)
- {
- // Translate and dispatch the message into the window messages handling procedure
- // (tpWindowsMessagesHandlingProcedure):
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- else
- {
- // We got a WM_QUIT message. Exit the main loop:
- break;
- }
- }
-
- return msg.wParam;
- }
-
-
- // ---------------------------------------------------------------------------
- // Name: WinMain
- // Description:
- // The "main" function. Is considered by the OS as the program entry point.
- //
- // Arguments:
- // hCurrentInst - Handle to the current instance of the application.
- // hPreviousInst - Always NULL.
- // lpszCmdLine - The application command line arguments.
- // nCmdShow - Specifies how the window is to be shown.
- //
- // Return Val:
- // int - Application exit code.
- // ---------------------------------------------------------------------------
- int APIENTRY WinMain(HINSTANCE hCurrentInst, HINSTANCE hPreviousInst, LPSTR lpszCmdLine, int nCmdShow)
- {
- int retVal = 0;
-
- // Create the application window:
- HWND hWnd = tpCreateApplicationWindow(hCurrentInst);
-
- // Save the application window device context:
- stat_hWindowDC = GetDC(hWnd);
-
- // Show the application window:
- ShowWindow(hWnd, SW_SHOWNORMAL);
- UpdateWindow(hWnd);
-
- // Set the device context pixel format:
- tpSetupPixelFormat(stat_hWindowDC);
-
- // Create the OpenGL render context:
- stat_hWindowGLRC = tpCreateOpenGLRenderContext(stat_hWindowDC);
-
- // Perform general OpenGL initializations:
- tpPerformGeneralOpenGLInitializations();
-
- // Perform calculations (setting view port, etc) that are related with the
- // window initial size:
- tpOnWindowSizeChanged(stat_windowWidth, stat_windowHeight);
-
- // Do the application message loop:
- retVal = tpApplicationMessageLoop();
-
- // Perform OpenGL cleanups:
- tpPerformGeneralOpenCleanups();
-
- // Clean up:
- ReleaseDC(hWnd, stat_hWindowDC);
-
- return retVal;
- }
-
-