Reputation: 6999
I'm trying to draw a triangle on the surface of a window with OpenGL. A black triangle is drawn when I don't use a shader program otherwise it draws nothing. There are no shader compilation errors. I tried to use different versions of GLSL with no success. Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
static const GLfloat g_vertex_buffer_data[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f,
};
unsigned int load_shader(const char *filepath, GLenum type) {
FILE *file = fopen(filepath, "r");
if (file == NULL) {
fprintf(stderr, "Error opening a file %s", filepath);
return -1;
}
fseek(file, 0, SEEK_END);
long size = ftell(file);
fseek(file, 0, SEEK_SET);
GLchar *buf = malloc(sizeof(GLchar) * (size + 1));
if (buf == NULL) {
fprintf(stderr, "Cannot allocate memory");
return -1;
}
fgets(buf, size, file);
fclose(file);
buf[size] = '\0';
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, (const GLchar * const*) &buf, NULL);
glCompileShader(shader);
GLint is_compiled;
char info_log[512];
glGetShaderiv(shader, GL_COMPILE_STATUS, &is_compiled);
if (is_compiled == GL_FALSE) {
glGetShaderInfoLog(shader, 512, NULL, info_log);
fprintf(stderr, "Shader compilation error: %s", info_log);
glDeleteShader(shader);
return -1;
}
return shader;
}
int main() {
if(!glfwInit()) {
fprintf(stderr, "Failed to initialize GLFW\n");
return -1;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow *window = glfwCreateWindow(1024, 768, "Tutorial 01", NULL, NULL);
if (window == NULL) {
fprintf(stderr, "Failed to create a window\n");
glfwTerminate();
return 1;
}
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
return 1;
}
GLuint vertex_shader = load_shader("simple.vert", GL_VERTEX_SHADER);
GLuint fragment_shader = load_shader("simple.frag", GL_FRAGMENT_SHADER);
GLuint shader_program = glCreateProgram();
glAttachShader(shader_program, vertex_shader);
glAttachShader(shader_program, fragment_shader);
glLinkProgram(shader_program);
GLint is_compiled;
char info_log[512];
glGetProgramiv(shader_program, GL_LINK_STATUS, &is_compiled);
if (is_compiled == GL_FALSE) {
glGetProgramInfoLog(shader_program, 512, NULL, info_log);
fprintf(stderr, "Shader program linking error: %s", info_log);
return 1;
}
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
GLuint VertexArrayID, vertexbuffer;
glGenVertexArrays(1, &VertexArrayID);
glGenBuffers(1, &vertexbuffer);
glBindVertexArray(VertexArrayID);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
do {
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shader_program);
glBindVertexArray(VertexArrayID);
glDrawArrays(GL_TRIANGLES, 0, 3);
// glDisableVertexAttribArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
} while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(window) == 0);
glDeleteVertexArrays(1, &VertexArrayID);
glDeleteBuffers(1, &vertexbuffer);
glDeleteProgram(shader_program);
glfwTerminate();
return 0;
}
simple.vert
#version 450 core
layout (location = 0) in vec3 aPos;
void main() {
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}
simple.frag
#version 450 core
void main() {
gl_FlagColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}
Upvotes: 0
Views: 130
Reputation: 22166
You are not reading your whole shader file but just the first line. fgets
stops reading when either (n-1) characters are read, the newline character is read, or the end-of-file is reached, whichever comes first. source
If you want to read the whole file, use, for example, fread
as described in this post: How to read the content of a file to a string in C?
There is also a typo in your fragment shader. gl_FlagColor
should be gl_FragColor
.
Upvotes: 1