By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
429,117 Members | 1,714 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 429,117 IT Pros & Developers. It's quick & easy.

Modern (SDL2) OpenGl 3.3 Not Drawing

P: 88
Hey I'm new to the modern world of OpenGL but have done quite a lot of older OpenGl stuff.

I had this program displaying stuff via loading in textures and a vertices array, but I changed it so I could append vertices (with their respective color) one by one and "initMesh()" later. For some reason this doesn't work and I can't see why it won't. Would be very appreciated if anyone could help :-). Here's all the files:

main.cpp:
Expand|Select|Wrap|Line Numbers
  1. #include <SDL2\SDL.h>
  2. #include <GL\glew.h>
  3. #include <glm\glm.hpp>
  4. #include "Window.h"
  5. #include "Shader.h"
  6. #include "Mesh.h"
  7.  
  8.  
  9.  
  10. int main(int argc, char *args[])
  11. {
  12.     Window window(600, 600, "Vector Field Editor");
  13.     Shader shader/*("")*/;
  14.  
  15.     Vertex vertices[] = { Vertex(glm::vec3(-0.5, -0.5, 1.0), glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)),
  16.         Vertex(glm::vec3(0,    0.5, 1.0), glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)),
  17.         Vertex(glm::vec3(0.5, -0.5, 1.0), glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)) };
  18.  
  19.     Mesh mesh(GL_TRIANGLES);
  20.  
  21.     mesh.appendVertex(vertices[0]);
  22.     mesh.appendVertex(vertices[1]);
  23.     mesh.appendVertex(vertices[2]);
  24.     mesh.initMesh();
  25.     while (window.isOpen())
  26.     {
  27.         // Clear window
  28.         window.clear(0.0f, 0.0f, 0.0f, 0.0f);
  29.         shader.bind();
  30.         mesh.draw();
  31.         // Update window
  32.         window.update();
  33.         // Handle events
  34.         window.handleEvents();
  35.     }
  36.     return 0;
  37. }
  38.  
Window.h + Window.cpp
Expand|Select|Wrap|Line Numbers
  1. Header:
  2. #pragma once
  3. #include <string>
  4. #include <SDL2\SDL.h>
  5. #include <GL\glew.h>
  6. #include <glm\glm.hpp>
  7. #include <iostream>
  8.  
  9. class Window
  10. {
  11. public:
  12.     Window(int width, int height, const std::string& title);
  13.     virtual ~Window();
  14.  
  15.     void update();
  16.     void handleEvents();
  17.     bool isOpen();
  18.     void clear(float r, float g, float b, float a);
  19.  
  20. protected:
  21.     //
  22. private:
  23.     // The Window
  24.     SDL_Window* window;
  25.     // Windows context
  26.     SDL_GLContext glContext;
  27.     // If the window is closed or not
  28.     bool isWOpen = true;
  29.     // Glew initialization status
  30.     GLenum m_status;
  31. };
  32.  
  33. CPP:
  34. #include "Window.h"
  35.  
  36. Window::Window(int width, int height, const std::string& title)
  37. {
  38.     // Initialize SDL
  39.     SDL_Init(SDL_INIT_EVERYTHING);
  40.     // Sets SDL OpenGL Attributes
  41.     SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
  42.     SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
  43.     SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
  44.     SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
  45.     SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
  46.     SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
  47.     SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
  48.     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
  49.     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
  50.  
  51.     // Makes the window pointer
  52.     window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL);
  53.  
  54.     // If window creation failed
  55.     if (window == NULL)
  56.     {
  57.         std::cerr << "SDL Error(couldn't create window): " << SDL_GetError() << std::endl;
  58.     }
  59.  
  60.     // Sets the context for the given window
  61.     glContext = SDL_GL_CreateContext(window);
  62.  
  63.     // If window context creation failed
  64.     if (glContext == NULL)
  65.     {
  66.         std::cerr << "SDL Error(something about glcontext): " << SDL_GetError() << std::endl;
  67.     }
  68.  
  69.     // Using an experimental version of OpenGl
  70.     glewExperimental = GL_TRUE;
  71.     // Initialize Glew
  72.     GLenum status = glewInit();
  73.     // Glew failed to initialize
  74.     if (status = !GLEW_OK)
  75.     {
  76.         std::cerr << "GLEW Error(something about the initilazation): " << glewGetErrorString(status) << " | OpenGL Version: " << glGetString(GL_VERSION) << std::endl;
  77.     }
  78.  
  79.     /*if (GLEW_VERSION_4_5)
  80.     {
  81.         std::cout << "We support version 4.5.0!" << std::endl;
  82.     }*/
  83.  
  84.     glEnable(GL_DEPTH_TEST);
  85.  
  86.     glEnable(GL_CULL_FACE);
  87.     glCullFace(GL_BACK);
  88. }
  89.  
  90. Window::~Window()
  91. {
  92.     // Delete Window Context
  93.     SDL_GL_DeleteContext(glContext);
  94.     // Destroy window
  95.     SDL_DestroyWindow(window);
  96.     // SDL Should quit
  97.     SDL_Quit();
  98. }
  99.  
  100. void Window::update()
  101. {
  102.     // Swap buffers
  103.     SDL_GL_SwapWindow(window);
  104. }
  105.  
  106. void Window::handleEvents()
  107. {
  108.     // Get all events
  109.     SDL_Event e;
  110.     // Extract all events
  111.     while (SDL_PollEvent(&e))
  112.     {
  113.         // If SDL_QUIT event, then window should close
  114.         if (e.type == SDL_QUIT)
  115.             isWOpen = false;
  116.     }
  117. }
  118.  
  119. bool Window::isOpen()
  120. {
  121.     return isWOpen;
  122. }
  123.  
  124. void Window::clear(float r, float g, float b, float a)
  125. {
  126.     glClearColor(r, g, b, a);
  127.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  128. }
  129.  
  130.  
Shader.h + Shader.cpp
Expand|Select|Wrap|Line Numbers
  1. Header:
  2. #pragma once
  3. #include <string>
  4. #include <GL\glew.h>
  5. #include <iostream>
  6. #include <vector>
  7. #include <fstream>
  8. #include <algorithm>
  9.  
  10. #define VERTEX_SHADER 0
  11. #define FRAGMENT_SHADER 1
  12. #define NUM_SHADERS 2
  13.  
  14. class Shader
  15. {
  16. public:
  17.     Shader();
  18.     virtual ~Shader();
  19.  
  20.     void bind();
  21.     //void update(const Transform& trans, const Camera& camera);
  22. protected:
  23.     //
  24. private:
  25.     //enum { TRANSFORM_U, NUM_UNIFORMS };
  26.  
  27.     GLuint program;
  28.     GLuint shaders[NUM_SHADERS];
  29.     //GLuint uniforms[NUM_UNIFORMS];
  30. };
  31.  
  32. CPP:
  33.  
  34. #include "Shader.h"
  35.  
  36. static std::string LoadShader(const std::string & fileName);
  37. static void CheckShaderError(GLuint shader, GLuint flag, bool isProgram, const std::string & errorMessage);
  38. static GLuint CreateShader(const std::string& text, GLenum shaderType);
  39.  
  40. Shader::Shader(/*const std::string& fileName*/)
  41. {
  42.     // Make a program for shaders
  43.     program = glCreateProgram();
  44.     // Make vertex shader
  45.     shaders[VERTEX_SHADER] = CreateShader(LoadShader(/*fileName + ".vs"*/"./shaders/vertexShader.glsl"), GL_VERTEX_SHADER);
  46.     // Make fragment shader
  47.     shaders[FRAGMENT_SHADER] = CreateShader(LoadShader(/*fileName + ".fs"*/"./shaders/fragmentShader.glsl"), GL_FRAGMENT_SHADER);
  48.  
  49.     // Attach all indevidual shaders to the program
  50.     for (unsigned int i = 0; i < NUM_SHADERS; i++)
  51.         glAttachShader(program, shaders[i]);
  52.  
  53.     // Bind the word "position" in the shader as "0"
  54.     glBindAttribLocation(program, 0, "position");
  55.     //
  56.     glBindAttribLocation(program, 1, "color");
  57.  
  58.     // Link shader program
  59.     glLinkProgram(program);
  60.     // Check shader program for linking errors
  61.     CheckShaderError(program, GL_LINK_STATUS, true, "Error: Program linking failed: ");
  62.  
  63.     // Validate shader program
  64.     glValidateProgram(program);
  65.     // Check shader program for validation status
  66.     CheckShaderError(program, GL_VALIDATE_STATUS, true, "Error: Program is invalid: ");
  67.  
  68.     /*uniforms[TRANSFORM_U] = glGetUniformLocation(program, "transform");*/
  69. }
  70.  
  71. Shader::~Shader()
  72. {
  73.     // Deleting all shaders
  74.     for (unsigned int i = 0; i < NUM_SHADERS; i++)
  75.     {
  76.         glDetachShader(program, shaders[i]);
  77.         glDeleteShader(shaders[i]);
  78.     }
  79.     // Delete shader program
  80.     glDeleteProgram(program);
  81. }
  82.  
  83. void Shader::bind()
  84. {
  85.     // Binds the program to window
  86.     glUseProgram(program);
  87. }
  88.  
  89. /*void Shader::update(const Transform& transform, const Camera& camera)
  90. {
  91.     glm::mat4 model = camera.getViewProjection() * transform.getModel();
  92.  
  93.     glUniformMatrix4fv(uniforms[TRANSFORM_U], 1, GL_FALSE, &model[0][0]);
  94. }*/
  95.  
  96. std::string LoadShader(const std::string& fileName)
  97. {
  98.     std::ifstream file((fileName).c_str());
  99.  
  100.     std::string output;
  101.     std::string line;
  102.  
  103.     if (file.is_open())
  104.     {
  105.         while (file.good())
  106.         {
  107.             getline(file, line);
  108.             output.append(line + "\n");
  109.         }
  110.     }
  111.     else
  112.     {
  113.         std::cerr << "Unable to load shader: " << fileName << std::endl;
  114.     }
  115.  
  116.     return output;
  117. }
  118.  
  119. void CheckShaderError(GLuint shader, GLuint flag, bool isProgram, const std::string& errorMessage)
  120. {
  121.     GLint success = 0;
  122.     GLchar error[1024] = { 0 };
  123.  
  124.     if (isProgram)
  125.         glGetProgramiv(shader, flag, &success);
  126.     else
  127.         glGetShaderiv(shader, flag, &success);
  128.  
  129.     if (success == GL_FALSE)
  130.     {
  131.         if (isProgram)
  132.             glGetProgramInfoLog(shader, sizeof(error), NULL, error);
  133.         else
  134.             glGetShaderInfoLog(shader, sizeof(error), NULL, error);
  135.  
  136.         std::cerr << errorMessage << ": '" << error << "'" << std::endl;
  137.     }
  138. }
  139.  
  140. GLuint CreateShader(const std::string& text, GLenum shaderType)
  141. {
  142.     GLuint shader = glCreateShader(shaderType);
  143.  
  144.     if (shader == 0)
  145.         std::cerr << "Error: Shader creation failed!" << std::endl;
  146.  
  147.     const GLchar* shaderSourceStrings[1];
  148.     shaderSourceStrings[0] = text.c_str();
  149.     GLint shaderSourceStringLengths[1];
  150.     shaderSourceStringLengths[0] = text.length();
  151.  
  152.     glShaderSource(shader, 1, shaderSourceStrings, shaderSourceStringLengths);
  153.     glCompileShader(shader);
  154.  
  155.     CheckShaderError(shader, GL_COMPILE_STATUS, false, "Error: Shader compilation failed: ");
  156.  
  157.     return shader;
  158. }
  159.  
  160.  
Vertex.h (inline):
Expand|Select|Wrap|Line Numbers
  1. #pragma once
  2. class Vertex
  3. {
  4. public:
  5.     Vertex(const glm::vec3& pos, glm::vec4& color = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f))
  6.     {
  7.         this->pos = pos;
  8.         this->color = color;
  9.     }
  10.  
  11.     virtual ~Vertex() {}
  12.  
  13.     inline glm::vec3 getPos() { return pos; }
  14.     inline void setPos(glm::vec3 pos) { this->pos = pos; }
  15.     inline glm::vec4 getColor() { return color; }
  16.     inline void setColor(glm::vec4 pos) { this->color = color; }
  17.  
  18.     bool operator==(Vertex& other) const
  19.     {
  20.         return (pos == other.getPos() && color == other.getColor());
  21.     }
  22.  
  23. protected:
  24.     //
  25. private:
  26.     glm::vec3 pos;
  27.     glm::vec4 color;
  28. };
  29.  
Mesh.h + Mesh.cpp
Expand|Select|Wrap|Line Numbers
  1. Header:
  2. #pragma once
  3. #include <glm/glm.hpp>
  4. #include <gl/glew.h>
  5. #include <vector>
  6. #include <string>
  7. #include <cassert>
  8. #include <iostream>
  9. #include "Vertex.h"
  10. #include "stb_image.h"
  11.  
  12. class Mesh
  13. {
  14. public:
  15.     Mesh(GLenum drawType/*, unsigned int* indecies, unsigned int numIndecies*/);
  16.     virtual ~Mesh();
  17.  
  18.     void appendVertex(Vertex vertex);
  19.     void draw();
  20.     void initMesh();
  21. protected:
  22.     //
  23. private:
  24.     enum {POSITION_VB, COLOR_VB, /*INDEX_VB,*/ NUM_BUFFERS};
  25.  
  26.     std::vector<Vertex> vertices;
  27.  
  28.     GLuint vertexArrayObject;
  29.     GLuint vertexArrayBuffers[NUM_BUFFERS];
  30.     //unsigned int nrVertices;
  31.     //bool textureAvaliable;
  32.     GLenum drawType;
  33. };
  34.  
  35. CPP:
  36.  
  37. #include "Mesh.h"
  38.  
  39. Mesh::Mesh(GLenum drawType/*, unsigned int* indecies, unsigned int numIndecies*/)
  40. {
  41.     // Set the drawType
  42.     this->drawType = drawType;
  43. }
  44.  
  45. Mesh::~Mesh()
  46. {
  47.     // Delete vertex array
  48.     glDeleteVertexArrays(1, &vertexArrayObject);
  49.     glDeleteBuffers(NUM_BUFFERS, vertexArrayBuffers);
  50. }
  51.  
  52. void Mesh::appendVertex(Vertex vertex)
  53. {
  54.     vertices.push_back(vertex);
  55.     //nrVertices++;
  56. }
  57.  
  58. void Mesh::draw()
  59. {
  60.     // Bind the vertex array object
  61.     glBindVertexArray(vertexArrayObject);
  62.     // Draw array
  63.     glDrawArrays(/*drawType*/ GL_TRIANGLES, 0, /*nrVertices*/vertices.size());
  64.     // Clear binding of vertex array
  65.     glBindVertexArray(0);
  66. }
  67.  
  68. void Mesh::initMesh()
  69. {
  70.     // Generate vertex array object
  71.     glGenVertexArrays(1, &vertexArrayObject);
  72.  
  73.     // Bind the vertex array object
  74.     glBindVertexArray(vertexArrayObject);
  75.  
  76.     std::vector<glm::vec3> positions;
  77.     std::vector<glm::vec4> colors;
  78.  
  79.  
  80.     // Prereserve enough memory
  81.     positions.reserve(/*nrVertices*/vertices.size());
  82.     colors.reserve(/*nrVertices*/vertices.size());
  83.  
  84.     // Move all positions and texCoords over
  85.     for (unsigned int i = 0; i < /*nrVertices*/vertices.size(); i++)
  86.     {
  87.         positions.push_back(vertices[i].getPos());
  88.         colors.push_back(vertices[i].getColor());
  89.     }
  90.  
  91.     for (unsigned int i = 0; i < /*nrVertices*/vertices.size(); i++)
  92.     {
  93.         std::cout << "\n\nPosition: (" << positions[i].x <<
  94.                                   ", " << positions[i].y <<
  95.                                   ", " << positions[i].z << ")\n Color: (" << colors[i].x <<
  96.                                                                       ", " << colors[i].y <<
  97.                                                                       ", " << colors[i].z <<
  98.                                                                       ", " << colors[i].w << ")";
  99.     }
  100.  
  101.     // Generate buffer
  102.     glGenBuffers(NUM_BUFFERS, vertexArrayBuffers);
  103.  
  104.     // !!!! Make a buffer for VERTEX POSITIONS !!!!
  105.     // Bind the buffer
  106.     glBindBuffer(GL_ARRAY_BUFFER, vertexArrayBuffers[POSITION_VB]);
  107.  
  108.     // Put the given data in buffer
  109.     glBufferData(GL_ARRAY_BUFFER, /*nrVertices*/vertices.size() * sizeof(positions[0]), &positions[0], GL_STATIC_DRAW);
  110.  
  111.     // Enable vertex attribute array POSITION_VB
  112.     glEnableVertexAttribArray(POSITION_VB);
  113.  
  114.     // Gett OpenGl how to use the vertex attribute array
  115.     glVertexAttribPointer(POSITION_VB, 3, GL_FLOAT, GL_FALSE, 0, 0);
  116.  
  117.     // !!!! Make a buffer for the COLORS !!!!
  118.     // Bind the buffer
  119.     glBindBuffer(GL_ARRAY_BUFFER, vertexArrayBuffers[COLOR_VB]);
  120.  
  121.     // Put the given data in buffer
  122.     glBufferData(GL_ARRAY_BUFFER, /*nrVertices*/vertices.size() * sizeof(colors[0]), &colors[0], GL_STATIC_DRAW);
  123.  
  124.     // // Enable vertex attribute array COLOR_VB
  125.     glEnableVertexAttribArray(COLOR_VB);
  126.  
  127.     // Gett OpenGl how to use the vertex attribute array
  128.     glVertexAttribPointer(COLOR_VB, 4, GL_FLOAT, GL_FALSE, 0, 0);
  129.  
  130.     // Bind vertex array
  131.     glBindVertexArray(0);
  132. }
  133.  
Vertex.glsl + Fragment.glsl
Expand|Select|Wrap|Line Numbers
  1. Vertex:
  2. #version 330
  3.  
  4. attribute vec3 position;
  5. attribute vec4 color;
  6.  
  7. varying vec4 color0;
  8.  
  9. //uniform mat4 transform;
  10.  
  11. void main()
  12. {
  13.     //gl_Position = /*transform * */vec4(position, 1.0);
  14.     gl_Position = vec4(position, 1.0);
  15.     color0 = color;
  16. }
  17.  
  18. Fragment:
  19. #version 330
  20.  
  21. varying vec4 color0;
  22.  
  23. void main()
  24. {
  25.     gl_FragColor = color0;
  26. }
  27.  
Jun 26 '17 #1

✓ answered by weaknessforcats

The next step is to put a breakpoint at the beginning of each function and start the code using your debugger. Each time a function is called, execution breaks to the debugger. You can see where the call came from and verify all the variables in the code are in the correct state.

When you are sure a function is correct, remove its breakpoint.

Obviously, the debugger should run to breakpoint rather than stepping a line at a time.

When there are no breakpoints left, the code should be working.

Let me know what happened.

Share this Question
Share on Google+
4 Replies


weaknessforcats
Expert Mod 5K+
P: 9,197
I am not an OpenGL person but I did have a question. In main() a mesh object s created, a constructor called, various other mesh member functions are called, and then initMesh member function is called.

Shouldn't initMesh be part of the constructor? It just looks odd that a mesh object is created, modified, and then initialized.
Jun 26 '17 #2

P: 88
No, the reason is that I can add a unknown number of vertices in a mesh and once the mesh initializes, OpenGL takes all those vertices at once and dumps them in a buffer for drawing. That's why it's Create, Modify and then Init :-) (I do understand that it looks a little weird) Plus it cuts down on the amount of array's of vertices I would need to have everywhere and it makes the code a little more cleaner I think :-)
Jun 26 '17 #3

weaknessforcats
Expert Mod 5K+
P: 9,197
The next step is to put a breakpoint at the beginning of each function and start the code using your debugger. Each time a function is called, execution breaks to the debugger. You can see where the call came from and verify all the variables in the code are in the correct state.

When you are sure a function is correct, remove its breakpoint.

Obviously, the debugger should run to breakpoint rather than stepping a line at a time.

When there are no breakpoints left, the code should be working.

Let me know what happened.
Jun 26 '17 #4

P: 88
I kind of fixed it. It was the "Depth_Buffer", "Depth_Test" and "GL_Cull_Face" that messed it up. OpenGL is testing each pixels z-value in the depth buffer, but I haven't assigned a depth buffer to be used other than saying OpenGl will get 16+ bits to store depth information per pixel, so OpenGl doesn't draw. Plus that I reverted "Mesh.h + Mesh.cpp" to take everything it needs and initializes immediately, instead of waiting for vertices and then initializing. But at least I can draw now :-)
Jun 26 '17 #5

Post your reply

Sign in to post your reply or Sign up for a free account.