As the title says, I'm trying to draw a square from two triangles for class. I've tried everything I can think of but I cannot figure out why it just displays a black screen. Here is my code so far. I have the project and libraries set up correctly. I've looked over it a dozen times and can't seem to find the issue.
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
static unsigned int CompileShader(unsigned int type, const std::string& source) {
unsigned int id = glCreateShader(type);
const char* src = source.c_str();
glShaderSource(id, 1, &src, nullptr);
glCompileShader(id);
return id;
}
static unsigned int CreateShader(const std::string& vrtxShader, const std::string& fragShader) {
unsigned int program = glCreateProgram();
//compile shaders
unsigned int vs = CompileShader(GL_VERTEX_SHADER, vrtxShader);
unsigned int fs = CompileShader(GL_FRAGMENT_SHADER, fragShader);
//attach shaders to program
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
//delete shaders
glDeleteShader(vs);
glDeleteShader(fs);
return program;
}
int main(void)
{
GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
return -1;
//sets up GLFW
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "Module 3", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
//Initialize GLEW
if (glewInit() != GLEW_OK)
std::cout << "Error!" << std::endl;
float vertPositions[] = {
// index 0
-0.5f, -0.5f, 0.0f,
1.0f, 0.0f, 0.0f,
// index 1
-5.0f, 0.5f, 0.0f,
0.0f, 0.0f, 1.0f,
// index 2
0.5f, -0.5f, 0.0f,
0.0f, 1.0f, 0.0f,
// index 3
0.5f, 0.5f, 0.0f,
1.0f, 0.0f, 0.0f,
};
float indices[] = { 0, 1, 2, 1, 2, 3 };
//creates vertex buffer object
unsigned int vbo;
unsigned int ebo;
glGenBuffers(1, &vbo);
glGenBuffers(1, &ebo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertPositions), vertPositions, GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
//attribute location and layout to gpu.
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (const void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (const void*)(3 * sizeof(float)));
// Vertex Shader Program Source Code
std::string vertexShaderSource = "#version 440 core\n"
"layout (location = 0) in vec4 aPos;\n"
"layout (location = 1) in vec4 aColor;\n"
"out vec4 colorOut;\n"
"void main()\n"
"{\n"
" gl_Position = aPos;\n"
" colorOut = aColor;\n"
"}\n\0";
// Fragment Shader Program Source Code
std::string fragmentShaderSource = "#version 440 core\n"
"in vec4 colorOut;\n"
"out vec4 fragColor;\n"
"void main()\n"
"{\n"
"fragColor = colorOut;\n"
"}\n\0";
unsigned int shader = CreateShader(vertexShaderSource, fragmentShaderSource);
glUseProgram(shader);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClear(GL_COLOR_BUFFER_BIT);
//draw the shapes
glDrawElements(GL_TRIANGLES, 6, GL_FLOAT, nullptr);
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
CodePudding user response:
Why using a core profile OpenGL Context (GLFW_OPENGL_CORE_PROFILE
) it is mandatory to create a Vertex Array Object. There is no default VAO when using a core profile.
e.g.:
unsigned int vao, vbo, ebo;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &vbo);
glGenBuffers(1, &ebo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertPositions), vertPositions, GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (const void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (const void*)(3 * sizeof(float)));
Further more the type of the indices must be integral. e.g:
unsigned int indices[] = { 0, 1, 2, 1, 2, 3 };
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);