簡體   English   中英

在QGLWidget中繪制字符串的最簡單方法

[英]The easiest way to draw strings in QGLWidget

我正在使用initializeGL創建一個QGLWidget子類。 resizeGLpaintG 。一切都很好,我也可以使用gluOrtho2D和3D繪制2D圖形。 一切順利。

現在,我需要繪制一些文本,沒有文本旋轉,沒有文本變形,沒有特定字體。 第一次試用是使用glut引擎,但是程序一直崩潰,所以我認為使用QGLWidget glut不能在這種情況下運行。

我已經嘗試過QPainter ,也記得也使用end()方法和swapBuffers ,但是..沒什么,呈現文本但沒有opengl東西。

在QGLWidget上繪制文本的最簡單方法是什么?

通常,我首先將文本渲染到QImage中 ,然后使用glTexSubImage2D將其內容復制到紋理中。 然后我畫一個紋理四邊形。

實際項目中的代碼

void displayText(QString const &text, bool render_text)
{
    if(!text_texture) {
        glGenTextures(1, &text_texture);
    }

    glActiveTexture(GL_TEXTURE0); gltPrintMultiError("glActiveTexture");
    glBindTexture(GL_TEXTURE_2D, text_texture); gltPrintMultiError("glBindTexture");

    int tex_width, tex_height;
    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &tex_width); gltPrintMultiError("glGetTexLevelParameteriv GL_TEXTURE_WIDTH");
    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &tex_height); gltPrintMultiError("glGetTexLevelParameter GL_TEXTURE_HEIGHT");

    if(tex_width != text_width || tex_height != text_height ) {
        render_text = true;
        tex_width = text_width;
        tex_height = text_height;
        glTexImage2D(
            GL_TEXTURE_2D, 0, GL_RGB8,
            tex_width, tex_height, 0,
            GL_RGB, GL_UNSIGNED_BYTE, NULL);
        gltPrintMultiError("glTexImage2D");
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    }

    if(render_text) {
        QImage textimg(tex_width, tex_height, QImage::Format_RGB888);
        {
            QPainter painter(&textimg);
            painter.fillRect(0, 0, tex_width, tex_height, QColor(0,0,0));
            painter.setBrush(QColor(255, 255, 255));
            painter.setPen(QColor(255, 255, 255));
            painter.setFont(QFont("Sans", 15));
            painter.drawText(5, 20, text);
        }

        glPixelStorei(GL_UNPACK_SWAP_BYTES,   GL_FALSE);
        glPixelStorei(GL_UNPACK_LSB_FIRST,    GL_FALSE);
        glPixelStorei(GL_UNPACK_ROW_LENGTH,   0);
        glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
        glPixelStorei(GL_UNPACK_SKIP_ROWS,    0);
        glPixelStorei(GL_UNPACK_SKIP_PIXELS,  0);
        glPixelStorei(GL_UNPACK_SKIP_IMAGES,  0);
        glPixelStorei(GL_UNPACK_ALIGNMENT,    4);

        glTexSubImage2D(
            GL_TEXTURE_2D, 0,
            0, 0,
            tex_width, tex_height,
            GL_RGB, GL_UNSIGNED_BYTE, textimg.constBits() );
    }

    static GLfloat const pos[] = {
        0, 1,
        1, 1,
        1, 0,
        0, 0
    };
    static GLfloat const tex[] = {
        0, 0,
        1, 0,
        1, 1,
        0, 1
    };

    glUseProgram(frame2d.program);

    /* frame2d is a program consisting of the
       following vertex and fragment shaders:
// Vertex Shader
#version 330    
in vec2 position;
in vec2 texcoord;    
out vec2 vert_tex;
void main()
{
    vert_tex = texcoord;
    gl_Position = vec4(position*2 - 1., 0, 1);
}

// Fragment Shader
#version 330
uniform sampler2D frame;
in vec2 vert_tex;    
void main()
{
    gl_FragColor = texture(frame, vert_tex);
}
    */

    glEnableVertexAttribArray(frame2d.attrib_position);
    glEnableVertexAttribArray(frame2d.attrib_texcoord);

    glVertexAttribPointer(frame2d.attrib_position, 2, GL_FLOAT, GL_FALSE, 0, pos);
    gltPrintMultiError("glVertexAttribPointer(attrib_position, ...)");
    glVertexAttribPointer(frame2d.attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 0, tex);
    gltPrintMultiError("glVertexAttribPointer(attrib_texcoord, ...)");
    glUniform1i(frame2d.uniform_sampler_frame, 0);
    gltPrintMultiError("glUniform1i(frame2d.uniform_sampler_frame)");

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR);

    glViewport(0, 0, tex_width, tex_height);

    glDisable(GL_DEPTH_TEST);
    glDepthMask(0);
    glColorMask(1,1,1,1);

    glDrawArrays(GL_QUADS, 0, 4);

    glDisableVertexAttribArray(frame2d.attrib_position);
    glDisableVertexAttribArray(frame2d.attrib_texcoord);
    glUseProgram(0);

    glBindTexture(GL_TEXTURE_2D, 0);
}

我不知道,但是QGLWidget類中還內置了renderText方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM