第四章:缓冲区、着色器、GLSL
原文链接:
本章更新了框架。GraphicsClass下面增加了3个新的类CameraClass、ModelClass、ColorShaderClass。CameraClass来处理我们之前讨论的视口矩阵。当需要绘制从视角看到的场景时,这个类将摄像机的位置传递给着色器。ModelClass处理3D模型的几何变换,本章为了简单只使用了一个三角形。ColorShaderClass通过GLSL着色器将模型渲染到屏幕上。
We will begin the tutorial code by looking at the GLSL shader program first.
本教程先从GLSL着色器代码开始。
Color.vs
These will be our first shader programs. Shaders are small programs that do the actual rendering of models. These shaders are written in GLSL and stored in source files called color.vs and color.ps. I placed the files with the .cpp and .h files in the engine for now. The purpose of this shader is just to draw colored triangles as I am keeping things simple as possible in this first GLSL tutorial. Here is the code for the vertex shader first:
这是我们首次写着色器程序。着色器程序用来渲染模型。这些着色器使用GLSL编写并将代码保存到color.vs和color.ps文件。我将文件放在engine下和.cpp .h文件相同的目录。作为首个着色器程序,只负责绘制一个带颜色的三角形。下面是顶点着色器代码:
// Filename: color.vs
The vertex shader begins by defining the version of GLSL that we are working with. The version we are working with is 4.0. The higher the version the more features that can be unlocked and used in the shader code.
在顶点着色器的头部定义了GLSL的版本。我们使用的版本是4.0。更高的版本意味着可以在着色器的代码里使用更多的特性。
#version 400
/
// INPUT VARIABLES //
/
in vec3 inputPosition;
in vec3 inputColor;
//
// OUTPUT VARIABLES //
//
out vec3 color;
///
// UNIFORM VARIABLES //
///
uniform mat4 worldMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
// Vertex Shadervoid 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 input color for the pixel shader to use.color = inputColor;
}
// Filename: color.ps#version 400/
// INPUT VARIABLES //
/
in vec3 color;//
// OUTPUT VARIABLES //
//
out vec4 outputColor;// Pixel Shadervoid main(void)
{outputColor = vec4(color, 1.0f);
}
// Filename: colorshaderclass.h#ifndef _COLORSHADERCLASS_H_
#define _COLORSHADERCLASS_H_//
// INCLUDES //
//
#include <fstream>
using namespace std;///
// MY CLASS INCLUDES //
///
#include "openglclass.h"// Class name: ColorShaderClassclass ColorShaderClass
{
public:ColorShaderClass();ColorShaderClass(const ColorShaderClass&);~ColorShaderClass();
bool Initialize(OpenGLClass*, HWND);void Shutdown(OpenGLClass*);void SetShader(OpenGLClass*);bool SetShaderParameters(OpenGLClass*, float*, 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
Colorshaderclass.cpp
// Filename: colorshaderclass.cpp#include "colorshaderclass.h"ColorShaderClass::ColorShaderClass()
{
}ColorShaderClass::ColorShaderClass(const ColorShaderClass& other)
{
}ColorShaderClass::~ColorShaderClass()
{
}
bool ColorShaderClass::Initialize(OpenGLClass* OpenGL, HWND hwnd)
{bool result;// Initialize the vertex and pixel shaders.result = InitializeShader("../Engine/color.vs", "../Engine/color.ps", OpenGL, hwnd);if(!result){return false;}return true;
}
void ColorShaderClass::Shutdown(OpenGLClass* OpenGL)
{// Shutdown the vertex and pixel shaders as well as the related objects.ShutdownShader(OpenGL);return;
}
void ColorShaderClass::SetShader(OpenGLClass* OpenGL)
{// Install the shader program as part of the current rendering state.OpenGL->glUseProgram(m_shaderProgram);return;
}
bool ColorShaderClass::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, "inputColor");// 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* ColorShaderClass::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 ColorShaderClass::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 ColorShaderClass::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 ColorShaderClass::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 ColorShaderClass::SetShaderParameters(OpenGLClass* OpenGL, float* worldMatrix, float* viewMatrix, float* projectionMatrix)
{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);return true;
}
// Filename: modelclass.h#ifndef _MODELCLASS_H_
#define _MODELCLASS_H_///
// MY CLASS INCLUDES //
///
#include "openglclass.h"// Class name: ModelClassclass ModelClass
{
private:
struct VertexType{float x, y, z;float r, g, b;};public:ModelClass();ModelClass(const ModelClass&);~ModelClass();
bool Initialize(OpenGLClass*);void Shutdown(OpenGLClass*);void Render(OpenGLClass*);private:bool InitializeBuffers(OpenGLClass*);void ShutdownBuffers(OpenGLClass*);void RenderBuffers(OpenGLClass*);The private variables in the ModelClass are the vertex array object, vertex buffer, and index buffer IDs. Also there are two integers to keep track of the size of the vertex and index buffers.
ModelClass定义的私有变量是顶点数组对象、顶点缓冲区和索引缓冲区ID。还定义了两个整形变量来保存顶点的和索引的数量。private:int m_vertexCount, m_indexCount;unsigned int m_vertexArrayId, m_vertexBufferId, m_indexBufferId;
};#endif
Modelclass.cpp
// Filename: modelclass.cpp#include "modelclass.h"ModelClass::ModelClass()
{
}ModelClass::ModelClass(const ModelClass& other)
{
}ModelClass::~ModelClass()
{
}
bool ModelClass::Initialize(OpenGLClass* OpenGL)
{bool result;// Initialize the vertex and index buffer that hold the geometry for the triangle.result = InitializeBuffers(OpenGL);if(!result){return false;}return true;
}
void ModelClass::Shutdown(OpenGLClass* OpenGL)
{// 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].r = 0.0f; // Color.vertices[0].g = 1.0f;vertices[0].b = 0.0f;// Top middle.vertices[1].x = 0.0f; // Position.vertices[1].y = 1.0f;vertices[1].z = 0.0f;vertices[1].r = 0.0f; // Color.vertices[1].g = 1.0f;vertices[1].b = 0.0f;// Bottom right.vertices[2].x = 1.0f; // Position.vertices[2].y = -1.0f;vertices[2].z = 0.0f;vertices[2].r = 0.0f; // Color.vertices[2].g = 1.0f;vertices[2].b = 0.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 and color) 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);// Enable the two vertex array attributes.OpenGL->glEnableVertexAttribArray(0); // Vertex position.OpenGL->glEnableVertexAttribArray(1); // Vertex color.// 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 color portion of the vertex buffer.OpenGL->glBindBuffer(GL_ARRAY_BUFFER, m_vertexBufferId);OpenGL->glVertexAttribPointer(1, 3, GL_FLOAT, false, sizeof(VertexType), (unsigned char*)NULL + (3 * 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;
}
// Filename: cameraclass.h#ifndef _CAMERACLASS_H_
#define _CAMERACLASS_H_//
// INCLUDES //
//
#include <math.h>// Class name: CameraClassclass CameraClass
{
private:struct VectorType{float x, y, z;};public:CameraClass();CameraClass(const CameraClass&);~CameraClass();void SetPosition(float, float, float);void SetRotation(float, float, float);void Render();void GetViewMatrix(float*);private:void MatrixRotationYawPitchRoll(float*, float, float, float);void TransformCoord(VectorType&, float*);void BuildViewMatrix(VectorType, VectorType, VectorType);private:float m_positionX, m_positionY, m_positionZ;float m_rotationX, m_rotationY, m_rotationZ;float m_viewMatrix[16];
};#endif
// Filename: cameraclass.cpp#include "cameraclass.h"
The class constructor will initialize the position and rotation of the camera to be at the origin of the scene.CameraClass::CameraClass()
{m_positionX = 0.0f;m_positionY = 0.0f;m_positionZ = 0.0f;m_rotationX = 0.0f;m_rotationY = 0.0f;m_rotationZ = 0.0f;
}CameraClass::CameraClass(const CameraClass& other)
{
}CameraClass::~CameraClass()
{
}
The SetPosition and SetRotation functions are used for setting up the position and rotation of the camera.
void CameraClass::SetPosition(float x, float y, float z)
{m_positionX = x;m_positionY = y;m_positionZ = z;return;
}void CameraClass::SetRotation(float x, float y, float z)
{m_rotationX = x;m_rotationY = y;m_rotationZ = z;return;
}
void CameraClass::Render()
{VectorType up, position, lookAt;float yaw, pitch, roll;float rotationMatrix[9];// Setup the vector that points upwards.
// 设置摄像机的正方向up.x = 0.0f;up.y = 1.0f;up.z = 0.0f;// Setup the position of the camera in the world.position.x = m_positionX;position.y = m_positionY;position.z = m_positionZ;// Setup where the camera is looking by default.lookAt.x = 0.0f;lookAt.y = 0.0f;lookAt.z = 1.0f;// Set the yaw (Y axis), pitch (X axis), and roll (Z axis) rotations in radians.pitch = m_rotationX * 0.0174532925f;yaw = m_rotationY * 0.0174532925f;roll = m_rotationZ * 0.0174532925f;// Create the rotation matrix from the yaw, pitch, and roll values.MatrixRotationYawPitchRoll(rotationMatrix, yaw, pitch, roll);// Transform the lookAt and up vector by the rotation matrix so the view is correctly rotated at the origin.TransformCoord(lookAt, rotationMatrix);TransformCoord(up, rotationMatrix);// Translate the rotated camera position to the location of the viewer.lookAt.x = position.x + lookAt.x;lookAt.y = position.y + lookAt.y;lookAt.z = position.z + lookAt.z;// Finally create the view matrix from the three updated vectors.BuildViewMatrix(position, lookAt, up);return;
}
void CameraClass::MatrixRotationYawPitchRoll(float* matrix, float yaw, float pitch, float roll)
{float cYaw, cPitch, cRoll, sYaw, sPitch, sRoll;// Get the cosine and sin of the yaw, pitch, and roll.cYaw = cosf(yaw);cPitch = cosf(pitch);cRoll = cosf(roll);sYaw = sinf(yaw);sPitch = sinf(pitch);sRoll = sinf(roll);// Calculate the yaw, pitch, roll rotation matrix.matrix[0] = (cRoll * cYaw) + (sRoll * sPitch * sYaw);matrix[1] = (sRoll * cPitch);matrix[2] = (cRoll * -sYaw) + (sRoll * sPitch * cYaw);matrix[3] = (-sRoll * cYaw) + (cRoll * sPitch * sYaw);matrix[4] = (cRoll * cPitch);matrix[5] = (sRoll * sYaw) + (cRoll * sPitch * cYaw);matrix[6] = (cPitch * sYaw);matrix[7] = -sPitch;matrix[8] = (cPitch * cYaw);return;
}
void CameraClass::TransformCoord(VectorType& vector, float* matrix)
{float x, y, z;// Transform the vector by the 3x3 matrix.x = (vector.x * matrix[0]) + (vector.y * matrix[3]) + (vector.z * matrix[6]);y = (vector.x * matrix[1]) + (vector.y * matrix[4]) + (vector.z * matrix[7]);z = (vector.x * matrix[2]) + (vector.y * matrix[5]) + (vector.z * matrix[8]);// Store the result in the reference.vector.x = x;vector.y = y;vector.z = z;return;
}
void CameraClass::BuildViewMatrix(VectorType position, VectorType lookAt, VectorType up)
{VectorType zAxis, xAxis, yAxis;float length, result1, result2, result3;// zAxis = normal(lookAt - position)zAxis.x = lookAt.x - position.x;zAxis.y = lookAt.y - position.y;zAxis.z = lookAt.z - position.z;length = sqrt((zAxis.x * zAxis.x) + (zAxis.y * zAxis.y) + (zAxis.z * zAxis.z));zAxis.x = zAxis.x / length;zAxis.y = zAxis.y / length;zAxis.z = zAxis.z / length;// xAxis = normal(cross(up, zAxis))xAxis.x = (up.y * zAxis.z) - (up.z * zAxis.y);xAxis.y = (up.z * zAxis.x) - (up.x * zAxis.z);xAxis.z = (up.x * zAxis.y) - (up.y * zAxis.x);length = sqrt((xAxis.x * xAxis.x) + (xAxis.y * xAxis.y) + (xAxis.z * xAxis.z));xAxis.x = xAxis.x / length;xAxis.y = xAxis.y / length;xAxis.z = xAxis.z / length;// yAxis = cross(zAxis, xAxis)yAxis.x = (zAxis.y * xAxis.z) - (zAxis.z * xAxis.y);yAxis.y = (zAxis.z * xAxis.x) - (zAxis.x * xAxis.z);yAxis.z = (zAxis.x * xAxis.y) - (zAxis.y * xAxis.x);// -dot(xAxis, position)result1 = ((xAxis.x * position.x) + (xAxis.y * position.y) + (xAxis.z * position.z)) * -1.0f;// -dot(yaxis, eye)result2 = ((yAxis.x * position.x) + (yAxis.y * position.y) + (yAxis.z * position.z)) * -1.0f;// -dot(zaxis, eye)result3 = ((zAxis.x * position.x) + (zAxis.y * position.y) + (zAxis.z * position.z)) * -1.0f;// Set the computed values in the view matrix.m_viewMatrix[0] = xAxis.x;m_viewMatrix[1] = yAxis.x;m_viewMatrix[2] = zAxis.x;m_viewMatrix[3] = 0.0f;m_viewMatrix[4] = xAxis.y;m_viewMatrix[5] = yAxis.y;m_viewMatrix[6] = zAxis.y;m_viewMatrix[7] = 0.0f;m_viewMatrix[8] = xAxis.z;m_viewMatrix[9] = yAxis.z;m_viewMatrix[10] = zAxis.z;m_viewMatrix[11] = 0.0f;m_viewMatrix[12] = result1;m_viewMatrix[13] = result2;m_viewMatrix[14] = result3;m_viewMatrix[15] = 1.0f;return;
}
void CameraClass::GetViewMatrix(float* matrix)
{matrix[0] = m_viewMatrix[0];matrix[1] = m_viewMatrix[1];matrix[2] = m_viewMatrix[2];matrix[3] = m_viewMatrix[3];matrix[4] = m_viewMatrix[4];matrix[5] = m_viewMatrix[5];matrix[6] = m_viewMatrix[6];matrix[7] = m_viewMatrix[7];matrix[8] = m_viewMatrix[8];matrix[9] = m_viewMatrix[9];matrix[10] = m_viewMatrix[10];matrix[11] = m_viewMatrix[11];matrix[12] = m_viewMatrix[12];matrix[13] = m_viewMatrix[13];matrix[14] = m_viewMatrix[14];matrix[15] = m_viewMatrix[15];return;
}
// Filename: graphicsclass.h#ifndef _GRAPHICSCLASS_H_
#define _GRAPHICSCLASS_H_///
// MY CLASS INCLUDES //
///
#include "openglclass.h"
#include "cameraclass.h"
#include "modelclass.h"
#include "colorshaderclass.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: GraphicsClassclass GraphicsClass
{
public:GraphicsClass();GraphicsClass(const GraphicsClass&);~GraphicsClass();bool Initialize(OpenGLClass*, HWND);void Shutdown();bool Frame();private:bool Render();private:OpenGLClass* m_OpenGL;CameraClass* m_Camera;ModelClass* m_Model;ColorShaderClass* m_ColorShader;
};#endif
Graphicsclass.cpp
// Filename: graphicsclass.cpp#include "graphicsclass.h"
The first change to GraphicsClass is initializing the camera, model, and color shader objects in the class constructor to null.
GraphicsClass::GraphicsClass()
{m_OpenGL = 0;m_Camera = 0;m_Model = 0;m_ColorShader = 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);if(!result){MessageBox(hwnd, L"Could not initialize the model object.", L"Error", MB_OK);return false;}// Create the color shader object.m_ColorShader = new ColorShaderClass;if(!m_ColorShader){return false;}// Initialize the color shader object.result = m_ColorShader->Initialize(m_OpenGL, hwnd);if(!result){MessageBox(hwnd, L"Could not initialize the color shader object.", L"Error", MB_OK);return false;}return true;
}
void GraphicsClass::Shutdown()
{// Release the color shader object.if(m_ColorShader){m_ColorShader->Shutdown(m_OpenGL);delete m_ColorShader;m_ColorShader = 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;// Render the graphics scene.result = Render();if(!result){return false;}return true;
}
bool GraphicsClass::Render()
{float worldMatrix[16];float viewMatrix[16];float projectionMatrix[16];// 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);// Set the color shader as the current shader program and set the matrices that it will use for rendering.m_ColorShader->SetShader(m_OpenGL);m_ColorShader->SetShaderParameters(m_OpenGL, worldMatrix, viewMatrix, projectionMatrix);// Render the model using the color shader.m_Model->Render(m_OpenGL);// Present the rendered scene to the screen.m_OpenGL->EndScene();return true;
}
第四章:缓冲区、着色器、GLSL相关推荐
- 《图形着色器的理论与实践(第2版)》翻译——第11章:着色器和图像处理(1)(Image Manipulation and Shaders)
本书是图形学编程的不错读物,通过浅显易懂,理论结合实践的方式介绍着色器的使用,我在翻译的过程中尽量保持原文的段落和含义,会删除比较无关的内容. 专有词汇会附加英文原词,用标签的形式表示,如 着色器(s ...
- osgEarth的Rex引擎原理分析(一二四)osgEarth着色器文件与场景树节点的对应关系
目标:(一二三)中问题210 场景树 rex | terrain-------------------------------------------------------------------- ...
- OpenGL着色器GLSL
OpenGL着色器 OpenGL着色器简介 GLSL 数据类型 向量 输入与输出 顶点着色器 片段着色器 Uniform 更多属性 我们自己的着色器类 从文件读取 OpenGL着色器简介 着色器(Sh ...
- 用vulkan写个引擎 (四)PBR着色器
PBR全称(Physicallly-Based Rendering),基于物理的渲染.本文将提供一份GLSL实用型着色器.对于理论部分网络上已经有太多文章了. 仓库:https://bitbucket ...
- 【OpenGL】蓝宝书第十一章——高级着色器应用
目录 高级顶点着色器 在顶点着色器中进行物理模拟 几何着色器 直通几何着色器 在应用程序中使用几何着色器 在几何着色器中丢弃几何图形 在几何着色器中修改几何图形 在几何着色器中生成几何图形 在几何着色 ...
- Learn OpenGL(四)——片段着色器(Fragment Shader)
片段着色器(Fragment Shader) 片段着色器是第二个也是最终我们打算创建的用于渲染三角形的着色器. 片段着色器的全部, 都是用来计算你的像素的最后颜色输出. 为了让事情比较简单, 我们的片 ...
- Shader攻占笔记(四)卡通着色器
卡通着色器 卡通光照 描边 -- 全息描边 描边 -- 顶点膨胀描边 沿着法线 在顶点与法线之间抉择 高光改进 卡通光照 课本上介绍的卡通着色器有使用坡度图(ramp map)和直接程序截断两种方法. ...
- 第三十九章 几何着色器总结
下面看下几何着色器:是顶点和片段着色器之间的着色器. 输入是一个图元(点或者三角形)的一组顶点,在顶点发送到下一阶段着色器之前可以随意变换,能够将这组顶点变换为完全不同的图元,并且生成比原来更多的顶点 ...
- Python第四章__装饰器、迭代器
http://www.cnblogs.com/bj-xy/p/6477728.html 转载于:https://www.cnblogs.com/ITniu/p/6480062.html
- 【我的OpenGL学习进阶之旅】着色器GLSL运行时报错: ERROR: 0:40: ‘gl_FragColor‘ : undeclared identifier
一.错误描述 把从一段GLSL2.0的代码改造成GLSL3.0代码的时候,运行报错,如下所示: [GLUtils.cpp][loadShader][42]: GLUtils::loadShader e ...
最新文章
- 贝叶斯岭回归(BayesianRidge)、自动关联决策回归、高斯过程、核函数、及高斯回归、高斯过程分类
- 获取命令帮助的六种方法
- matlab 分段式规范作图
- eclipse常用插件安装
- 程序员到底要不要用框架开发?
- 什么是JAVA语言为什么要学习JAVA
- Go 开发关键技术指南 | 为什么你要选择 GO?(内含超全知识大图)
- T-SQL笔记6:GO
- flutter网络dio框架get请求使用总结
- Dart 1(环境安装)
- 马斯克的星链计划对互联网有哪些影响?
- mongodb的初步使用
- pch文件找不到的解决办法
- jfinal解决跨域(eova和jfinal)
- 人工智能、机器学习、神经网络及深度学习关系
- HTML+css实现元素居中对齐的方法
- ROS时钟--支持时间倒计时小工具
- 去哪儿网2018春招软件开发工程师、前端开发工程师编程题 - 题解
- 【年度总结】于无声处听惊雷-2016年度总结
- 数字图像信号-灰度内插