Reputation: 509
So I'm learning OpenGL and GLSL (obviously). I've followed several tutorials religiously on matrix transformations, but I can't figure out why the square isn't rendering. I've figured out through trial and error that my rendering code is fine, it's just when I do "transformation * vec4(...)" in the vertex shader that the program messes up. I checked the returned value of glGetUniformLocation and I got a return value of 0, so it's getting the location of the uniform. I've looked around and I haven't found a solution.
#include <stdio.h>
#include <memory.h>
#include <stdlib.h>
#define GLEW_STATIC
#include <glew.h>
#include <SDL.h>
#include <math.h>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>
const GLchar* VertShaderCode = "\
#version 330 core\n\
layout (location = 0) in vec2 position;\n\
uniform mat4 transformation;\n\
void main ()\n\
{\n\
vec4 lol = transformation * vec4(position.xy, 0, 1);\n\
gl_Position = lol;\n\
}\n\
";
const GLchar* FragShaderCode = "\
#version 330 core\n\
void main ()\n\
{\n\
gl_FragColor = vec4(1, 0, 1, 1);\n\
}\n\
";
#define SDL_main main
#define scuffed !SDL_QuitRequested()
int main()
{
if (SDL_Init(SDL_INIT_EVERYTHING))
{
printf("Could not initialize SDL!\n");
return -4;
};
SDL_Window* window = SDL_CreateWindow("Testing Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 420, 420, SDL_WINDOW_OPENGL);
if (!window)
{
printf("Could not create window!\n");
return -5;
};
SDL_GLContext context = SDL_GL_CreateContext(window);
if (!context)
{
printf("Could not create context!\n");
return -7;
};
if (glewInit() != GLEW_OK)
{
printf("Could not initialize GLEW!\n");
return -6;
};
GLint err;
char* log = NULL;
//printf("Vertex Shader Source: \n%s\n",VertShaderCode);
GLuint VertShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(VertShader,1,&VertShaderCode,NULL);
glCompileShader(VertShader);
glGetShaderiv(VertShader,GL_COMPILE_STATUS,&err);
if (err == GL_FALSE)
{
// Shader didn't compile.
glGetShaderiv(VertShader, GL_INFO_LOG_LENGTH, &err);
log = (char*)malloc(err);
glGetShaderInfoLog(VertShader,err,NULL,log);
printf("Vertex shader could not be compiled!\n\n%s\n\n",log);
return -1;
};
//printf("Fragment Shader Source: \n%s\n", FragShaderCode);
GLuint FragShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(FragShader, 1, &FragShaderCode, NULL);
glCompileShader(FragShader);
glGetShaderiv(FragShader, GL_COMPILE_STATUS, &err);
if (err == GL_FALSE)
{
// Shader didn't compile.
glGetShaderiv(FragShader, GL_INFO_LOG_LENGTH, &err);
log = (char*)malloc(err);
glGetShaderInfoLog(FragShader, err, NULL, log);
printf("Fragment shader could not be compiled!\n\n%s\n\n", log);
return -2;
};
GLuint Program = glCreateProgram();
glAttachShader(Program,VertShader);
glAttachShader(Program,FragShader);
glLinkProgram(Program);
glGetProgramiv(Program,GL_LINK_STATUS,&err);
if (err == GL_FALSE)
{
// Program didn't link.
glGetProgramiv(Program,GL_INFO_LOG_LENGTH,&err);
log = (char*)malloc(err);
glGetProgramInfoLog(Program,err,NULL,log);
printf("Program could not be linked!\n\n%s\n\n",log);
return -3;
};
glUseProgram(Program);
GLuint vertBuff = 0, arrayBuff = 0, elementBuff = 0;
glGenVertexArrays(1, &arrayBuff);
glGenBuffers(1, &vertBuff);
glGenBuffers(1, &elementBuff);
glBindVertexArray(arrayBuff);
glBindBuffer(GL_ARRAY_BUFFER, vertBuff);
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuff);
GLfloat vertices[] =
{
-0.5, 0.5,
-0.5, -0.5,
0.5, -0.5,
0.5, -0.5,
-0.5, 0.5,
0.5, 0.5,
};
GLubyte colors[] =
{
255,0,0,
0,255,0,
0,0,255
};
GLuint indicies[] =
{
0, 1, 2,
2, 0, 3,
};
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glm::mat4 mat = glm::scale(mat, glm::vec3(2, .5, 0));
glUniformMatrix4fv(glGetUniformLocation(Program, "transformation"), 1, GL_FALSE, glm::value_ptr(mat));
while (scuffed)
{
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 6);
SDL_GL_SwapWindow(window);
}
glDeleteVertexArrays(1, &arrayBuff);
glDeleteBuffers(1, &vertBuff);
//glDeleteBuffers(1, &elementBuff);
SDL_GL_DeleteContext(context);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Upvotes: 0
Views: 116
Reputation: 22162
The problem is not the code in the shader, but the data you pass to transformation
:
glm::mat4 mat = glm::scale(mat, glm::vec3(2, .5, 0));
The glm::scale function
multiplies a new scaling function to the mat
you pass in. The problem is, that mat
is not initialized when you pass it to scale
and contains just some random garbage. What you actually want is to initialize the matrix first (as an identity matrix, but that's the default behavior), and then pass it to scale:
glm::mat4 mat;
mat = glm::scale(mat, glm::vec3(2, .5, 0));
Note, that these two version are not equivalent in c++ since the first version doesn't call the constructor of mat
before passing it to the function.
Upvotes: 2