I was trying to draw a Triangle with a custom FragmentShader for a gradient effect on the triangle.
I was trying to use Indexed-Drawing instead of Drawing Arrays.
Although glDrawArrays(...)
works just fine, glDrawElements(...)
doesn't work for me. I just get a blank screen with indexed-drawing as opposed to a normal output (Screenshots are attached below).
Could someone tell me where I'm going wrong?
(Here's my code)
#include <iostream>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
// Vertex Shader source code
const char* vertexShaderSource =
"#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"layout (location = 1) in vec3 aColor;\n"
"out vec3 outColor;\n"
"void main() {\n"
" gl_Position = vec4(aPos, 1.0);\n"
" outColor = aColor;\n"
"}\n\0";
// Fragment Shader source code
const char* fragmentShaderSource =
"#version 330 core\n"
"out vec4 FragColor;\n"
"in vec3 outColor;\n"
"void main() {\n"
" FragColor = vec4(outColor, 1.0f);\n"
"}\n\0";
const int width{ 800 };
const int height{ 600 };
bool WIREFRAME_MODE = false;
int main() {
glfwInit();
#pragma region Creating a Window
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(width, height, "Triangle Exercise", nullptr, nullptr);
if (!window) {
std::cout << " >> Failed to create window!" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
#pragma endregion
gladLoadGL();
glViewport(0, 0, width, height);
#pragma region Shader Compilation
// Vertex Shader
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
glCompileShader(vertexShader);
// Fragment Shader
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
glCompileShader(fragmentShader);
// Shader Program
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
// Delete the shaders
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
#pragma endregion
#pragma region Vertex and Index data
// Vertex data
GLfloat vertices[] = {
// positions // colors
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // bottom left
0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // top
};
// Index data
GLuint indices[] = {
0, 1, 2
};
#pragma endregion
#pragma region VAO, VBO and EBO
GLuint VAO; // Vertex Attribute Object ref
GLuint VBO; // Vertex Buffer Object ref
GLuint EBO; // Element Buffer Object ref
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// Point to the X,Y,Z vertex data in the VBO (at layout location 0)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * (sizeof(GLfloat)), (void*)0);
glEnableVertexAttribArray(0);
// Point to the RGB color data in the VBO (at layout location 1)
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * (sizeof(GLfloat)), (void*)(3*sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0); // unbind VBO
glBindVertexArray(0); // unbind VAO
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // unbind EBO (conatined in VAO)
#pragma endregion
// While window isn't closed
while (!glfwWindowShouldClose(window)) {
if (WIREFRAME_MODE) {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // Wireframe mode
}
else {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // Fill mode
}
glClearColor(0, 0, 0, 1); // black background
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
// WORKS FINE
glDrawArrays(GL_TRIANGLES, 0, sizeof(vertices) / sizeof(GLfloat));
// DOESN'T WORK?
//
//glDrawElements(GL_TRIANGLES, sizeof(indices)/sizeof(GLuint), GL_UNSIGNED_INT, indices);
//
glfwSwapBuffers(window);
glfwPollEvents();
}
#pragma region Cleanup
glDeleteProgram(shaderProgram);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &VAO);
glDeleteBuffers(1, &EBO);
glfwDestroyWindow(window);
#pragma endregion
glfwTerminate();
return 0;
}
Output screenshot with glDrawArrays()
:
Output screenshot with glDrawElements()
:
I tried checking if my EBO's parameters were wrong, but they seem fine to me.