Reputation: 21
So I've been trying to learn OpenGL lately, following several text and video tutorials.
I cant get the triangle to draw, I've double and triple checked that I'm preforming all the necessary steps in the right order, but I'm obviously missing something
before adding some of the code I should state that im using glfw, glad and ogl 4.6.
Main.cpp
//while debugging ive add extra unnecessary call to UseProgram and bindvertexarray every frame to be sure
static void Render(GLFWwindow* window)
{
glfwMakeContextCurrent(window);
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
glfwSwapInterval(1);
glClearColor(.98f, .5f, .5f, 1);
std::vector<Vertex> vertsTri = {
{
Vertex(0.0f,1.0f,0.0f,0,0,0,0,0)
},
{
Vertex(-1.0f,-1.0f,0.0f,0,0,0,0,0)
},
{
Vertex(1.0f,-1.0f,0.0f,0,0,0,0,0)
}
};
Model tri(vertsTri, "basic");
tri.UseProgram();
glBindVertexArray(tri.getVAO());
while (!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT);
// rendering here
tri.UseProgram();
glBindVertexArray(tri.getVAO());
glDrawArrays(GL_TRIANGLES, 0, tri.size());
glfwSwapBuffers(window);
}
}
int main()
{
glfwSetErrorCallback(errorCallback);
if (!glfwInit())
exit(EXIT_FAILURE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(800, 600, "Title", nullptr, nullptr);
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwSetFramebufferSizeCallback(window, windowResizeCallback);
glfwSetKeyCallback(window, keyCallback);
// Resource loading and creation in here
std::thread renderThread(Render, window);
while (!glfwWindowShouldClose(window))
{
// Realtime game mechanics here
glfwPollEvents();
}
if (renderThread.joinable())
renderThread.join();
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}
Model.cpp
//Gets called in the constructor with a Vertex vector, p_shader is created in Model constructor
void Model::Create()
{
// Generate a vertex array object and bind it
glGenVertexArrays(1, &p_vaoId);
glBindVertexArray(p_vaoId);
// Generate a vertex buffer object and bind it
glGenBuffers(1, &p_vboId);
glBindBuffer(GL_ARRAY_BUFFER, p_vboId);
glBufferData(GL_ARRAY_BUFFER, p_vertices.size()*sizeof(Vertex), &(p_vertices[0]), GL_STATIC_DRAW);
// Define attributes and enable them
glEnableVertexArrayAttrib(p_vaoId, 0);
glVertexAttribPointer(0, sizeof(Vertex::position) / sizeof(float), GL_FLOAT, false, sizeof(Vertex::position), (void*)offsetof(Vertex, position));
glEnableVertexArrayAttrib(p_vaoId, 1);
glVertexAttribPointer(1, sizeof(Vertex::normal) / sizeof(float), GL_FLOAT, false, sizeof(Vertex::normal), (void*)offsetof(Vertex, normal));
glEnableVertexArrayAttrib(p_vaoId, 2);
glVertexAttribPointer(2, sizeof(Vertex::uv) / sizeof(float), GL_FLOAT, false, sizeof(Vertex::uv), (void*)offsetof(Vertex, uv));
}
Shader.cpp
// p_v/fShaderSource is set in LoadSource, while debugging ive made sure the source is gotten correctly
void Shader::Create()
{
int errorResult = 0;
// Load shader sources into memory before anything else
LoadSource();
// Creating shader objects
p_vShaderId = glCreateShader(GL_VERTEX_SHADER);
p_fShaderId = glCreateShader(GL_FRAGMENT_SHADER);
// Compile the shaders
Compile(p_vShaderId, p_vShaderSource);
Compile(p_fShaderId, p_fShaderSource);
// Create a program object
p_programId = glCreateProgram();
// Attach shaders to the program
glAttachShader(p_programId, p_vShaderId);
glAttachShader(p_programId, p_fShaderId);
//Link the program and handle errors
glLinkProgram(p_programId);
glGetProgramiv(p_programId, GL_LINK_STATUS, &errorResult);
if (!errorResult)
{
int length;
glGetShaderiv(p_programId, GL_INFO_LOG_LENGTH, &length);
char* log = new char[length];
glGetProgramInfoLog(p_programId, length, &length, log);
std::cout << "[Link Error] Failed to link program" << std::endl;
std::cout << log << std::endl;
delete log;
glDeleteShader(p_vShaderId);
glDeleteShader(p_fShaderId);
}
// Validate the program and handle errors
glValidateProgram(p_programId);
glGetProgramiv(p_programId, GL_VALIDATE_STATUS, &errorResult);
if (!errorResult)
{
int length;
glGetShaderiv(p_programId, GL_INFO_LOG_LENGTH, &length);
char* log = new char[length];
glGetProgramInfoLog(p_programId, length, &length, log);
std::cout << "[Validate Error] Failed to validate program" << std::endl;
std::cout << log << std::endl;
delete log;
glDeleteShader(p_vShaderId);
glDeleteShader(p_fShaderId);
glDeleteProgram(p_programId);
}
// Cleanup shaders after linking and validating
glDetachShader(p_programId, p_vShaderId);
glDetachShader(p_programId, p_fShaderId);
glDeleteShader(p_vShaderId);
glDeleteShader(p_fShaderId);
}
void Shader::Compile(unsigned int& shaderId, std::string source)
{
int compileResult = 0;
const char* csource = (const char*)source.c_str();
glShaderSource(shaderId, 1, &csource, 0);
glCompileShader(shaderId);
glGetShaderiv(shaderId, GL_COMPILE_STATUS, &compileResult);
if (!compileResult)
{
int length;
glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &length);
char* log = new char[length];
glGetShaderInfoLog(shaderId, length, &length, log);
std::cout << "[Compile Error] Failed to compile shader - \"" + source + "\""<< std::endl;
std::cout << log << std::endl;
delete log;
}
}
basic.vert
#version 460 core
layout(location = 0) in vec3 position;
out vec4 fColor;
void main()
{
gl_Position.xyz = position;
gl_Position.w = 1.0;
fColor = vec4(gl_Position.xyz, 1.0);
}
basic.frag
#version 460 core
in vec4 fColor;
layout(location = 0) out vec4 diffuseColor;
void main()
{
diffuseColor = vec4(1,0,0,0);
}
I've removed some of the class specific code that doesnt perform any ogl calls, if that make it too hard to diagnose i could add the entire code, as its not too bad. I've tried multiple styles of out color in the fragment shader and non of the ones ive tried have worked, with that said though, let me know if you believe that problem is indeed in the fragment shader.
Upvotes: 0
Views: 127
Reputation: 21
pointed by @datemwolf: problem was with the stride parameter that was passed to glVertexAttribPointer
From:
glVertexAttribPointer(0, sizeof(Vertex::position) / sizeof(float), GL_FLOAT, false, sizeof(Vertex::position), (void*)offsetof(Vertex, position));
glVertexAttribPointer(1, sizeof(Vertex::normal) / sizeof(float), GL_FLOAT, false, sizeof(Vertex::normal), (void*)offsetof(Vertex, normal));
glVertexAttribPointer(2, sizeof(Vertex::uv) / sizeof(float), GL_FLOAT, false, sizeof(Vertex::uv), (void*)offsetof(Vertex, uv));
To:
glVertexAttribPointer(0, sizeof(Vertex::position) / sizeof(float), GL_FLOAT, false, sizeof(Vertex), (void*)offsetof(Vertex, position));
glVertexAttribPointer(1, sizeof(Vertex::normal) / sizeof(float), GL_FLOAT, false, sizeof(Vertex), (void*)offsetof(Vertex, normal));
glVertexAttribPointer(2, sizeof(Vertex::uv) / sizeof(float), GL_FLOAT, false, sizeof(Vertex), (void*)offsetof(Vertex, uv));
Upvotes: 1