Robadob / sdl_exp

Low-level graphics engine built over SDL2
MIT License
1 stars 2 forks source link

vec2 TexCoords are unsupported, must be vec3 within shader. #19

Closed Robadob closed 8 years ago

Robadob commented 8 years ago

If a shader breaks and an attribute doesn't link, refreshing the shader won't fix it, a full program restart is required. (Fixed https://github.com/Robadob/sdl_exp/commit/510e4ef43b8ef55c2351d9bacd24a808f0ad4b7c)

It appears that vec2 TexCoords are unsupported (but vec3 work fine). I had a quick look through the code trying to find the cause, but couldn't spot anything amiss. The particular problem seems to be if the tex coord vector where attributes are passed into the shader is a vec2, binding them all in host code as vec2 works fine, but as soon as shader changes type from vec2 to vec3 various problems appear.

It's possible that this has something to do with the Uniform location/index debacle, (the documentation is similar), however we're lacking a glGetAttribIndices() method. Testing this with other attributes to see if we can generic vec2's would be a good debugging strategy to identify if its a random tex coord bug (unlikely) or if it's just an inability to provide any vec2 attributes (likely).

Robadob commented 8 years ago

George is having a similar issue, and this page clearly states

To get the attribute location (the one used by glVertexAttribPointer​, not the index​ field used above), we use this function:

So how to convert an attribute location or name, to an attribute index?

Robadob commented 8 years ago
std::pair<int, GLenum> ShaderCore::findAttribute(const char *attributeName, const int shaderProgram)
{
    int attribLocation = shaderProgram<0 ? -1 : GL_CALL(glGetAttribLocation(shaderProgram, attributeName));
    //attribLocation != attribIndex (Index required to get info, Location required to set val)
    GLuint attribIndex = shaderProgram<0 ? -1 : GL_CALL(glGetProgramResourceIndex(shaderProgram, GL_PROGRAM_INPUT, attributeName));
    if (attribLocation>-1 && attribIndex != GL_INVALID_INDEX)
    {
        GLenum type;
        GLint size;//Collect size, because its not documented that you can pass 0
        GL_CALL(glGetActiveAttrib(shaderProgram, attribIndex, 0, nullptr, &size, &type, nullptr));
        return std::pair<int, GLenum>(attribLocation, type);
    }
    return  std::pair<int, GLenum>(-1, 0);
}

This appears to fix George's bug, exactly the same kind of problem as the uniform one we corrected before. Not tested this fixes the texture shader.

Not a fan of the new method, passing the enum GL_PROGRAM_INPUT rather than something that actually mentions attribute, but I guess 430 as deprecated attribute, and now calls them in's. Should also update the output stuff in multipass branch to use get program resource index too I guess, saving the requirement of relinking the shader.