C++ FreeType-纹理图集-为什么我的文本呈现为四边形?

C++ FreeType-纹理图集-为什么我的文本呈现为四边形?,c++,opengl-es,glsl,freetype,texture-atlas,C++,Opengl Es,Glsl,Freetype,Texture Atlas,我目前正在尝试改进我的文本呈现。渲染每个角色的基本方法是单独工作的,但现在我想通过渲染纹理图集在一次绘制调用中完成所有工作。 纹理图谱几乎完成了。它确实将文本呈现为四边形,但我不知道如何解决alpha问题。 R、G和B的值均为零 我还尝试了GL\u ALPHA,GL\u RGBA和GL\u亮度 注意:我正在开发一个树莓圆周率并使用OpenGL ES 2.0 所有字体字符的图像: 着色器: precision mediump float; attribute vec4 vertex; var

我目前正在尝试改进我的文本呈现。渲染每个角色的基本方法是单独工作的,但现在我想通过渲染纹理图集在一次绘制调用中完成所有工作。 纹理图谱几乎完成了。它确实将文本呈现为四边形,但我不知道如何解决alpha问题。 RGB的值均为零

我还尝试了
GL\u ALPHA
GL\u RGBA
GL\u亮度

注意:我正在开发一个树莓圆周率并使用OpenGL ES 2.0

所有字体字符的图像

着色器

precision mediump float;

attribute vec4 vertex;

varying vec2 textCoord;

void main()
{
   gl_Position = vec4(vertex.xy, 0.0, 1.0);
   textCoord = vertex.zw;
}
// Set uniforms
    a_Shader->SetVec3("textColor", m_v3Color);

    glActiveTexture(GL_TEXTURE0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);

    point coords[6 * 128];
    int dc = 0;

    const uint8_t *p;

    float sx = 2.0 / SCREEN_WIDTH;
    float sy = 2.0 / SCREEN_HEIGHT;

//  float x = (m_v2Position.x - (SCREEN_WIDTH / 2)) * sx;
    //float y = (m_v2Position.y - (SCREEN_HEIGHT / 2)) * sy;

    float x = -1.f;
    float y = 0.f;

    // Loop through all characters 
    for (int p = 0; p < 128; p++) {
        // Calculate the vertex and texture coordinates 
        float x2 = x + c[p].bl * sx;
        float y2 = -y - c[p].bt * sy;
        float w = c[p].bw * sx;
        float h = c[p].bh * sy;

        // Advance the cursor to the start of the next character 
        x += c[p].ax * sx;
        y += c[p].ay * sy;

        // Skip glyphs that have no pixels 
        if (!w || !h)
            continue;

        coords[dc++] = (point) {
            x2, -y2, c[p].tx, c[p].ty
        };
        coords[dc++] = (point) {
            x2 + w, -y2, c[p].tx + c[p].bw / w, c[p].ty
        };
        coords[dc++] = (point) {
            x2, -y2 - h, c[p].tx, c[p].ty + c[p].bh / h
        };
        coords[dc++] = (point) {
            x2 + w, -y2, c[p].tx + c[p].bw / w, c[p].ty
        };
        coords[dc++] = (point) {
            x2, -y2 - h, c[p].tx, c[p].ty + c[p].bh / h
        };
        coords[dc++] = (point) {
            x2 + w, -y2 - h, c[p].tx + c[p].bw / w, c[p].ty + c[p].bh / h
        };
    }

    // Render glyph texture over quad
    glBindTexture(GL_TEXTURE_2D, tex);

    // Update content of VBO memory
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(coords), coords, GL_DYNAMIC_DRAW); 
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    // Render quad
    glDrawArrays(GL_TRIANGLES, 0, dc);

    glDisableVertexAttribArray(0);
    glBindTexture(GL_TEXTURE_2D, 0);

    glCheckError(); 
设置纹理图谱

glGenBuffers(1,&vbo);
if(FT_Init_FreeType(&m_FT)){
std::cout glyph->bitmap.width+1;
rowh=std::max(rowh,m_Face->glyph->bitmap.rows);
}
w=标准::最大值(w,roww);
h+=行;
//创建将用于保存所有ASCII图示符的纹理
玻璃纹理(GL_纹理0);
glGenTextures(1和tex);
glBindTexture(GL_TEXTURE_2D,tex);
GetShader()->Use();
GetShader()->SetInt(“文本”,tex);
GLTEXAGE2D(GL_纹理_2D,0,GL_RGBA,w,h,0,GL_RGBA,GL_无符号_字节,0);
//上传纹理数据时,我们需要1字节对齐
glPixelStorei(GLU解包对齐,1);
glTexParameteri(GL_纹理_2D、GL_纹理_包裹、GL_夹紧_至_边缘);
glTexParameteri(GL_纹理\u 2D、GL_纹理\u包裹\u T、GL_夹紧\u至\u边缘);
glTexParameteri(GL_纹理2D、GL_纹理最小过滤器、GL_线性);
glTexParameteri(GL_纹理2D、GL_纹理MAG_过滤器、GL_线性);
//将所有轮廓位图粘贴到纹理中,记住偏移
int-ox=0;
int-oy=0;
rowh=0;
对于(int i=0;i<128;i++){
if(FT_Load_Char(m_Face,i,FT_Load_RENDER)){
fprintf(stderr,“加载字符%c失败!\n”,i);
继续;
}
如果(ox+m_面->字形->位图.width+1>=屏幕宽度){
oy+=rowh;
rowh=0;
ox=0;
}
glTexSubImage2D(GL_纹理_2D,0,ox,oy,m_面->字形->位图.width,m_面->字形->位图.rows,GL_RGBA,GL_无符号_字节,m_面->字形->位图.buffer);
c[i].ax=m_Face->glyph->advance.x>>6;
c[i].ay=m_Face->glyph->advance.y>>6;
c[i].bw=m_Face->glyph->bitmap.width;
c[i].bh=m_Face->glyph->bitmap.rows;
c[i].bl=m_面->字形->位图左;
c[i].bt=m\u Face->glyph->bitmap\u top;
c[i].tx=ox/(浮点数)w;
c[i].ty=oy/(浮点数)h;
rowh=std::max(rowh,m_Face->glyph->bitmap.rows);
ox+=m_Face->glyph->bitmap.width+1;
}
fprintf(stderr,“生成了一个%d x%d(%d kb)纹理图集\n”,w,h,w*h/1024);
GetShader()->Stop();
glBindTexture(GL_TEXTURE_2D,0);
绘图功能

precision mediump float;

attribute vec4 vertex;

varying vec2 textCoord;

void main()
{
   gl_Position = vec4(vertex.xy, 0.0, 1.0);
   textCoord = vertex.zw;
}
// Set uniforms
    a_Shader->SetVec3("textColor", m_v3Color);

    glActiveTexture(GL_TEXTURE0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);

    point coords[6 * 128];
    int dc = 0;

    const uint8_t *p;

    float sx = 2.0 / SCREEN_WIDTH;
    float sy = 2.0 / SCREEN_HEIGHT;

//  float x = (m_v2Position.x - (SCREEN_WIDTH / 2)) * sx;
    //float y = (m_v2Position.y - (SCREEN_HEIGHT / 2)) * sy;

    float x = -1.f;
    float y = 0.f;

    // Loop through all characters 
    for (int p = 0; p < 128; p++) {
        // Calculate the vertex and texture coordinates 
        float x2 = x + c[p].bl * sx;
        float y2 = -y - c[p].bt * sy;
        float w = c[p].bw * sx;
        float h = c[p].bh * sy;

        // Advance the cursor to the start of the next character 
        x += c[p].ax * sx;
        y += c[p].ay * sy;

        // Skip glyphs that have no pixels 
        if (!w || !h)
            continue;

        coords[dc++] = (point) {
            x2, -y2, c[p].tx, c[p].ty
        };
        coords[dc++] = (point) {
            x2 + w, -y2, c[p].tx + c[p].bw / w, c[p].ty
        };
        coords[dc++] = (point) {
            x2, -y2 - h, c[p].tx, c[p].ty + c[p].bh / h
        };
        coords[dc++] = (point) {
            x2 + w, -y2, c[p].tx + c[p].bw / w, c[p].ty
        };
        coords[dc++] = (point) {
            x2, -y2 - h, c[p].tx, c[p].ty + c[p].bh / h
        };
        coords[dc++] = (point) {
            x2 + w, -y2 - h, c[p].tx + c[p].bw / w, c[p].ty + c[p].bh / h
        };
    }

    // Render glyph texture over quad
    glBindTexture(GL_TEXTURE_2D, tex);

    // Update content of VBO memory
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(coords), coords, GL_DYNAMIC_DRAW); 
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    // Render quad
    glDrawArrays(GL_TRIANGLES, 0, dc);

    glDisableVertexAttribArray(0);
    glBindTexture(GL_TEXTURE_2D, 0);

    glCheckError(); 
//设置制服
a_Shader->SetVec3(“textColor”,m_v3Color);
玻璃纹理(GL_纹理0);
glBindBuffer(GL_数组_BUFFER,0);
glBindBuffer(GL_数组_BUFFER,vbo);
GlenableVertexAttributeArray(0);
glvertexattributepointer(0,4,GL_FLOAT,GL_FALSE,0,0);
点坐标[6*128];
int dc=0;
const uint8_t*p;
浮动sx=2.0/屏幕宽度;
浮子sy=2.0/屏幕高度;
//浮动x=(m_v2Position.x-(屏幕宽度/2))*sx;
//浮动y=(m_v2Position.y-(屏幕高度/2))*sy;
浮动x=-1.f;
浮动y=0.f;
//循环遍历所有字符
对于(int p=0;p<128;p++){
//计算顶点和纹理坐标
浮点数x2=x+c[p].bl*sx;
浮点y2=-y-c[p].bt*sy;
浮点数w=c[p].bw*sx;
浮点数h=c[p].bh*sy;
//将光标移到下一个字符的开头
x+=c[p].ax*sx;
y+=c[p].ay*sy;
//跳过没有像素的图示符
如果(!w | |!h)
继续;
坐标[dc++]=(点){
x2,-y2,c[p].tx,c[p].ty
};
坐标[dc++]=(点){
x2+w,-y2,c[p].tx+c[p].bw/w,c[p].ty
};
坐标[dc++]=(点){
x2,-y2-h,c[p].tx,c[p].ty+c[p].bh/h
};
坐标[dc++]=(点){
x2+w,-y2,c[p].tx+c[p].bw/w,c[p].ty
};
坐标[dc++]=(点){
x2,-y2-h,c[p].tx,c[p].ty+c[p].bh/h
};
坐标[dc++]=(点){
x2+w,-y2-h,c[p].tx+c[p].bw/w,c[p].ty+c[p].bh/h
};
}
//在四边形上渲染轮廓纹理
glBindTexture(GL_TEXTURE_2D,tex);
//更新VBO内存的内容
glBindBuffer(GL_数组_BUFFER,vbo);
glBufferData(GL_数组_缓冲区、sizeof(coords)、coords、GL_动态_绘图);
glBindBuffer(GL_数组_BUFFER,0);
//渲染四边形
gldrawArray(GL_三角形,0,dc);
glDisableVertexAttributeArray(0);
glBindTexture(GL_TEXTURE_2D,0);
glCheckError();

m_Face->glyph->bitmap提供的缓冲区。buffer
是一个具有单一颜色通道的缓冲区。由于使用了OpenGL ES,纹理的源格式必须是
GL\u亮度

指定具有单个(红色)颜色通道的二维纹理图像。纹理行的对齐必须设置为1(请参见)。注意:默认值为4,与每像素1字节大小的紧密压缩纹理不匹配:

glPixelStorei(GL_解包_对齐,1);
GLTEXAGE2D(GL_纹理_2D,0,GL_亮度,w,h,0,GL_亮度,GL_无符号字节,0);
注意,由于纹理不是2的幂,因此无法使用mip贴图,因此纹理缩小功能必须是
GL\u最近的
GL\u线性
,并且包裹模式必须是
GL\u夹紧到

glTexParameteri(GL\u纹理\u 2D、GL\u纹理\u包裹、GL\u夹紧到边);
glTexParameteri(GL_纹理\u 2D、GL_纹理\u包裹\u T、GL_夹紧\u至\u边缘);
glTexParameteri(GL_纹理2D、GL_纹理最小过滤器、GL_线性);
glTexParameteri(G