I have been following this tutorial to try and start learning OpenGL. However, upon compiling my code, my triangle turns out to be black. At first I thought that there was something wrong with the fragment shader, but when I tried hard-coding x-values for the vertex shader, I noticed that it had no effect (notice the 0.7f x-value on the vertex shader).
main.cpp
#define GLFW_DLL
#include <iostream>
#include <fstream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
GLfloat verticies[] = {
-1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
1.0f, -1.0f, 0.0f
};
// Objects
GLuint VBO;
GLuint VAO;
GLuint vertShader;
GLuint fragShader;
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
std::string readFile(const char* filePath)
{
std::string content;
std::ifstream fileStream(filePath);
if(!fileStream.is_open())
{
std::cout << "Failed to open " << filePath << "." << std::endl;
return "";
}
std::string line = "";
while(!fileStream.eof())
{
std::getline(fileStream, line);
content.append(line + "\n");
}
fileStream.close();
return content;
}
void createShader(const GLenum shaderType, const char* shaderPath, GLuint& shaderObject)
{
// Create the shader.
shaderObject = glCreateShader(shaderType);
// Read the shader code from the shader file.
const GLchar* shaderCode = readFile(shaderPath).c_str();
// DEBUG:
std::cout << shaderCode << std::endl;
// Assign the shader code to the shader object.
glShaderSource(shaderObject, 1, &shaderCode, NULL);
// Compile the shader.
glCompileShader(shaderObject);
// Check to see if it compiled successfully.
GLint success;
GLchar infoLog[512];
glGetShaderiv(shaderObject, GL_COMPILE_STATUS, &success);
if(!success)
{
glGetShaderInfoLog(shaderObject, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n"
<< infoLog
<< std::endl;
}
}
int main(int argc, char *argv[])
{
// Initialize GLFW.
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
// Create OpenGL window. Exit if fails.
GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", nullptr, nullptr);
if (window == nullptr)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
// Make window current
glfwMakeContextCurrent(window);
// Initialize GLEW.
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
{
std::cout << "Failed to initialize GLEW" << std::endl;
return -1;
}
// Set viewport size and position.
glViewport(0, 0, 800, 600);
// Set callback functions.
glfwSetKeyCallback(window, key_callback);
// Set clear color state.
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
// Create vertex and fragment shaders.
createShader(GL_VERTEX_SHADER, "../src/shaders/vertex.vert", vertShader);
createShader(GL_FRAGMENT_SHADER, "../src/shaders/fragment.frag", fragShader);
// Attach then link shaders
GLuint shaderProgram;
glAttachShader(shaderProgram, vertShader);
glAttachShader(shaderProgram, fragShader);
glLinkProgram(shaderProgram);
// Delete the shaders
glDeleteShader(vertShader);
glDeleteShader(fragShader);
// Check if it succeeded.
GLint linkSucceeded;
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &linkSucceeded);
if(!linkSucceeded)
{
GLchar infoLog[512];
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINK_FAILED\n"
<< infoLog
<< std::endl;
}
// Generate the VAO and bind it.
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
// Create VBO and bind to it.
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
// Send verticies to buffer's memory.
glBufferData(GL_ARRAY_BUFFER, sizeof(verticies), verticies, GL_STATIC_DRAW);
// Set up vertex attributes
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
// Unbind VBO
glBindBuffer(GL_ARRAY_BUFFER, 0);
// Unbind VAO
glBindVertexArray(0);
// Game loop.
while(!glfwWindowShouldClose(window))
{
// Get input.
glfwPollEvents();
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
// Swap buffers.
glfwSwapBuffers(window);
}
// De-allocate resources.
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
// Terminate and close.
glfwTerminate();
return 0;
}
Vertex Shader
#version 330 core
layout(location = 0) in vec3 position;
void main()
{
gl_Position = vec4(0.7f, position.y, position.z, 1.0f);
}
Fragment Shader
#version 330 core
out vec4 color;
void main()
{
color = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}