简体   繁体   English

使纹理在OpenGL 3.2中工作

[英]Getting textures to work in OpenGL 3.2

I have been staring at this code for a while now with no luck. 我一直盯着这段代码已经有一段时间了,没有运气。 I'm working on integrating librocket into my own project (the library isn't that important to the question) and part of that requires writing a renderer class. 我正在将librocket集成到我自己的项目中(该库对问题不是那么重要),其中一部分需要编写renderer类。 I've been trying to do just that but can't get the textures to display. 我一直试图做到这一点,但无法显示纹理。 The vertex color and position work fine. 顶点颜色和位置可以正常工作。

I'm using OpenGL3.2. 我正在使用OpenGL3.2。

I've temporarily modified the code to try to draw a single quad. 我临时修改了代码以尝试绘制单个四边形。 The only parameter being used is the texture parameter, which is just a GLuint cast to another type. 使用的唯一参数是texture参数,它只是将GLuint为另一种类型。

There's a good chance that I'm missing something stupid, but I can't see it. 我很可能会丢失一些愚蠢的东西,但我看不到。 Hopefully another set of eyes will help. 希望另一双眼睛会有所帮助。 Feel free to ask for more code/info. 随时要求更多代码/信息。

// Called by Rocket when it wants to render geometry that it does not wish to optimise.
void SDLRenderInterface::RenderGeometry(Rocket::Core::Vertex* vertices, int num_vertices, int* indices, int num_indices, const Rocket::Core::TextureHandle texture, const Rocket::Core::Vector2f& translation)
{
    GLuint program;
    GLuint vertexBuffer;
    GLuint indexBuffer;
    GLuint vertexPosLoc      = 0;
    GLuint vertexColorLoc    = 0;
    GLuint vertexTexCoordLoc = 0;
    GLuint texSamplerLoc     = 0;
    GLuint translationLoc    = 0;
    GLuint viewDimLoc        = 0;


    int offset = 8;
    int vertexCount = 4;
    float vertexData[] = {-0.5, -0.5, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0,
                           0.5, -0.5, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0,
                           0.5,  0.5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
                          -0.5,  0.5, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0};
    int indexData[] = {0,1,2,0,2,3};
    int indexCount = 6;

    // Populate vertex buffer
    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(float)*offset*vertexCount,
                 vertexData, GL_STATIC_DRAW);

    // Populate index buffer
    glGenBuffers(1, &indexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * indexCount,
                 indexData, GL_STATIC_DRAW);

    program = shaderManager->getProgram(2, "rocketTex.vert",
                                           "rocketTex.frag");
    glUseProgram(program);
    // Set up the texture
    texSamplerLoc = glGetUniformLocation(program, "texSampler");
    vertexTexCoordLoc = glGetAttribLocation(program, "vertexTexCoord");
    if(texSamplerLoc == -1)
    {
        std::cerr << "Error: cannot find texture location." << std::endl;
        return;
    }
    if(vertexTexCoordLoc == -1)
    {
        std::cerr << "Error: cannot find texture coord location."
                  << std::endl;
        return;
    }

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, (GLuint) texture);
    glUniform1i(texSamplerLoc, 0);

    // Set up the per vertex texture coords 
    glEnableVertexAttribArray(vertexTexCoordLoc);
    glVertexAttribPointer(vertexTexCoordLoc, 2, GL_FLOAT, GL_FALSE,
                          offset * sizeof(float),
                          (void*) (sizeof(float) * 6));

    // Set up uniforms
    translationLoc = glGetUniformLocation(program, "translation");
    viewDimLoc = glGetUniformLocation(program, "viewDimensions");
    if(translationLoc == -1)
    {
        std::cerr << "Error: cannot find translation location."
                  << std::endl;
        return;
    }
    if(viewDimLoc == -1)
    {
        std::cerr << "Error: cannot find viewDim location."
                  << std::endl;
        return;
    }
    glUniform2f(translationLoc, 0,0);
    glUniform2f(viewDimLoc, 1,1);


    // Set up per-vertex attributes
    vertexPosLoc = glGetAttribLocation(program, "vertexPosition");
    vertexColorLoc = glGetAttribLocation(program, "vertexColor");
    if(vertexPosLoc == -1)
    {
        std::cerr << "Error: cannot find vertex position location."
                  << std::endl;
        return;
    }
    if(vertexColorLoc == -1)
    {
        std::cerr << "Error: cannot find vertex color location."
                  << std::endl;
        return;
    }
    glEnableVertexAttribArray(vertexPosLoc);
    glEnableVertexAttribArray(vertexColorLoc);
    glVertexAttribPointer(vertexPosLoc, 2, GL_FLOAT, GL_FALSE,
                              offset * sizeof(float), 0);
    glVertexAttribPointer(vertexColorLoc, 4, GL_FLOAT, GL_TRUE,
                              offset * sizeof(float),
                              (void*) (sizeof(float) * 2));

    // Draw the geometry
    glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, 0);

    glDisableVertexAttribArray(vertexPosLoc);
    glDisableVertexAttribArray(vertexColorLoc);
    glDisableVertexAttribArray(vertexTexCoordLoc);
    glDeleteBuffers(1, &vertexBuffer);
    glDeleteBuffers(1, &indexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glUseProgram(0);

}

Vertex Shader: 顶点着色器:

#version 120

uniform vec2 translation;
uniform vec2 viewDimensions;

attribute vec2 vertexPosition;
attribute vec4 vertexColor;
attribute vec2 vertexTexCoord;

varying vec2 texCoord;
varying vec4 fragColor;

void main(void)
{
    vec2 ndcPos = ((vertexPosition + translation)/(viewDimensions));

    texCoord = vertexTexCoord;
    fragColor = vertexColor;
    gl_Position = vec4(ndcPos, 0.0, 1.0);
}

Fragment Shader: 片段着色器:

#version 120

uniform sampler2D texSampler;

varying vec2 texCoord;
varying vec4 fragColor;

void main(void)
{
    vec4 objectColor = texture2D(texSampler, texCoord);
    gl_FragColor = vec4((objectColor * fragColor).xyz, 1.0);
}

So, I finally figured it out. 所以,我终于想通了。 jozxyqk's advice for testing the texture coords confirmed my suspicions that the texture coordinates were off (every vertex was getting the same coordinate). jozxyqk关于测试纹理坐标的建议证实了我的怀疑,即纹理坐标已关闭(每个顶点都获得相同的坐标)。 The problem ended up being that I was calling glVertexAttribDivisor(attributeLoc, 1) in another part of my code and never setting it back to per vertex, so it was affecting my other shaders. 问题最终导致我在代码的另一部分中调用glVertexAttribDivisor(attributeLoc, 1) ,并且从未将其设置回每个顶点,因此影响了我的其他着色器。 Thinking about the design of OpenGL, it makes sense that this would be necessary. 考虑到OpenGL的设计,这很有必要。

Glad that's settled! 很高兴解决了!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM