I am learning opengl and the following code is displaying a blank screen when using glm 0.9.9.8, but it works correctly using 0.9.8.5. The expected behavior is to display a triangle moving left to right. The translation happens both way, because I print the offset.
#include <stdio.h>
#include <string.h>
#include <cmath>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
// Window dimensions
const GLint WIDTH = 800, HEIGHT = 600;
GLuint VAO, VBO, shader, uniformModel;
bool direction = true;
float triOffset = 0.0f;
float triMaxOffset = 0.7f;
float triIncrement = 0.005f;
// Vertex Shader
static const char* vShader = " \n\
#version 330 \n\
\n\
layout (location = 0) in vec3 pos; \n\
uniform mat4 model; \n\
\n\
void main() \n\
{ \n\
gl_Position = model * vec4(0.4 * pos.x, 0.4 * pos.y, pos.z, 1.0); \n\
}";
// Fragment Shader
static const char* fShader = " \n\
#version 330 \n\
\n\
out vec4 color; \n\
\n\
void main() \n\
{ \n\
color = vec4(1.0, 0.0, 0.0, 1.0); \n\
}";
void CreateTriangle()
{
GLfloat vertices[] =
{
-1.0f, -1.0f, 0.0f, // Lower left corner
1.0f, -1.0f, 0.0f, // Lower right corner
0.0f, 1.0f, 0.0f // Top corner
};
// Create vertex array object
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
// Create vertex buffer object
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
// Copy vertices to buffer
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// Specify attribute pointer
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
// Unbind VBO and VAO
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void AddShader(GLuint theProgram, const char* shaderCode, GLenum shaderType)
{
// Create shader object
GLuint theShader = glCreateShader(shaderType);
// Create shader source
const GLchar* theCode[1];
theCode[0] = shaderCode;
GLint codeLength[1];
codeLength[0] = strlen(shaderCode);
// Compile shader
glShaderSource(theShader, 1, theCode, codeLength);
glCompileShader(theShader);
// Check for errors
GLint result = 0;
GLchar eLog[1024] = { 0 };
glGetShaderiv(theShader, GL_COMPILE_STATUS, &result);
if (!result)
{
glGetShaderInfoLog(theShader, sizeof(eLog), NULL, eLog);
printf("Error compiling the %d shader: '%s'\n", shaderType, eLog);
return;
}
// Attach shader to program
glAttachShader(theProgram, theShader);
}
void CompileShaders() {
shader = glCreateProgram();
if (!shader) {
printf("Error creating shader program!\n");
return;
}
AddShader(shader, vShader, GL_VERTEX_SHADER);
AddShader(shader, fShader, GL_FRAGMENT_SHADER);
GLint result = 0;
GLchar eLog[1024] = { 0 };
// Link program
glLinkProgram(shader);
glGetProgramiv(shader, GL_LINK_STATUS, &result);
if (!result)
{
glGetProgramInfoLog(shader, sizeof(eLog), NULL, eLog);
printf("Error linking program: '%s'\n", eLog);
return;
}
// Validate program
glValidateProgram(shader);
glGetProgramiv(shader, GL_VALIDATE_STATUS, &result);
if (!result)
{
glGetProgramInfoLog(shader, sizeof(eLog), NULL, eLog);
printf("Error validating program: '%s'\n", eLog);
return;
}
uniformModel = glGetUniformLocation(shader, "model");
}
int main()
{
// Initialize GLFW
if (!glfwInit())
{
printf("GLFW initialization failed!");
glfwTerminate();
return 1;
}
// Setup GLFW window properties
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
// Core profile = No Backwards Compatibility
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
// Create the window
GLFWwindow *mainWindow = glfwCreateWindow(WIDTH, HEIGHT, "Test Window", NULL, NULL);
if (!mainWindow)
{
printf("GLFW window creation failed!");
glfwTerminate();
return 1;
}
// Get buffer size information
int bufferWidth, bufferHeight;
glfwGetFramebufferSize(mainWindow, &bufferWidth, &bufferHeight);
// Set context for GLEW to use
glfwMakeContextCurrent(mainWindow);
// Allow modern extension features
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
{
printf("GLEW initialization failed!");
glfwDestroyWindow(mainWindow);
glfwTerminate();
return 1;
}
// Create viewport
glViewport(0, 0, bufferWidth, bufferHeight);
CreateTriangle();
CompileShaders();
// Loop until window closed
while (!glfwWindowShouldClose(mainWindow))
{
if (direction)
{
triOffset += triIncrement;
}
else
{
triOffset -= triIncrement;
}
if (abs(triOffset) >= triMaxOffset)
{
direction = !direction;
}
printf("%f\n", triOffset);
// Clear window
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Color
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shader);
glm::mat4 model;
model = glm::translate(model, glm::vec3(triOffset, 0.0f, 0.0f));
glUniformMatrix4fv(uniformModel, 1, GL_FALSE, glm::value_ptr(model));
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glUseProgram(0);
glfwSwapBuffers(mainWindow);
}
return 0;
}
I am using glfw-3.3.8.bin.WIN32 and glew-2.2.0-win32