Created
June 19, 2016 18:36
-
-
Save krysseltillada/1c04b4d38903d46a365694d856607bdb to your computer and use it in GitHub Desktop.
exercise 18 (translation, scaling, rotation) matrix stack
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version 330 | |
smooth in vec4 vertexColorOutput; | |
out vec4 fragmentColor; | |
void main () | |
{ | |
fragmentColor = vertexColorOutput; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define GLEW_STATIC | |
#include <GL/glew.h> | |
#include <GL/freeglut.h> | |
#include <cstdlib> | |
#include <string> | |
#include <stdexcept> | |
#include <iostream> | |
#include <stack> | |
#include <glm.hpp> | |
#include <gtc/type_ptr.hpp> | |
#include "Shader.hpp" | |
namespace WindowProperties { | |
float width = 800.0f; | |
float height = 600.0f; | |
const float xPOSITION = 200; | |
const float yPOSITION = 200; | |
std::string windowTitle = "exercise 18 (translation, scaling, rotation) matrix stack"; | |
const GLuint displayMode = GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH; | |
const GLuint openGLMINVERSION = 3; | |
const GLuint openGLMAXVERSION = 3; | |
const GLuint openglProfile = GLUT_CORE_PROFILE; | |
} | |
namespace Window { | |
class MatrixStack { | |
public: | |
MatrixStack() : | |
currMat(1.0f) { } | |
MatrixStack(const int &i) : | |
currMat(i) { } | |
MatrixStack &Translate(const glm::vec3 &position) { | |
glm::mat4 translationMatrix(1.0f); | |
translationMatrix[3].x = position.x; | |
translationMatrix[3].y = position.y; | |
translationMatrix[3].z = position.z; | |
currMat *= translationMatrix; | |
return *this; | |
} | |
MatrixStack &Scale(const glm::vec3 &scale) { | |
glm::mat4 scaleMatrix(1.0f); | |
scaleMatrix[0].x = scale.x; | |
scaleMatrix[1].y = scale.y; | |
scaleMatrix[2].z = scale.z; | |
currMat *= scaleMatrix; | |
return *this; | |
} | |
MatrixStack &Rotate(const glm::vec3 &rotationAxis) { | |
glm::mat4 rotationMatrixX(1.0f); | |
glm::mat4 rotationMatrixY(1.0f); | |
glm::mat4 rotationMatrixZ(1.0f); | |
rotationMatrixX[1].y = glm::cos(rotationAxis.x); | |
rotationMatrixX[1].z = glm::sin(rotationAxis.x); | |
rotationMatrixX[2].y = -glm::sin(rotationAxis.x); | |
rotationMatrixX[2].z = glm::cos(rotationAxis.x); | |
rotationMatrixY[0].x = glm::cos(rotationAxis.y); | |
rotationMatrixY[0].z = -glm::sin(rotationAxis.y); | |
rotationMatrixY[2].x = glm::sin(rotationAxis.y); | |
rotationMatrixY[2].z = glm::cos(rotationAxis.y); | |
rotationMatrixZ[0].x = glm::cos(rotationAxis.z); | |
rotationMatrixZ[0].y = glm::sin(rotationAxis.z); | |
rotationMatrixZ[1].x = -glm::sin(rotationAxis.z); | |
rotationMatrixZ[1].y = glm::cos(rotationAxis.z); | |
currMat *= rotationMatrixY * rotationMatrixX * rotationMatrixZ; | |
return *this; | |
} | |
MatrixStack &push() { | |
matStack.push(currMat); | |
return *this; | |
} | |
MatrixStack &pop() { | |
currMat = matStack.top(); | |
matStack.pop(); | |
return *this; | |
} | |
glm::mat4 peek() { | |
return currMat; | |
} | |
private: | |
glm::mat4 currMat; | |
std::stack <glm::mat4> matStack; | |
}; | |
class Camera { | |
public: | |
glm::vec3 position; | |
float fov, zNear, zFar; | |
}; | |
class Object { | |
public: | |
glm::vec3 position; | |
glm::vec3 scale; | |
glm::vec3 rotate; | |
}; | |
const float vertexData[] = { | |
0.25f, 0.25f, -1.25f, 1.0f, | |
0.25f, -0.25f, -1.25f, 1.0f, | |
-0.25f, 0.25f, -1.25f, 1.0f, | |
0.25f, -0.25f, -1.25f, 1.0f, | |
-0.25f, -0.25f, -1.25f, 1.0f, | |
-0.25f, 0.25f, -1.25f, 1.0f, | |
0.25f, 0.25f, -2.75f, 1.0f, | |
-0.25f, 0.25f, -2.75f, 1.0f, | |
0.25f, -0.25f, -2.75f, 1.0f, | |
0.25f, -0.25f, -2.75f, 1.0f, | |
-0.25f, 0.25f, -2.75f, 1.0f, | |
-0.25f, -0.25f, -2.75f, 1.0f, | |
-0.25f, 0.25f, -1.25f, 1.0f, | |
-0.25f, -0.25f, -1.25f, 1.0f, | |
-0.25f, -0.25f, -2.75f, 1.0f, | |
-0.25f, 0.25f, -1.25f, 1.0f, | |
-0.25f, -0.25f, -2.75f, 1.0f, | |
-0.25f, 0.25f, -2.75f, 1.0f, | |
0.25f, 0.25f, -1.25f, 1.0f, | |
0.25f, -0.25f, -2.75f, 1.0f, | |
0.25f, -0.25f, -1.25f, 1.0f, | |
0.25f, 0.25f, -1.25f, 1.0f, | |
0.25f, 0.25f, -2.75f, 1.0f, | |
0.25f, -0.25f, -2.75f, 1.0f, | |
0.25f, 0.25f, -2.75f, 1.0f, | |
0.25f, 0.25f, -1.25f, 1.0f, | |
-0.25f, 0.25f, -1.25f, 1.0f, | |
0.25f, 0.25f, -2.75f, 1.0f, | |
-0.25f, 0.25f, -1.25f, 1.0f, | |
-0.25f, 0.25f, -2.75f, 1.0f, | |
0.25f, -0.25f, -2.75f, 1.0f, | |
-0.25f, -0.25f, -1.25f, 1.0f, | |
0.25f, -0.25f, -1.25f, 1.0f, | |
0.25f, -0.25f, -2.75f, 1.0f, | |
-0.25f, -0.25f, -2.75f, 1.0f, | |
-0.25f, -0.25f, -1.25f, 1.0f, | |
0.0f, 0.0f, 1.0f, 1.0f, | |
0.0f, 0.0f, 1.0f, 1.0f, | |
0.0f, 0.0f, 1.0f, 1.0f, | |
0.0f, 0.0f, 1.0f, 1.0f, | |
0.0f, 0.0f, 1.0f, 1.0f, | |
0.0f, 0.0f, 1.0f, 1.0f, | |
0.8f, 0.8f, 0.8f, 1.0f, | |
0.8f, 0.8f, 0.8f, 1.0f, | |
0.8f, 0.8f, 0.8f, 1.0f, | |
0.8f, 0.8f, 0.8f, 1.0f, | |
0.8f, 0.8f, 0.8f, 1.0f, | |
0.8f, 0.8f, 0.8f, 1.0f, | |
0.0f, 1.0f, 0.0f, 1.0f, | |
0.0f, 1.0f, 0.0f, 1.0f, | |
0.0f, 1.0f, 0.0f, 1.0f, | |
0.0f, 1.0f, 0.0f, 1.0f, | |
0.0f, 1.0f, 0.0f, 1.0f, | |
0.0f, 1.0f, 0.0f, 1.0f, | |
0.5f, 0.5f, 0.0f, 1.0f, | |
0.5f, 0.5f, 0.0f, 1.0f, | |
0.5f, 0.5f, 0.0f, 1.0f, | |
0.5f, 0.5f, 0.0f, 1.0f, | |
0.5f, 0.5f, 0.0f, 1.0f, | |
0.5f, 0.5f, 0.0f, 1.0f, | |
1.0f, 0.0f, 0.0f, 1.0f, | |
1.0f, 0.0f, 0.0f, 1.0f, | |
1.0f, 0.0f, 0.0f, 1.0f, | |
1.0f, 0.0f, 0.0f, 1.0f, | |
1.0f, 0.0f, 0.0f, 1.0f, | |
1.0f, 0.0f, 0.0f, 1.0f, | |
0.0f, 1.0f, 1.0f, 1.0f, | |
0.0f, 1.0f, 1.0f, 1.0f, | |
0.0f, 1.0f, 1.0f, 1.0f, | |
0.0f, 1.0f, 1.0f, 1.0f, | |
0.0f, 1.0f, 1.0f, 1.0f, | |
0.0f, 1.0f, 1.0f, 1.0f, | |
}; | |
GLfloat triangle[] = { | |
0.5f, -0.5f, 0.0f, 1.0f, | |
-0.5f, -0.5f, 0.0f, 1.0f, | |
0.0f, 0.5f, 0.0f, 1.0f | |
}; | |
glm::mat4 cameraToClipMatrix; | |
GLboolean ifInit = GL_FALSE; | |
GLboolean ifToggleAspect = GL_FALSE; | |
GLboolean ifToggleDClamping = GL_FALSE; | |
GLboolean ifToggleFCulling = GL_FALSE; | |
GLboolean ifToggleDTest = GL_FALSE; | |
GLchar DIkey = '+'; | |
GLuint vertexBufferObject; | |
GLuint vertexArrayObject; | |
GLuint modelToCameraMatrixUniformLocation; | |
GLuint cameraToClipMatrixUniformLocation; | |
GLuint shaderProgram; | |
Camera camera; | |
Object object1; | |
MatrixStack transformationStack; | |
float calcFrustumScale(const float &angle) { | |
return (1.0f / glm::tan(glm::radians(angle) / 2.0f)); | |
} | |
void Update() { | |
if (ifToggleAspect) { | |
cameraToClipMatrix[0].x = calcFrustumScale(camera.fov) / (WindowProperties::width / WindowProperties::height); | |
cameraToClipMatrix[1].y = calcFrustumScale(camera.fov); | |
} | |
else { | |
cameraToClipMatrix[0].x = calcFrustumScale(camera.fov); | |
cameraToClipMatrix[1].y = calcFrustumScale(camera.fov); | |
} | |
if (ifToggleFCulling) { | |
glEnable(GL_CULL_FACE); | |
glCullFace(GL_BACK); | |
glFrontFace(GL_CW); | |
} | |
else | |
glDisable(GL_CULL_FACE); | |
if (ifToggleDTest) { | |
glEnable(GL_DEPTH_TEST); | |
glDepthFunc(GL_LEQUAL); | |
glDepthRange(0.0f, 1.0f); | |
glDepthMask(GL_TRUE); | |
} | |
else | |
glDisable(GL_DEPTH_TEST); | |
if (ifToggleDClamping) | |
glEnable(GL_DEPTH_CLAMP); | |
else | |
glDisable(GL_DEPTH_CLAMP); | |
transformationStack.push(); | |
transformationStack.Translate(glm::vec3(-camera.position.x, -camera.position.y, camera.position.z)); | |
transformationStack.Translate(glm::vec3(object1.position.x, object1.position.y, object1.position.z)); | |
transformationStack.Rotate(glm::vec3(object1.rotate.x, object1.rotate.y, object1.rotate.z)); | |
transformationStack.Scale(glm::vec3(object1.scale.x, object1.scale.y, object1.scale.z)); | |
glUseProgram(shaderProgram); | |
glUniformMatrix4fv(modelToCameraMatrixUniformLocation, 1, GL_FALSE, glm::value_ptr(transformationStack.peek())); | |
glUniformMatrix4fv(cameraToClipMatrixUniformLocation, 1, GL_FALSE, glm::value_ptr(cameraToClipMatrix)); | |
glUseProgram(0); | |
transformationStack.pop(); | |
} | |
void Render() { | |
glUseProgram(shaderProgram); | |
glBindVertexArray(vertexArrayObject); | |
glDrawArrays(GL_TRIANGLES, 0, 36); | |
glBindVertexArray(0); | |
glUseProgram(0); | |
glutSwapBuffers(); | |
glutPostRedisplay(); | |
} | |
void initObjects() { | |
std::cout << "setting the required objects" << std::endl; | |
camera.fov = 45.0f; | |
camera.position.x = 0.0f; | |
camera.position.y = 0.0f; | |
camera.position.z = 0.0f; | |
camera.zNear = 1.0f; | |
camera.zFar = 100.0f; | |
object1.position.x = 0.5f; | |
object1.position.y = 0.4; | |
object1.position.z = -1.0f; | |
object1.scale.x = 1.0f; | |
object1.scale.y = 3.0f; | |
object1.scale.z = 1.0f; | |
object1.rotate.y = 0.0f; | |
object1.rotate.x = 0.0f; | |
object1.rotate.z = 0.0f; | |
std::cout << "loading the shader files" << std::endl; | |
std::string vertexCode = Shader::ShaderUtility::loadShaderFile("transformation.vert"); | |
std::string fragmentCode = Shader::ShaderUtility::loadShaderFile("fragmentColor.frag"); | |
std::cout << "compiling and building the shader program" << std::endl; | |
shaderProgram = Shader::ShaderUtility::buildProgram({ Shader::ShaderUtility::compileShader(vertexCode.c_str(), GL_VERTEX_SHADER), | |
Shader::ShaderUtility::compileShader(fragmentCode.c_str(), GL_FRAGMENT_SHADER) }); | |
glGenBuffers(1, &vertexBufferObject); | |
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject); | |
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW); | |
glBindBuffer(GL_ARRAY_BUFFER, 0); | |
glGenVertexArrays(1, &vertexArrayObject); | |
glBindVertexArray(vertexArrayObject); | |
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject); | |
glEnableVertexAttribArray(0); | |
glEnableVertexAttribArray(1); | |
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, (void *)0); | |
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void *)576); | |
glBindVertexArray(0); | |
glDisableVertexAttribArray(0); | |
glDisableVertexAttribArray(1); | |
glBindBuffer(GL_ARRAY_BUFFER, 0); | |
if (ifToggleAspect) { | |
cameraToClipMatrix[0].x = calcFrustumScale(camera.fov) / (WindowProperties::width / WindowProperties::height); | |
cameraToClipMatrix[1].y = calcFrustumScale(camera.fov); | |
} | |
else { | |
cameraToClipMatrix[0].x = calcFrustumScale(camera.fov); | |
cameraToClipMatrix[1].y = calcFrustumScale(camera.fov); | |
} | |
cameraToClipMatrix[2].z = (camera.zNear + camera.zFar) / (camera.zNear - camera.zFar); | |
cameraToClipMatrix[3].z = (2 * camera.zNear + camera.zFar) / (camera.zNear - camera.zFar); | |
cameraToClipMatrix[2].w = -1.0f; | |
cameraToClipMatrixUniformLocation = glGetUniformLocation(shaderProgram, "cameraToClipMatrix"); | |
modelToCameraMatrixUniformLocation = glGetUniformLocation(shaderProgram, "modelToCameraMatrix"); | |
transformationStack.push(); | |
transformationStack.Translate(glm::vec3(object1.position.x, object1.position.y, object1.position.z)); | |
transformationStack.Translate(glm::vec3(-camera.position.x, -camera.position.y, camera.position.z)); | |
transformationStack.Rotate(glm::vec3(object1.rotate.x, object1.rotate.y, object1.rotate.z)); | |
transformationStack.Scale(glm::vec3(object1.scale.x, object1.scale.y, object1.scale.z)); | |
glUseProgram(shaderProgram); | |
glUniformMatrix4fv(cameraToClipMatrixUniformLocation, 1, GL_FALSE, glm::value_ptr(cameraToClipMatrix)); | |
glUniformMatrix4fv(modelToCameraMatrixUniformLocation, 1, GL_FALSE, glm::value_ptr(transformationStack.peek())); | |
glUseProgram(0); | |
transformationStack.pop(); | |
if (ifToggleFCulling) { | |
glEnable(GL_CULL_FACE); | |
glCullFace(GL_BACK); | |
glFrontFace(GL_CW); | |
} | |
if (ifToggleDTest) { | |
glEnable(GL_DEPTH_TEST); | |
glDepthFunc(GL_LEQUAL); | |
glDepthRange(0.0f, 1.0f); | |
glDepthMask(GL_TRUE); | |
} | |
if (ifToggleDClamping) | |
glEnable(GL_DEPTH_CLAMP); | |
} | |
void Clear() { | |
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | |
glClearDepth(1.0f); | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
} | |
void Run() { | |
if (!ifInit) { | |
initObjects(); | |
ifInit = GL_TRUE; | |
std::cout << "press 1 to toggle aspect ratio" << std::endl | |
<< "press 2 to toggle Depth clamping" << std::endl | |
<< "press 3 to toggle Face culling" << std::endl | |
<< "press 4 to toggle Depth testing" << std::endl; | |
} | |
Clear(); | |
Render(); | |
Update(); | |
} | |
void KeyEvent(unsigned char key, int x, int y) { | |
switch (key) { | |
case '+': | |
std::cout << "increase" << std::endl; | |
DIkey = '+'; | |
break; | |
case '-': | |
std::cout << "decrease" << std::endl; | |
DIkey = '-'; | |
break; | |
case 'r': | |
camera.position.y += 0.1f; | |
break; | |
case 'f': | |
camera.position.y -= 0.1f; | |
break; | |
case 'w': | |
camera.position.z += 0.1f; | |
break; | |
case 's': | |
camera.position.z -= 0.1f; | |
break; | |
case 'a': | |
camera.position.x -= 0.1f; | |
break; | |
case 'd': | |
camera.position.x += 0.1f; | |
break; | |
case 'x': | |
if (DIkey == '+') | |
object1.scale.x += 1.0f; | |
else if (DIkey == '-') | |
object1.scale.x -= 1.0f; | |
break; | |
case 'z': | |
if (DIkey == '+') | |
object1.scale.z += 1.0f; | |
else if (DIkey == '-') | |
object1.scale.z -= 1.0f; | |
break; | |
case 'c': | |
if (DIkey == '+') | |
object1.scale.y += 1.0f; | |
else if (DIkey == '-') | |
object1.scale.y -= 1.0f; | |
break; | |
case 'i': | |
object1.position.y += 0.1f; | |
break; | |
case 'k': | |
object1.position.y -= 0.1f; | |
break; | |
case 'j': | |
object1.position.x -= 0.1f; | |
break; | |
case 'l': | |
object1.position.x += 0.1f; | |
break; | |
case 'b': | |
if (DIkey == '+') | |
object1.rotate.x += 0.1f; | |
else if (DIkey == '-') | |
object1.rotate.x -= 0.1f; | |
break; | |
case 'n': | |
if (DIkey == '+') | |
object1.rotate.y += 0.1f; | |
else if (DIkey == '-') | |
object1.rotate.y -= 0.1f; | |
break; | |
case 'm': | |
if (DIkey == '+') | |
object1.rotate.z += 0.1f; | |
else if (DIkey == '-') | |
object1.rotate.z -= 0.1f; | |
break; | |
case '1': | |
if (!ifToggleAspect) { | |
ifToggleAspect = GL_TRUE; | |
std::cout << "toggle on aspect ratio" << std::endl; | |
} | |
else { | |
ifToggleAspect = GL_FALSE; | |
std::cout << "toggle off aspect ratio" << std::endl; | |
} | |
break; | |
case '2': | |
if (!ifToggleDClamping) { | |
ifToggleDClamping = GL_TRUE; | |
std::cout << "toggle on Depth Clamping" << std::endl; | |
} | |
else { | |
ifToggleDClamping = GL_FALSE; | |
std::cout << "toggle off Depth Clamping" << std::endl; | |
} | |
break; | |
case '3': | |
if (!ifToggleFCulling) { | |
ifToggleFCulling = GL_TRUE; | |
std::cout << "toggle on Face Culling" << std::endl; | |
} | |
else { | |
ifToggleFCulling = GL_FALSE; | |
std::cout << "toggle off Face Culling" << std::endl; | |
} | |
break; | |
case '4': | |
if (!ifToggleDTest) { | |
ifToggleDTest = GL_TRUE; | |
std::cout << "toggle on Depth Testing" << std::endl; | |
} | |
else { | |
ifToggleDTest = GL_FALSE; | |
std::cout << "toggle off Depth Testing" << std::endl; | |
} | |
break; | |
default: | |
break; | |
} | |
} | |
void Resize(int w, int h) { | |
WindowProperties::width = w; | |
WindowProperties::height = h; | |
glViewport(0, 0, WindowProperties::width, WindowProperties::height); | |
if (ifToggleAspect) { | |
cameraToClipMatrix[0].x = calcFrustumScale(camera.fov) / (WindowProperties::width / WindowProperties::height); | |
cameraToClipMatrix[1].y = calcFrustumScale(camera.fov); | |
} | |
else { | |
cameraToClipMatrix[0].x = calcFrustumScale(camera.fov); | |
cameraToClipMatrix[1].y = calcFrustumScale(camera.fov); | |
} | |
glUseProgram(shaderProgram); | |
glUniformMatrix4fv(cameraToClipMatrixUniformLocation, 1, GL_FALSE, glm::value_ptr(cameraToClipMatrix)); | |
glUseProgram(0); | |
} | |
void initWindow(int *const cp_argn, char **const cp_argc) { | |
glutInit(cp_argn, cp_argc); | |
glutInitContextProfile(GLUT_CORE_PROFILE); | |
glutInitContextVersion(WindowProperties::openGLMAXVERSION, WindowProperties::openGLMINVERSION); | |
glutInitDisplayMode(WindowProperties::displayMode); | |
glutInitWindowSize(WindowProperties::width, WindowProperties::height); | |
glutInitWindowPosition(200, 200); | |
glutCreateWindow(WindowProperties::windowTitle.c_str()); | |
std::cout << "exercise 18 (translation, scale, rotation / orientation, matrix stack)" << std::endl; | |
std::cout << "opening window..." << std::endl; | |
glewExperimental = GLEW_OK; | |
std::cout << "initializing the open gl context" << std::endl; | |
if (glewInit()) { | |
std::cerr << "cannot initialized the contesxt" << std::endl; | |
throw std::runtime_error("error check your drivers"); | |
} | |
std::cout << glGetString(GL_VERSION) << std::endl; | |
std::cout << "successfully initialized" << std::endl; | |
std::cout << "registering callback events " << std::endl; | |
glutReshapeFunc(&Resize); | |
glutDisplayFunc(&Run); | |
glutKeyboardFunc(&KeyEvent); | |
glutMainLoop(); | |
} | |
} | |
int main(int argn, char **argc) | |
{ | |
Window::initWindow(&argn, argc); | |
return EXIT_SUCCESS; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Shader.hpp" | |
namespace Shader { | |
std::string ShaderUtility::loadShaderFile(const std::string &fileName) { | |
std::fstream readFile(fileName, std::fstream::in, std::fstream::trunc); | |
std::string sourceCode, line; | |
if (!readFile) { | |
std::cerr << "cannot load File " << fileName << std::endl; | |
throw std::runtime_error("error cannot load file"); | |
} | |
for (; std::getline(readFile, line);) { | |
sourceCode += line + '\n'; | |
} | |
if (sourceCode[sourceCode.length() - 1] != '\0') | |
sourceCode.push_back('\0'); | |
return sourceCode; | |
} | |
GLuint ShaderUtility::compileShader(const char *sourceCode, const GLenum &shaderType) { | |
GLuint shaderObject = glCreateShader (shaderType); | |
GLint compileStatus; | |
glShaderSource(shaderObject, 1, &sourceCode, nullptr); | |
glCompileShader(shaderObject); | |
glGetShaderiv(shaderObject, GL_COMPILE_STATUS, &compileStatus); | |
if (!compileStatus) { | |
std::string typeOfShader; | |
GLint errorLogLength; | |
glGetShaderiv(shaderObject, GL_INFO_LOG_LENGTH, &errorLogLength); | |
GLchar *errorLog = new GLchar[errorLogLength + 1]; | |
glGetShaderInfoLog(shaderObject, errorLogLength + 1, nullptr, errorLog); | |
switch (shaderType) { | |
case GL_VERTEX_SHADER: | |
typeOfShader = "VERTEX"; | |
break; | |
case GL_FRAGMENT_SHADER: | |
typeOfShader = "FRAGMENT"; | |
break; | |
default: | |
typeOfShader = "NONE"; | |
break; | |
} | |
std::cerr << "error " << typeOfShader << std::endl | |
<< errorLog << std::endl; | |
delete[] errorLog; | |
} | |
return shaderObject; | |
} | |
GLuint ShaderUtility::buildProgram(std::initializer_list <GLuint> shaderObjectList) { | |
GLuint programObject = glCreateProgram(); | |
GLint linkingStatus; | |
for (std::initializer_list <GLuint>::iterator it = shaderObjectList.begin(); it != shaderObjectList.end(); ++it) | |
glAttachShader(programObject, *it); | |
glLinkProgram(programObject); | |
glGetProgramiv(programObject, GL_LINK_STATUS, &linkingStatus); | |
if (!linkingStatus) { | |
GLint errorLogLength; | |
glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &errorLogLength); | |
std::unique_ptr <GLchar> errorLog(new GLchar[errorLogLength + 1]); | |
glGetProgramInfoLog(programObject, errorLogLength + 1, nullptr, errorLog.get()); | |
std::cerr << "LINKING ERROR::" << std::endl | |
<< errorLog.get() << std::endl; | |
} | |
for (std::initializer_list <GLuint>::iterator it2 = shaderObjectList.begin(); it2 != shaderObjectList.end(); ++it2) { | |
glDetachShader(programObject, *it2); | |
glDeleteShader(*it2); | |
} | |
return programObject; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef SHADER_HEADER | |
#define SHADER_HEADER | |
#define GLEW_STATIC | |
#include <GL/glew.h> | |
#include <GL/freeglut.h> | |
#include <fstream> | |
#include <memory> | |
#include <initializer_list> | |
#include <iostream> | |
#include <string> | |
#include <stdexcept> | |
namespace Shader { | |
class ShaderUtility { | |
public: | |
static std::string loadShaderFile(const std::string &); | |
static GLuint compileShader(const char *, const GLenum &); | |
static GLuint buildProgram(std::initializer_list <GLuint>); | |
}; | |
} | |
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version 330 | |
layout (location = 0) in vec4 vertexPositionInput; | |
layout (location = 1) in vec4 vertexColorInput; | |
uniform mat4 cameraToClipMatrix; | |
uniform mat4 modelToCameraMatrix; | |
smooth out vec4 vertexColorOutput; | |
void main () | |
{ | |
vec4 cameraSpace = modelToCameraMatrix * vertexPositionInput; | |
gl_Position = cameraToClipMatrix * cameraSpace; | |
vertexColorOutput = vertexColorInput; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment