Я уже давно смотрю на этот код без удачи. Я работаю над интеграцией librocket в свой собственный проект (библиотека не так важна для вопроса), и часть этого требует написания класса рендерера. Я пытался сделать это, но не могу отобразить текстуры. Цвет и положение вершины работают нормально.
Я использую OpenGL3.2.
Я временно изменил код, чтобы попытаться нарисовать один квад. Единственный используемый параметр — это texture
параметр, который просто GLuint
приведение к другому типу.
Есть большая вероятность, что я упускаю что-то глупое, но я не вижу этого. Надеюсь, еще один набор глаз поможет. Не стесняйтесь просить больше кода / информации.
// 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);
}
Вершинный шейдер:
#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);
}
Фрагмент шейдера:
#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);
}
Итак, я наконец понял это. Совет jozxyqk по тестированию координат текстуры подтвердил мои подозрения, что координаты текстуры были отключены (каждая вершина получала одну и ту же координату). Проблема закончилась тем, что я звонил glVertexAttribDivisor(attributeLoc, 1)
в другой части моего кода и никогда не возвращая его на каждую вершину, так что это влияло на другие мои шейдеры. Размышляя о дизайне OpenGL, есть смысл, что это будет необходимо.
Рад, что это решено!
Других решений пока нет …