Reputation: 139
I am learning openGL in C++ and I got to the point where I could draw a triangle. I decided to put the creation of the triangle into a class so that all the code wasn't just in one file and now when I execute the draw function nothing happens. I've been looking through this code for a while now I can't figure out why this happens.
The program dosen't crash it just draws a black background. Also OpenGL does not return any errors.
Here is my main function:
int main(int argc, char* args[]){
GLrenderer renderer;
setRendererSettings(&renderer);
renderer.init();
//triangle tri = createTriangle();
//compileShaders();
glslShader triangle("VertexShader.glsl", "FragShader.glsl");
std::vector<GLfloat> vertices = {
-1.0f, -1.0f, 0.0f,
-1.0f, 1.0f, 0.0f,
1.0f, -1.0f, 0.0f
};
triangle.createShape(vertices);
triangle.compileShaders();
while(renderer.shouldRun()){
input(&renderer);
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
triangle.draw();
renderer.swapBuffers();
}
renderer.destroy();
return 0;
}
Here is my GLrenderer header
class GLrenderer {
private:
SDL_Window* window;
SDL_GLContext GLcontext;
bool isRunning = false;
bool initSDL();
bool initGL();
public:
GLrenderer();
int width = 1, height = 1;
int winX = 0, winY = 0;
int versionMajor = 3, versionMinor = 3;
const char* title = "OpenGL window";
Uint32 flags = SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN;
bool init();
bool shouldRun();
void setShouldRun(bool value);
void destroy();
void swapBuffers();
SDL_Window* getWindow();
};
The source for GLrenderer
GLrenderer::GLrenderer() {}
bool GLrenderer::init(){
if(!initSDL()) return false;
if(!initGL()) return false;
isRunning = true;
return true;
}
bool GLrenderer::initSDL(){
if(SDL_Init(SDL_INIT_EVERYTHING) < 0){
printf("Failed to init SDL.\n");
return false;
}
window = SDL_CreateWindow(
title,
winX, winY,
width, height,
flags
);
if(window == NULL){
printf("Failed to create SDL_Window.\n");
return false;
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, versionMajor);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, versionMinor);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
GLcontext = SDL_GL_CreateContext(window);
if(!GLcontext){
printf("Failed to create OpenGl context.\n");
return false;
}
SDL_GL_MakeCurrent(window, GLcontext);
return true;
}
bool GLrenderer::initGL(){
glewExperimental = GL_TRUE;
if(glewInit() != GLEW_OK){
printf("Failed to init glew.\n");
return false;
}
return true;
}
bool GLrenderer::shouldRun(){
return isRunning;
}
void GLrenderer::setShouldRun(bool value){
isRunning = value;
}
void GLrenderer::destroy(){
SDL_DestroyWindow(window);
SDL_GL_DeleteContext(GLcontext);
SDL_Quit();
}
SDL_Window* GLrenderer::getWindow(){
return window;
}
void GLrenderer::swapBuffers(){
SDL_GL_SwapWindow(window);
}
Header for my class im using to create the triangle
class glslShader;
std::string readShader(std::string file);
class glslShader {
private:
GLuint ShaderProgram, VAO, VBO;
std::string vertexFile, fragFile;
public:
glslShader(std::string _vertexFile, std::string _fragFile);
void createShape(std::vector<GLfloat> vertices);
bool compileShaders();
void draw();
};
And finally the source for that header
bool fileExsists(std::string file){
std::fstream test(file);
return test.good();
}
std::string readShader(std::string file){
if(!fileExsists(file)){
printf("Not able to locate shader\n");
return "";
}
const int maxLine = 130;
std::string shader = "";
std::fstream shaderFile(file);
while(!shaderFile.eof()){
char line[maxLine];
shaderFile.getline(line, 130);
shader += line;
shader += "\n";
}
return shader;
}
glslShader::glslShader(std::string _vertexFile, std::string _fragFile) : vertexFile{_vertexFile}, fragFile{_fragFile} {}
void glslShader::createShape(std::vector<GLfloat> vertices){
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices.data()), vertices.data(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
bool addShader(GLuint program, const char* shaderSRC, GLenum type){
GLuint shader = glCreateShader(type);
const GLchar* src[1];
src[0] = shaderSRC;
GLint size[1];
size[0] = strlen(shaderSRC);
glShaderSource(shader, 1, src, size);
GLint result = 0;
GLchar log[1024];
glCompileShader(shader);
glGetShaderiv(shader, GL_COMPILE_STATUS, &result);
if(!result){
glGetShaderInfoLog(shader, 1024, NULL, log);
printf("ERROR: Failed to compile shader: &s\n", log);
return false;
}
glAttachShader(program, shader);
return true;
}
bool glslShader::compileShaders(){
ShaderProgram = glCreateProgram();
if (!ShaderProgram){
printf("ERROR: Failed to create shader program.\n");
return false;
}
if (!addShader(ShaderProgram, readShader("VertexShader.glsl").c_str(), GL_VERTEX_SHADER)){
printf("ERROR: failed to create vertex shader.\n");
return false;
}
if (!addShader(ShaderProgram, readShader("FragShader.glsl").c_str(), GL_FRAGMENT_SHADER)){
printf("ERROR: failed to create fragment shader.\n");
return false;
}
GLint result = 0;
GLchar log[1024];
glLinkProgram(ShaderProgram);
glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &result);
if(!result){
glGetProgramInfoLog(ShaderProgram, sizeof(log), NULL, log);
printf("ERROR: Failed to link program: %s", log);
return false;
}
glValidateProgram(ShaderProgram);
glGetProgramiv(ShaderProgram, GL_VALIDATE_STATUS, &result);
if (!result){
glGetProgramInfoLog(ShaderProgram, sizeof(log), NULL, log);
printf("ERROR: Failed to validate program: %s\n", log);
return false;
}
return true;
}
void glslShader::draw(){
glUseProgram(ShaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glUseProgram(0);
}
I am certain its not my shader code because I am using the same shaders that I used to render my last triangle before I was using a class.
Upvotes: 0
Views: 158
Reputation: 139
glBufferData(GL_ARRAY_BUFFER, sizeof(_verticies.data()), _verticies.data(), GL_STATIC_DRAW);
Should have been:
glBufferData(GL_ARRAY_BUFFER, _verticies.size() * sizeof(Glfloat), _verticies.data(), GL_STATIC_DRAW);
Upvotes: 2