1
\$\begingroup\$

I'm getting a very weird problem where OpenGL doesn't use the hardware to render anything, so I get just a cleared blank screen.

Here's some code:

//Mesh.hpp
template <typename T>
struct Vertex
{    
    glm::tvec3<T> Coordinate;
    glm::tvec3<T> Normal;
    glm::tvec2<T> TextureCoordinates;
};

using FVertex = Vertex<float>;
using DVertex = Vertex<double>;

class Mesh
{
public:
    explicit Mesh(aiMesh*, const aiScene*);
    explicit Mesh(const Mesh&);
    explicit Mesh(Mesh&&);
    virtual ~Mesh();

    Mesh& operator=(const Mesh&) = delete;
    Mesh& operator=(Mesh&&) = delete;

public:

public:
    virtual void Render(const uint32_t&);
    virtual void SetupMesh();

private:

private:

protected:
    std::vector<FVertex> VertexBuffer;
    std::vector<uint32_t> IndexBuffer;
    std::vector<Texture> Textures;

    gl::GLuint VAO;
    gl::GLuint VBO;
    gl::GLuint EBO;

protected:

};

//Mesh.cpp

//This is how I feed the buffers. I've double checked, and the 
//data imported from a Wavefront file is inside the VertexBuffer and IndexBuffer,
//and it is correctly loaded.
void Mesh::SetupMesh()
{
    gl::glBindVertexArray(VAO);
    gl::glBindBuffer(gl::GL_ARRAY_BUFFER, VBO);
    gl::glBindBuffer(gl::GL_ELEMENT_ARRAY_BUFFER, EBO);


    gl::glBufferData(gl::GL_ARRAY_BUFFER, VertexBuffer.size() * sizeof(Realms::FVertex), &(VertexBuffer.at(0)), gl::GL_STATIC_DRAW);
    gl::glBufferData(gl::GL_ELEMENT_ARRAY_BUFFER, IndexBuffer.size() * sizeof(uint32_t), &(IndexBuffer.at(0)), gl::GL_STATIC_DRAW);

    using Realms::FVertex;

    gl::glVertexAttribPointer(0, 3, gl::GL_FLOAT, gl::GL_FALSE, sizeof(FVertex), (void*)(offsetof(FVertex, Coordinate)));
    gl::glVertexAttribPointer(1, 3, gl::GL_FLOAT, gl::GL_FALSE, sizeof(FVertex), (void*)(offsetof(FVertex, Normal)));
    gl::glVertexAttribPointer(2, 2, gl::GL_FLOAT, gl::GL_FALSE, sizeof(FVertex), (void*)(offsetof(FVertex, TextureCoordinates)));
    gl::glEnableVertexAttribArray(0);
    gl::glEnableVertexAttribArray(1);
    gl::glEnableVertexAttribArray(2);
 }

void Mesh::Render(const uint32_t& glProgram)
{
    gl::glBindVertexArray(VAO);
    gl::glDrawElements(gl::GL_TRIANGLES, IndexBuffer.size(), gl::GL_UNSIGNED_INT, &(IndexBuffer.at(0)));
}

I've used a debugger to make sure the data inside the buffers is correct and accurate, that the vertex array object, buffer object and element object are all correctly generated and bound. Since my engine concept always chunks it down to drawing Meshes, nothing is being rendered. Here are the vertex and fragment shaders using GLSL:

 //VERT
 #version 330 core

layout (location = 0) in vec3 triangle;
layout (location = 1) in vec3 normals;
layout (location = 2) in vec2 TextCoords;

uniform mat4 ProjectionMatrix;
uniform mat4 LookAtMatrix;
uniform mat4 ModelMatrix;

void main()
{
    gl_Position = ProjectionMatrix * LookAtMatrix * ModelMatrix * vec4(triangle, 1.0);
}

 //FRAG
#version 330 core

out vec4 FragColor;

void main()
{
    FragColor = vec4(0.6, 0.3, 1.0, 1.0);
}

I've made sure the ProjectionMatrix, LookAtMatrix, and ModelMatrix are all correctly sent to the vertex shader.

\$\endgroup\$
1
\$\begingroup\$

Solved. Although the OpenGL specification documentation clearly states :

void glDrawElements(GLenum mode,
                    GLsizei count,
                    GLenum type,
                    const GLvoid * indices);

/

*indices*
Specifies a pointer to the location where the indices are stored.

, calling glDrawElements with indices = (void*)(0) worked for me.

\$\endgroup\$
  • 1
    \$\begingroup\$ I don't have the spec to hand but I can assure you that this behaviour is to spec. When using an index buffer object bound to a vao the last parameter of the function indicates an offset for the data in the buffer object, which starts at 0. So using the address of the first element in your C++ IndexBuffer, which is likely much bigger than 0, offsets the GL buffer so much that there's no more data to read. \$\endgroup\$ – cozmic Jul 15 '17 at 17:13
  • \$\begingroup\$ That does make sense, but the Khronos group OpenGL core specification on glDrawElements does not mention anything about an offset; Thanks for clearing this up! \$\endgroup\$ – curious student Jul 15 '17 at 17:18
  • \$\begingroup\$ Hey! if you solved the issue, you might want to mark this answer as accepted ;) \$\endgroup\$ – Vaillancourt 23 hours ago

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.