OpenGL ES具有多种纹理,但仅绘制了一层

时间:2018-07-30 10:49:07

标签: c++ opengl-es textures

我面临一个奇怪的问题。

我目前正在嵌入式设备上进行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;
}

0 个答案:

没有答案