我面临一个奇怪的问题。
我目前正在嵌入式设备上进行Open GL ES 3项目。 目的是从头开始或多或少地创建2D小部件库。
由于我有很多(很多)绘制调用,所以我决定打包小部件渲染以减少绘制调用。
因此,我有2个代码块执行几乎相同的操作,但其中一个用于图像,另一个用于文本。着色器属性不同,因此我使用2种不同的着色器,但它们非常相似。
它在图像绘图上效果很好,但对于文本却不起作用... xS
here is an example of the expected result (in fact what I get without packing the data to draw)
And there is the result when the data are packed
似乎文本的纹理位置全部为-1,除了text0一样,好像opengl将其剥离为未使用,但是tbh我不知道要解决这个问题。
有人可以帮我吗?
这是用于完成这项工作的大量代码,您可以告诉我,这很可怕,但是它就像一个beta版本,因此我想使用一些自定义数据结构来提高性能。
感谢您的帮助伙伴!
void BaseRenderContext::prerenderGlyph(const text::GlyphProxy &glyph,
glm::vec2 &position, const glm::vec4 &color, float scale)
{
if(m_textTextures.size() == 16)
renderText();
GL::text::FreeTypeLib &ft = GL::text::FreeTypeLib::getInstance();
std::vector<float> vertices = ft.getGlyphCoordinates(glyph, position, scale);
m_textVertices.insert(m_textVertices.end(), vertices.begin(), vertices.end());
for(size_t i = 0; i < 6; ++i)
m_textColors.emplace_back(color);
m_textTextures.emplace_back(glyph.getTextureID());
position.x += ft.getGlyphWidth(glyph, scale);
}
void BaseRenderContext::prerenderText(const std::string &text, const Font *font, const glm::vec4 &color, const glm::vec3 &position, float scale)
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
prerenderText(converter.from_bytes(text), font, color, position, scale);
}
void BaseRenderContext::prerenderText(const std::wstring &text, const Font *font, const glm::vec4 &color, const glm::vec3 &position, float scale)
{
glm::vec2 pos(position.x, position.y);
for (size_t i = 0, imax = text.size(); i < imax; ++i)
{
prerenderGlyph(font->operator [](static_cast<uint32_t>(text[i])), pos, color, scale);
}
}
void BaseRenderContext::renderText()
{
if(m_textTextures.empty())
return;
glUseProgram(m_shaders["textShader"]);
glUniformMatrix4fv(m_shaderVars["textShader.projection"], 1, GL_FALSE, glm::value_ptr(m_projection));
size_t texture_size = m_textTextures.size();
for(size_t i = 0, imax = texture_size; i < imax; ++i)
{
int location = m_shaderVars["textShader.text" + std::to_string(i)];
glUniform1i(location, static_cast<int>(i));
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(GL_TEXTURE_2D, m_textTextures[i]);
}
size_t data_size = m_textVertices.size();
size_t nb_vertices= texture_size * 6;
glBindBuffer(GL_ARRAY_BUFFER, m_vbos["textVbo"]);
glBufferSubData(GL_ARRAY_BUFFER, 0, data_size*sizeof(float), m_textVertices.data());
glBufferSubData(GL_ARRAY_BUFFER, 384*sizeof(float), nb_vertices*4*sizeof(float), m_textColors.data());
glBindVertexArray(m_vaos["textVao"]);
glDrawArrays(GL_TRIANGLES, 0, nb_vertices);
// If I uncomment these lines and comment the one above everything is ok :'(
/*for(size_t i = 0, imax = texture_size; i < imax; ++i)
{
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_textTextures[i]);
glDrawArrays(GL_TRIANGLES, i * 6, 6);
}*/
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glUseProgram(0);
m_textTextures.clear();
m_textColors.clear();
m_textVertices.clear();
m_textTextures.reserve(16);
m_textColors.reserve(96);
m_textVertices.reserve(384);
}
void BaseRenderContext::prerenderImage(uint textureId, const glm::vec4 &color, const glm::vec3 &position, const glm::vec2 &size, float colorFactor, float scale)
{
if(m_imageTextures.size() == 16)
renderImage();
float w = size.x * scale;
float h = size.y * scale;
std::vector<float> vertices{
position.x, position.y + h,
position.x, position.y,
position.x + w, position.y,
position.x, position.y + h,
position.x + w, position.y,
position.x + w, position.y + h
};
m_imageVertices.insert(m_imageVertices.end(), vertices.begin(), vertices.end());
for(size_t i = 0; i < 6; ++i)
{
m_imageColors.emplace_back(color);
m_imageColorFactors.emplace_back(colorFactor);
}
m_imageTextures.emplace_back(textureId);
}
void BaseRenderContext::renderImage()
{
if(m_imageTextures.empty())
return;
glUseProgram(m_shaders["imageShader"]);
glUniformMatrix4fv(m_shaderVars["imageShader.projection"], 1, GL_FALSE, glm::value_ptr(m_projection));
size_t texture_size = m_imageTextures.size();
for(size_t i = 0, imax = texture_size; i < imax; ++i)
{
int location = m_shaderVars["imageShader.text" + std::to_string(i)];
glUniform1i(location, static_cast<int>(i));
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(GL_TEXTURE_2D, m_imageTextures[i]);
}
size_t data_size = m_imageVertices.size();
size_t nb_vertices = texture_size * 6;
glBindBuffer(GL_ARRAY_BUFFER, m_vbos["imageVbo"]);
glBufferSubData(GL_ARRAY_BUFFER, 0, data_size*sizeof(float), m_imageVertices.data());
glBufferSubData(GL_ARRAY_BUFFER, 384*sizeof(float), nb_vertices*4*sizeof(float), m_imageColors.data());
glBufferSubData(GL_ARRAY_BUFFER, 768*sizeof(float), nb_vertices*sizeof(float), m_imageColorFactors.data());
glBindVertexArray(m_vaos["imageVao"]);
glDrawArrays(GL_TRIANGLES, 0, nb_vertices);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glUseProgram(0);
m_imageTextures.clear();
m_imageColors.clear();
m_imageColorFactors.clear();
m_imageVertices.clear();
m_imageTextures.reserve(16);
m_imageColors.reserve(96);
m_imageColorFactors.reserve(16);
m_imageVertices.reserve(384);
}
还有着色器:
对于文本:
//The vertex shader
#version 300 es
layout (location = 0) in vec2 vertex;
layout (location = 1) in vec2 tex;
layout (location = 2) in vec4 color;
out vec2 TexCoords;
out vec4 v_color;
flat out int v_textureIndex;
uniform mat4 projection;
void main()
{
gl_Position = projection * vec4(vertex.xy, 1.0, 1.0);
TexCoords = tex;
v_color = color;
v_textureIndex = gl_VertexID / 6;
}
。
//The fragment shader
#version 300 es
precision mediump float;
in vec2 TexCoords;
in vec4 v_color;
flat in int v_textureIndex;
out vec4 color;
uniform sampler2D text0;
uniform sampler2D text1;
uniform sampler2D text2;
uniform sampler2D text3;
uniform sampler2D text4;
uniform sampler2D text5;
uniform sampler2D text6;
uniform sampler2D text7;
uniform sampler2D text8;
uniform sampler2D text9;
uniform sampler2D text10;
uniform sampler2D text11;
uniform sampler2D text12;
uniform sampler2D text13;
uniform sampler2D text14;
uniform sampler2D text15;
vec4 getTexFragment(int index)
{
if(index == 0)
return texture(text0, TexCoords);
else if(index == 1)
return texture(text1, TexCoords);
else if(index == 2)
return texture(text2, TexCoords);
else if(index == 3)
return texture(text3, TexCoords);
else if(index == 4)
return texture(text4, TexCoords);
else if(index == 5)
return texture(text5, TexCoords);
else if(index == 6)
return texture(text6, TexCoords);
else if(index == 7)
return texture(text7, TexCoords);
else if(index == 8)
return texture(text8, TexCoords);
else if(index == 9)
return texture(text9, TexCoords);
else if(index == 10)
return texture(text10, TexCoords);
else if(index == 11)
return texture(text11, TexCoords);
else if(index == 12)
return texture(text12, TexCoords);
else if(index == 13)
return texture(text13, TexCoords);
else if(index == 14)
return texture(text14, TexCoords);
else
return texture(text15, TexCoords);
}
void main()
{
color = v_color * vec4(1.0, 1.0, 1.0, getTexFragment(0).r);
}
对于图像:
//The vertex shader
#version 300 es
layout (location = 0) in vec2 vertex;
layout (location = 1) in vec2 tex;
layout (location = 2) in vec4 color;
layout (location = 3) in float colorFactor;
out vec2 TexCoords;
out vec4 v_color;
out float v_colorFactor;
flat out int v_textureIndex;
uniform mat4 projection;
void main()
{
gl_Position = projection * vec4(vertex.xy, 1.0, 1.0);
TexCoords = tex;
v_color = color;
v_colorFactor = colorFactor;
v_textureIndex = gl_VertexID / 6;
}
。
//The fragment shader
#version 300 es
layout (location = 0) in vec2 vertex;
layout (location = 1) in vec2 tex;
layout (location = 2) in vec4 color;
layout (location = 3) in float colorFactor;
out vec2 TexCoords;
out vec4 v_color;
out float v_colorFactor;
flat out int v_textureIndex;
uniform mat4 projection;
void main()
{
gl_Position = projection * vec4(vertex.xy, 1.0, 1.0);
TexCoords = tex;
v_color = color;
v_colorFactor = colorFactor;
v_textureIndex = gl_VertexID / 6;
}