Reputation: 665
This is my code written in C++ that is supposed to produce 2 triangles, however I am getting a blank screen. Is there something I am missing?
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <glm/vec3.hpp> // glm::vec3
#include <glm/vec4.hpp> // glm::vec4
#include <glm/mat4x4.hpp> // glm::mat4
#include <glm/gtc/matrix_transform.hpp> // glm::translate, glm::rotate, glm::scale, glm::perspective
using namespace std;
static string ParseShader(string filepath) {
ifstream stream(filepath);
string line;
stringstream stringStream;
while (getline(stream, line))
{
stringStream << line << '\n';
}
return stringStream.str();
}
static unsigned int CompileShader(unsigned int type, const string& source) {
unsigned int id = glCreateShader(type);
const char* src = source.c_str(); // this returns a pointer to data inside the string, the first character
glShaderSource(id, 1, &src, nullptr); // shader id, count of source codes, a pointer to the array that holds the strings
glCompileShader(id);
int result;
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
if (result == GL_FALSE) {
int length;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
char* message = (char*)alloca(length * sizeof(char));
glGetShaderInfoLog(id, length, &length, message);
cout << type << endl;
cout << message << endl;
glDeleteShader(id);
return 0;
}
return id;
}
// takes the shader codes as a string parameters
static unsigned int CreateShader(const string& vertexShader, const string& fragmentShader)
{
GLuint program = glCreateProgram();
unsigned int vs = CompileShader(GL_VERTEX_SHADER, vertexShader);
unsigned int fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader);
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glValidateProgram(program); // validate if the program is valid and can be run in the current state of opengl
glDeleteShader(vs);
glDeleteShader(fs);
return program;
}
int main(void)
{
GLFWwindow* window;
float Angle = 0;
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
// call glewInit after creating the context...
GLenum err = glewInit();
if (GLEW_OK != err)
{
/* Problem: glewInit failed, something is seriously wrong. */
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
}
GLfloat coordinates[12] = {
-0.5f, 0.5f,
0.0f, 0.5f,
0.5f, 0.5f,
-0.5f, -0.5f,
0.0f, -0.5f,
0.5f, -0.5f
};
GLuint indices[6] = { 0, 3, 1, 4, 2, 5 };
GLuint position_buffer;
glGenBuffers(1, &position_buffer);
glBindBuffer(GL_ARRAY_BUFFER, position_buffer);
glBufferData(GL_ARRAY_BUFFER, 6 * 2 * sizeof(float), coordinates, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0); //vertex positions
glEnableVertexAttribArray(0);
GLuint index_buffer;
glGenBuffers(1, &index_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(GLuint), indices, GL_STATIC_DRAW);
string vertexSource = ParseShader("vertex.shader");
string fragmentSource = ParseShader("fragment.shader");
unsigned int program = CreateShader(vertexSource, fragmentSource);
glUseProgram(program);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
// Render here
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawElements(GL_TRIANGLE_STRIP, 6, GL_UNSIGNED_INT, nullptr);
//Swap front and back buffers
glfwSwapBuffers(window);
// Poll for and process events
glfwPollEvents();
}
glDeleteProgram(program);
glfwTerminate();
return 0;
}
This is my vertex shader.
#version 330 core
layout(location = 0) in vec4 position;
layout(location = 1) in vec4 color;
out vec4 var_color;
void main()
{
var_color = color;
gl_Position = position;
};
And here is my fragment shader.
#version 330 core
out vec4 color;
in vec4 var_color;
void main()
{
//color = vec4(1.0f, 0.0f, 0.0f, 1.0f);
color = var_color;
//discard;
};
I get a black screen as a result, I doubt this is an issue with my machine as other code snippets worked on it.
Upvotes: 2
Views: 1439
Reputation: 3812
The code shouldn't produce two triangles, as it is asked to render a triangle strip. The first three vertices define one triangle and each subsequent vertex adds another triangle for a total of 4 triangles.
The blank screen you're getting is the result of the vertex shader being sent 2D positions and interpreting them as 4D positions, as well as no color information being present.
To resolve these issues:
The vertex shader should receive a vec2
for the positions, since these are given in 2D:
layout(location = 0) in vec2 position;
Then convert these to 4D for gl_Position
:
gl_Position = vec4(position, 0.0f, 1.0f);
The definition of the colors, setting up the corresponding buffer and uploading of the color data was missing. For example, add:
GLfloat colors[24] = {
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f,
0.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
};
GLuint color_buffer;
glGenBuffers(1, &color_buffer);
glBindBuffer(GL_ARRAY_BUFFER, color_buffer);
glBufferData(GL_ARRAY_BUFFER, 6 * 4 * sizeof(float), colors, GL_STATIC_DRAW);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 4, 0);
glEnableVertexAttribArray(1);
The result:
Upvotes: 2
Reputation: 3264
Colors are not specified in the provided code. The shader are most probably drawing black squares because of the value already in memory when you execute the program. To add colors, use this code:
GLfloat colors[24] = { // Random colors
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
};
GLuint color_buffer;
glGenBuffers(1, &color_buffer);
glBindBuffer(GL_ARRAY_BUFFER, color_buffer);
glBufferData(GL_ARRAY_BUFFER, 6 * 4 * sizeof(float), colors, GL_STATIC_DRAW);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 4, 0); //vertex colors
glEnableVertexAttribArray(1);
Upvotes: 3