c++openglglslglm-mathvertex-attributes

Vertex attributes - using short instead of float for vertex positions


Currently I have following setup which is working fine for far.

struct Vertex {
    glm::vec3 position;
    glm::vec3 normal;
    glm::vec2 texCoord;
}
std::vector<Vertex> vertices;

The Vertex-Attributes:

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) offsetof(Vertex, Vertex::position)); 
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) offsetof(Vertex, Vertex::normal));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) offsetof(Vertex, Vertex::texCoord));

Now I want to increase my performance by changing the vertex attributes to from float to short. I tried to start with the vertex positions.

OpenGL's Vertex Specification Best Practices tells me this:

Positions [...] To do this, you rearrange your model space data so that all positions are packed in a [-1, 1] box around the origin. You do that by finding the min/max values in XYZ among all positions. Then you subtract the center point of the min/max box from all vertex positions; followed by scaling all of the positions by half the width/height/depth of the min/max box. You need to keep the center point and scaling factors around. When you build your model-to-view matrix (or model-to-whatever matrix), you need to apply the center point offset and scale at the top of the transform stack (so at the end, right before you draw).

I also read this Thread.

That's why I added this preprocessing step mapping all vertices to [-1,1]

for (auto& v : vertices) {
    v.position = (v.position - center) * halfAxisLengths;
}

and recale it in the vertex-shader

vec4 rescaledPos = vec4(in_pos, 1.0) * vec4(halfAxisLengths, 1.0) + vec4(center, 0.0);
gl_Position = P * V * M * rescaledPos;

My vertex attribute using GL_SHORT instead of GL_FLOAT, and normalize set to GL_TRUE:

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_SHORT, GL_TRUE, sizeof(Vertex), (void*) offsetof(Vertex, Vertex::position));

As result I just get a chaos of triangles, but not my model with increased fps.

Is this the correct way to set vertex attributes to short?

Or do I have to change my complete Vertex structure? If yes, what's the best way to do this (glm vectors with shorts?).

An working example would be great, I couldn't find any.


Solution

  • I adjusted the data structure for the vertex buffer:

    struct newVertex {
        GLshort position[4]; // for GL_SHORT
        GLint normal; // for GL_INT_2_10_10_10_REV
        GLshort texCoord[2]; // for GL_SHORT
    };
    

    As a result I get ~20% increased performance.