标签:opengl
原文链接:
//////////////////////////////////////////////////////////////////////////////// // Filename: light.vs //////////////////////////////////////////////////////////////////////////////// #version 400
///////////////////// // INPUT VARIABLES // ///////////////////// in vec3 inputPosition; in vec2 inputTexCoord; in vec3 inputNormal; ////////////////////// // OUTPUT VARIABLES // ////////////////////// out vec2 texCoord; out vec3 normal; /////////////////////// // UNIFORM VARIABLES // /////////////////////// uniform mat4 worldMatrix; uniform mat4 viewMatrix; uniform mat4 projectionMatrix; //////////////////////////////////////////////////////////////////////////////// // Vertex Shader //////////////////////////////////////////////////////////////////////////////// void main(void) { // Calculate the position of the vertex against the world, view, and projection matrices. gl_Position = worldMatrix * vec4(inputPosition, 1.0f); gl_Position = viewMatrix * gl_Position; gl_Position = projectionMatrix * gl_Position; // Store the texture coordinates for the pixel shader. texCoord = inputTexCoord;
// Calculate the normal vector against the world matrix only. normal = mat3(worldMatrix) * inputNormal; // Normalize the normal vector. normal = normalize(normal); }
//////////////////////////////////////////////////////////////////////////////// // Filename: light.ps //////////////////////////////////////////////////////////////////////////////// #version 400
///////////////////// // INPUT VARIABLES // ///////////////////// in vec2 texCoord; in vec3 normal; ////////////////////// // OUTPUT VARIABLES // ////////////////////// out vec4 outputColor;
/////////////////////// // UNIFORM VARIABLES // /////////////////////// uniform sampler2D shaderTexture; uniform vec3 lightDirection; uniform vec4 diffuseLightColor; //////////////////////////////////////////////////////////////////////////////// // Pixel Shader //////////////////////////////////////////////////////////////////////////////// void main(void) { vec4 textureColor; vec3 lightDir; float lightIntensity; // Sample the pixel color from the texture using the sampler at this texture coordinate location. textureColor = texture(shaderTexture, texCoord);
// Invert the light direction for calculations. lightDir = -lightDirection; // Calculate the amount of light on this pixel. lightIntensity = clamp(dot(normal, lightDir), 0.0f, 1.0f); // Determine the final amount of diffuse color based on the diffuse color combined with the light intensity. outputColor = clamp((diffuseLightColor * lightIntensity), 0.0f, 1.0f);
// Multiply the texture pixel and the final diffuse color to get the final pixel color result. outputColor = outputColor * textureColor; }
//////////////////////////////////////////////////////////////////////////////// // Filename: lightshaderclass.h //////////////////////////////////////////////////////////////////////////////// #ifndef _LIGHTSHADERCLASS_H_ #define _LIGHTSHADERCLASS_H_ ////////////// // INCLUDES // ////////////// #include <fstream> using namespace std; /////////////////////// // MY CLASS INCLUDES // /////////////////////// #include "openglclass.h" //////////////////////////////////////////////////////////////////////////////// // Class name: LightShaderClass //////////////////////////////////////////////////////////////////////////////// class LightShaderClass { public: LightShaderClass(); LightShaderClass(const LightShaderClass&); ~LightShaderClass(); bool Initialize(OpenGLClass*, HWND); void Shutdown(OpenGLClass*); void SetShader(OpenGLClass*); bool SetShaderParameters(OpenGLClass*, float*, float*, float*, int, float*, float*); private: bool InitializeShader(char*, char*, OpenGLClass*, HWND); char* LoadShaderSourceFile(char*); void OutputShaderErrorMessage(OpenGLClass*, HWND, unsigned int, char*); void OutputLinkerErrorMessage(OpenGLClass*, HWND, unsigned int); void ShutdownShader(OpenGLClass*); private: unsigned int m_vertexShader; unsigned int m_fragmentShader; unsigned int m_shaderProgram; }; #endif
//////////////////////////////////////////////////////////////////////////////// // Filename: lightshaderclass.cpp //////////////////////////////////////////////////////////////////////////////// #include "lightshaderclass.h" LightShaderClass::LightShaderClass() { } LightShaderClass::LightShaderClass(const LightShaderClass& other) { } LightShaderClass::~LightShaderClass() { } bool LightShaderClass::Initialize(OpenGLClass* OpenGL, HWND hwnd) { bool result;
// Initialize the vertex and pixel shaders. result = InitializeShader("../Engine/light.vs", "../Engine/light.ps", OpenGL, hwnd); if(!result) { return false; } return true; } void LightShaderClass::Shutdown(OpenGLClass* OpenGL) { // Shutdown the vertex and pixel shaders as well as the related objects. ShutdownShader(OpenGL); return; } void LightShaderClass::SetShader(OpenGLClass* OpenGL) { // Install the shader program as part of the current rendering state. OpenGL->glUseProgram(m_shaderProgram); return; } bool LightShaderClass::InitializeShader(char* vsFilename, char* fsFilename, OpenGLClass* OpenGL, HWND hwnd) { const char* vertexShaderBuffer; const char* fragmentShaderBuffer; int status; // Load the vertex shader source file into a text buffer. vertexShaderBuffer = LoadShaderSourceFile(vsFilename); if(!vertexShaderBuffer) { return false; } // Load the fragment shader source file into a text buffer. fragmentShaderBuffer = LoadShaderSourceFile(fsFilename); if(!fragmentShaderBuffer) { return false; } // Create a vertex and fragment shader object. m_vertexShader = OpenGL->glCreateShader(GL_VERTEX_SHADER); m_fragmentShader = OpenGL->glCreateShader(GL_FRAGMENT_SHADER); // Copy the shader source code strings into the vertex and fragment shader objects. OpenGL->glShaderSource(m_vertexShader, 1, &vertexShaderBuffer, NULL); OpenGL->glShaderSource(m_fragmentShader, 1, &fragmentShaderBuffer, NULL); // Release the vertex and fragment shader buffers. delete [] vertexShaderBuffer; vertexShaderBuffer = 0; delete [] fragmentShaderBuffer; fragmentShaderBuffer = 0; // Compile the shaders. OpenGL->glCompileShader(m_vertexShader); OpenGL->glCompileShader(m_fragmentShader); // Check to see if the vertex shader compiled successfully. OpenGL->glGetShaderiv(m_vertexShader, GL_COMPILE_STATUS, &status); if(status != 1) { // If it did not compile then write the syntax error message out to a text file for review. OutputShaderErrorMessage(OpenGL, hwnd, m_vertexShader, vsFilename); return false; } // Check to see if the fragment shader compiled successfully. OpenGL->glGetShaderiv(m_fragmentShader, GL_COMPILE_STATUS, &status); if(status != 1) { // If it did not compile then write the syntax error message out to a text file for review. OutputShaderErrorMessage(OpenGL, hwnd, m_fragmentShader, fsFilename); return false; } // Create a shader program object. m_shaderProgram = OpenGL->glCreateProgram(); // Attach the vertex and fragment shader to the program object. OpenGL->glAttachShader(m_shaderProgram, m_vertexShader); OpenGL->glAttachShader(m_shaderProgram, m_fragmentShader);
// Bind the shader input variables. OpenGL->glBindAttribLocation(m_shaderProgram, 0, "inputPosition"); OpenGL->glBindAttribLocation(m_shaderProgram, 1, "inputTexCoord"); OpenGL->glBindAttribLocation(m_shaderProgram, 2, "inputNormal"); // Link the shader program. OpenGL->glLinkProgram(m_shaderProgram); // Check the status of the link. OpenGL->glGetProgramiv(m_shaderProgram, GL_LINK_STATUS, &status); if(status != 1) { // If it did not link then write the syntax error message out to a text file for review. OutputLinkerErrorMessage(OpenGL, hwnd, m_shaderProgram); return false; } return true; } char* LightShaderClass::LoadShaderSourceFile(char* filename) { ifstream fin; int fileSize; char input; char* buffer; // Open the shader source file. fin.open(filename); // If it could not open the file then exit. if(fin.fail()) { return 0; } // Initialize the size of the file. fileSize = 0; // Read the first element of the file. fin.get(input); // Count the number of elements in the text file. while(!fin.eof()) { fileSize++; fin.get(input); } // Close the file for now. fin.close(); // Initialize the buffer to read the shader source file into. buffer = new char[fileSize+1]; if(!buffer) { return 0; } // Open the shader source file again. fin.open(filename); // Read the shader text file into the buffer as a block. fin.read(buffer, fileSize); // Close the file. fin.close(); // Null terminate the buffer. buffer[fileSize] = '\0'; return buffer; } void LightShaderClass::OutputShaderErrorMessage(OpenGLClass* OpenGL, HWND hwnd, unsigned int shaderId, char* shaderFilename) { int logSize, i; char* infoLog; ofstream fout; wchar_t newString[128]; unsigned int error, convertedChars; // Get the size of the string containing the information log for the failed shader compilation message. OpenGL->glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &logSize); // Increment the size by one to handle also the null terminator. logSize++; // Create a char buffer to hold the info log. infoLog = new char[logSize]; if(!infoLog) { return; } // Now retrieve the info log. OpenGL->glGetShaderInfoLog(shaderId, logSize, NULL, infoLog); // Open a file to write the error message to. fout.open("shader-error.txt"); // Write out the error message. for(i=0; i<logSize; i++) { fout << infoLog[i]; } // Close the file. fout.close(); // Convert the shader filename to a wide character string. error = mbstowcs_s(&convertedChars, newString, 128, shaderFilename, 128); if(error != 0) { return; } // Pop a message up on the screen to notify the user to check the text file for compile errors. MessageBox(hwnd, L"Error compiling shader. Check shader-error.txt for message.", newString, MB_OK); return; } void LightShaderClass::OutputLinkerErrorMessage(OpenGLClass* OpenGL, HWND hwnd, unsigned int programId) { int logSize, i; char* infoLog; ofstream fout; // Get the size of the string containing the information log for the failed shader compilation message. OpenGL->glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &logSize); // Increment the size by one to handle also the null terminator. logSize++; // Create a char buffer to hold the info log. infoLog = new char[logSize]; if(!infoLog) { return; } // Now retrieve the info log. OpenGL->glGetProgramInfoLog(programId, logSize, NULL, infoLog); // Open a file to write the error message to. fout.open("linker-error.txt"); // Write out the error message. for(i=0; i<logSize; i++) { fout << infoLog[i]; } // Close the file. fout.close(); // Pop a message up on the screen to notify the user to check the text file for linker errors. MessageBox(hwnd, L"Error compiling linker. Check linker-error.txt for message.", L"Linker Error", MB_OK); return; } void LightShaderClass::ShutdownShader(OpenGLClass* OpenGL) { // Detach the vertex and fragment shaders from the program. OpenGL->glDetachShader(m_shaderProgram, m_vertexShader); OpenGL->glDetachShader(m_shaderProgram, m_fragmentShader); // Delete the vertex and fragment shaders. OpenGL->glDeleteShader(m_vertexShader); OpenGL->glDeleteShader(m_fragmentShader); // Delete the shader program. OpenGL->glDeleteProgram(m_shaderProgram); return; }
bool LightShaderClass::SetShaderParameters(OpenGLClass* OpenGL, float* worldMatrix, float* viewMatrix, float* projectionMatrix, int textureUnit, float* lightDirection, float* diffuseLightColor) { unsigned int location; // Set the world matrix in the vertex shader. location = OpenGL->glGetUniformLocation(m_shaderProgram, "worldMatrix"); if(location == -1) { return false; } OpenGL->glUniformMatrix4fv(location, 1, false, worldMatrix); // Set the view matrix in the vertex shader. location = OpenGL->glGetUniformLocation(m_shaderProgram, "viewMatrix"); if(location == -1) { return false; } OpenGL->glUniformMatrix4fv(location, 1, false, viewMatrix); // Set the projection matrix in the vertex shader. location = OpenGL->glGetUniformLocation(m_shaderProgram, "projectionMatrix"); if(location == -1) { return false; } OpenGL->glUniformMatrix4fv(location, 1, false, projectionMatrix); // Set the texture in the pixel shader to use the data from the first texture unit. location = OpenGL->glGetUniformLocation(m_shaderProgram, "shaderTexture"); if(location == -1) { return false; } OpenGL->glUniform1i(location, textureUnit);
// Set the light direction in the pixel shader. location = OpenGL->glGetUniformLocation(m_shaderProgram, "lightDirection"); if(location == -1) { return false; } OpenGL->glUniform3fv(location, 1, lightDirection); // Set the light direction in the pixel shader. location = OpenGL->glGetUniformLocation(m_shaderProgram, "diffuseLightColor"); if(location == -1) { return false; } OpenGL->glUniform4fv(location, 1, diffuseLightColor); return true; }
//////////////////////////////////////////////////////////////////////////////// // Filename: modelclass.h //////////////////////////////////////////////////////////////////////////////// #ifndef _MODELCLASS_H_ #define _MODELCLASS_H_ /////////////////////// // MY CLASS INCLUDES // /////////////////////// #include "textureclass.h" //////////////////////////////////////////////////////////////////////////////// // Class name: ModelClass //////////////////////////////////////////////////////////////////////////////// class ModelClass { private:
struct VertexType { float x, y, z; float tu, tv; float nx, ny, nz; }; public: ModelClass(); ModelClass(const ModelClass&); ~ModelClass(); bool Initialize(OpenGLClass*, char*, unsigned int, bool); void Shutdown(OpenGLClass*); void Render(OpenGLClass*); private: bool InitializeBuffers(OpenGLClass*); void ShutdownBuffers(OpenGLClass*); void RenderBuffers(OpenGLClass*); bool LoadTexture(OpenGLClass*, char*, unsigned int, bool); void ReleaseTexture(); private: int m_vertexCount, m_indexCount; unsigned int m_vertexArrayId, m_vertexBufferId, m_indexBufferId; TextureClass* m_Texture; }; #endif
//////////////////////////////////////////////////////////////////////////////// // Filename: modelclass.cpp //////////////////////////////////////////////////////////////////////////////// #include "modelclass.h" ModelClass::ModelClass() { m_Texture = 0; } ModelClass::ModelClass(const ModelClass& other) { } ModelClass::~ModelClass() { } bool ModelClass::Initialize(OpenGLClass* OpenGL, char* textureFilename, unsigned int textureUnit, bool wrap) { bool result; // Initialize the vertex and index buffer that hold the geometry for the triangle. result = InitializeBuffers(OpenGL); if(!result) { return false; } // Load the texture for this model. result = LoadTexture(OpenGL, textureFilename, textureUnit, wrap); if(!result) { return false; } return true; } void ModelClass::Shutdown(OpenGLClass* OpenGL) { // Release the texture used for this model. ReleaseTexture(); // Release the vertex and index buffers. ShutdownBuffers(OpenGL); return; } void ModelClass::Render(OpenGLClass* OpenGL) { // Put the vertex and index buffers on the graphics pipeline to prepare them for drawing. RenderBuffers(OpenGL); return; } bool ModelClass::InitializeBuffers(OpenGLClass* OpenGL) { VertexType* vertices; unsigned int* indices; // Set the number of vertices in the vertex array. m_vertexCount = 3; // Set the number of indices in the index array. m_indexCount = 3; // Create the vertex array. vertices = new VertexType[m_vertexCount]; if(!vertices) { return false; } // Create the index array. indices = new unsigned int[m_indexCount]; if(!indices) { return false; }
// Load the vertex array with data. // Bottom left. vertices[0].x = -1.0f; // Position. vertices[0].y = -1.0f; vertices[0].z = 0.0f; vertices[0].tu = 0.0f; // Texture coordinates. vertices[0].tv = 0.0f; vertices[0].nx = 0.0f; // Normals. vertices[0].ny = 0.0f; vertices[0].nz = -1.0f; // Top middle. vertices[1].x = 0.0f; // Position. vertices[1].y = 1.0f; vertices[1].z = 0.0f; vertices[1].tu = 0.5f; // Texture coordinates. vertices[1].tv = 1.0f; vertices[1].nx = 0.0f; // Normals. vertices[1].ny = 0.0f; vertices[1].nz = -1.0f; // Bottom right. vertices[2].x = 1.0f; // Position. vertices[2].y = -1.0f; vertices[2].z = 0.0f; vertices[2].tu = 1.0f; // Texture coordinates. vertices[2].tv = 0.0f; vertices[2].nx = 0.0f; // Normals. vertices[2].ny = 0.0f; vertices[2].nz = -1.0f; // Load the index array with data. indices[0] = 0; // Bottom left. indices[1] = 1; // Top middle. indices[2] = 2; // Bottom right. // Allocate an OpenGL vertex array object. OpenGL->glGenVertexArrays(1, &m_vertexArrayId); // Bind the vertex array object to store all the buffers and vertex attributes we create here. OpenGL->glBindVertexArray(m_vertexArrayId); // Generate an ID for the vertex buffer. OpenGL->glGenBuffers(1, &m_vertexBufferId); // Bind the vertex buffer and load the vertex (position, texture, and normal) data into the vertex buffer. OpenGL->glBindBuffer(GL_ARRAY_BUFFER, m_vertexBufferId); OpenGL->glBufferData(GL_ARRAY_BUFFER, m_vertexCount * sizeof(VertexType), vertices, GL_STATIC_DRAW); The next major change is that we enable the normal vertex attribute array. // Enable the three vertex array attributes. OpenGL->glEnableVertexAttribArray(0); // Vertex position. OpenGL->glEnableVertexAttribArray(1); // Texture coordinates. OpenGL->glEnableVertexAttribArray(2); // Normals. // Specify the location and format of the position portion of the vertex buffer. OpenGL->glBindBuffer(GL_ARRAY_BUFFER, m_vertexBufferId); OpenGL->glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(VertexType), 0); // Specify the location and format of the texture coordinate portion of the vertex buffer. OpenGL->glBindBuffer(GL_ARRAY_BUFFER, m_vertexBufferId); OpenGL->glVertexAttribPointer(1, 2, GL_FLOAT, false, sizeof(VertexType), (unsigned char*)NULL + (3 * sizeof(float))); We also specify that the position of the normal vector is the 6th, 7th, and 8th float in the buffer. // Specify the location and format of the normal vector portion of the vertex buffer. OpenGL->glBindBuffer(GL_ARRAY_BUFFER, m_vertexBufferId); OpenGL->glVertexAttribPointer(2, 3, GL_FLOAT, false, sizeof(VertexType), (unsigned char*)NULL + (5 * sizeof(float))); // Generate an ID for the index buffer. OpenGL->glGenBuffers(1, &m_indexBufferId); // Bind the index buffer and load the index data into it. OpenGL->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBufferId); OpenGL->glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indexCount* sizeof(unsigned int), indices, GL_STATIC_DRAW); // Now that the buffers have been loaded we can release the array data. delete [] vertices; vertices = 0; delete [] indices; indices = 0; return true; } void ModelClass::ShutdownBuffers(OpenGLClass* OpenGL) { // Disable the two vertex array attributes. OpenGL->glDisableVertexAttribArray(0); OpenGL->glDisableVertexAttribArray(1); // Release the vertex buffer. OpenGL->glBindBuffer(GL_ARRAY_BUFFER, 0); OpenGL->glDeleteBuffers(1, &m_vertexBufferId); // Release the index buffer. OpenGL->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); OpenGL->glDeleteBuffers(1, &m_indexBufferId); // Release the vertex array object. OpenGL->glBindVertexArray(0); OpenGL->glDeleteVertexArrays(1, &m_vertexArrayId); return; } void ModelClass::RenderBuffers(OpenGLClass* OpenGL) { // Bind the vertex array object that stored all the information about the vertex and index buffers. OpenGL->glBindVertexArray(m_vertexArrayId); // Render the vertex buffer using the index buffer. glDrawElements(GL_TRIANGLES, m_indexCount, GL_UNSIGNED_INT, 0); return; } bool ModelClass::LoadTexture(OpenGLClass* OpenGL, char* textureFilename, unsigned int textureUnit, bool wrap) { bool result; // Create the texture object. m_Texture = new TextureClass; if(!m_Texture) { return false; } // Initialize the texture object. result = m_Texture->Initialize(OpenGL, textureFilename, textureUnit, wrap); if(!result) { return false; } return true; } void ModelClass::ReleaseTexture() { // Release the texture object. if(m_Texture) { m_Texture->Shutdown(); delete m_Texture; m_Texture = 0; } return; }
//////////////////////////////////////////////////////////////////////////////// // Filename: lightclass.h //////////////////////////////////////////////////////////////////////////////// #ifndef _LIGHTCLASS_H_ #define _LIGHTCLASS_H_ //////////////////////////////////////////////////////////////////////////////// // Class name: LightClass //////////////////////////////////////////////////////////////////////////////// class LightClass { public: LightClass(); LightClass(const LightClass&); ~LightClass(); void SetDiffuseColor(float, float, float, float); void SetDirection(float, float, float); void GetDiffuseColor(float*); void GetDirection(float*); private: float m_diffuseColor[4]; float m_direction[3]; }; #endif
//////////////////////////////////////////////////////////////////////////////// // Filename: lightclass.cpp //////////////////////////////////////////////////////////////////////////////// #include "lightclass.h" LightClass::LightClass() { } LightClass::LightClass(const LightClass& other) { } LightClass::~LightClass() { } void LightClass::SetDiffuseColor(float red, float green, float blue, float alpha) { m_diffuseColor[0] = red; m_diffuseColor[1] = green; m_diffuseColor[2] = blue; m_diffuseColor[3] = alpha; return; } void LightClass::SetDirection(float x, float y, float z) { m_direction[0] = x; m_direction[1] = y; m_direction[2] = z; return; } void LightClass::GetDiffuseColor(float* color) { color[0] = m_diffuseColor[0]; color[1] = m_diffuseColor[1]; color[2] = m_diffuseColor[2]; color[3] = m_diffuseColor[3]; return; } void LightClass::GetDirection(float* direction) { direction[0] = m_direction[0]; direction[1] = m_direction[1]; direction[2] = m_direction[2]; return; }
//////////////////////////////////////////////////////////////////////////////// // Filename: graphicsclass.h //////////////////////////////////////////////////////////////////////////////// #ifndef _GRAPHICSCLASS_H_ #define _GRAPHICSCLASS_H_ /////////////////////// // MY CLASS INCLUDES // /////////////////////// #include "openglclass.h" #include "cameraclass.h" #include "modelclass.h"
#include "lightshaderclass.h" #include "lightclass.h" ///////////// // GLOBALS // ///////////// const bool FULL_SCREEN = true; const bool VSYNC_ENABLED = true; const float SCREEN_DEPTH = 1000.0f; const float SCREEN_NEAR = 0.1f; //////////////////////////////////////////////////////////////////////////////// // Class name: GraphicsClass //////////////////////////////////////////////////////////////////////////////// class GraphicsClass { public: GraphicsClass(); GraphicsClass(const GraphicsClass&); ~GraphicsClass(); bool Initialize(OpenGLClass*, HWND); void Shutdown(); bool Frame(); private: Render now takes a float value as input. bool Render(float); private: OpenGLClass* m_OpenGL; CameraClass* m_Camera; ModelClass* m_Model;
LightShaderClass* m_LightShader; LightClass* m_Light; }; #endif
//////////////////////////////////////////////////////////////////////////////// // Filename: graphicsclass.cpp //////////////////////////////////////////////////////////////////////////////// #include "graphicsclass.h" GraphicsClass::GraphicsClass() { m_OpenGL = 0; m_Camera = 0; m_Model = 0;
m_LightShader = 0; m_Light = 0; } GraphicsClass::GraphicsClass(const GraphicsClass& other) { } GraphicsClass::~GraphicsClass() { } bool GraphicsClass::Initialize(OpenGLClass* OpenGL, HWND hwnd) { bool result; // Store a pointer to the OpenGL class object. m_OpenGL = OpenGL; // Create the camera object. m_Camera = new CameraClass; if(!m_Camera) { return false; } // Set the initial position of the camera. m_Camera->SetPosition(0.0f, 0.0f, -10.0f); // Create the model object. m_Model = new ModelClass; if(!m_Model) { return false; }
// Initialize the model object. result = m_Model->Initialize(m_OpenGL, "../Engine/data/stone.tga", 0, true); if(!result) { MessageBox(hwnd, L"Could not initialize the model object.", L"Error", MB_OK); return false; }
// Create the light shader object. m_LightShader = new LightShaderClass; if(!m_LightShader) { return false; } // Initialize the light shader object. result = m_LightShader->Initialize(m_OpenGL, hwnd); if(!result) { MessageBox(hwnd, L"Could not initialize the light shader object.", L"Error", MB_OK); return false; }
// Create the light object. m_Light = new LightClass; if(!m_Light) { return false; } // Initialize the light object. m_Light->SetDiffuseColor(1.0f, 1.0f, 0.0f, 1.0f); m_Light->SetDirection(0.0f, 0.0f, 1.0f); return true; } void GraphicsClass::Shutdown() {
// Release the light object. if(m_Light) { delete m_Light; m_Light = 0; } // Release the light shader object. if(m_LightShader) { m_LightShader->Shutdown(m_OpenGL); delete m_LightShader; m_LightShader = 0; } // Release the model object. if(m_Model) { m_Model->Shutdown(m_OpenGL); delete m_Model; m_Model = 0; } // Release the camera object. if(m_Camera) { delete m_Camera; m_Camera = 0; } // Release the pointer to the OpenGL class object. m_OpenGL = 0; return; } bool GraphicsClass::Frame() { bool result;
static float rotation = 0.0f; // Update the rotation variable each frame. rotation += 0.0174532925f * 2.0f; if(rotation > 360.0f) { rotation -= 360.0f; } // Render the graphics scene. result = Render(rotation); if(!result) { return false; } return true; } bool GraphicsClass::Render(float rotation) { float worldMatrix[16]; float viewMatrix[16]; float projectionMatrix[16]; float lightDirection[3]; float diffuseLightColor[4]; // Clear the buffers to begin the scene. m_OpenGL->BeginScene(0.0f, 0.0f, 0.0f, 1.0f); // Generate the view matrix based on the camera's position. m_Camera->Render(); // Get the world, view, and projection matrices from the opengl and camera objects. m_OpenGL->GetWorldMatrix(worldMatrix); m_Camera->GetViewMatrix(viewMatrix); m_OpenGL->GetProjectionMatrix(projectionMatrix); We obtain the direction and diffuse color of the light here. // Get the light properties. m_Light->GetDirection(lightDirection); m_Light->GetDiffuseColor(diffuseLightColor);
// Rotate the world matrix by the rotation value so that the triangle will spin. m_OpenGL->MatrixRotationY(worldMatrix, rotation);
// Set the light shader as the current shader program and set the matrices that it will use for rendering. m_LightShader->SetShader(m_OpenGL); m_LightShader->SetShaderParameters(m_OpenGL, worldMatrix, viewMatrix, projectionMatrix, 0, lightDirection, diffuseLightColor); // Render the model using the light shader. m_Model->Render(m_OpenGL); // Present the rendered scene to the screen. m_OpenGL->EndScene(); return true; }
标签:opengl
原文地址:http://blog.csdn.net/weyson/article/details/46942033