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 Answer 1

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\$
3
  • 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, 2017 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\$ Jul 15, 2017 at 17:18
  • \$\begingroup\$ Hey! if you solved the issue, you might want to mark this answer as accepted ;) \$\endgroup\$
    – Vaillancourt
    Dec 5, 2019 at 16:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .