0

QGLWidgetでサブクラスを作成していinitializeGLます。resizeGLpaintGL.すべて問題ありません。gluOrtho2Dと3Dでも2Dグラフィックを描画できます。すべて順調。

ここで、テキストを描画する必要があります。テキストの回転、テキストの変形、特定のフォントは必要ありません。最初の試行は glut エンジンを使用したものでしたが、プログラムがクラッシュし続けたため、QGLWidget の glut はそのコンテキストでは機能しないと考えました。

メソッドもQPainter使用することを忘れないでください、しかし..何も、テキストはレンダリングされませんが、openglのものはありません..end()swapBuffers

QGLWidget にテキストを描画する最も簡単な方法は何ですか?

4

2 に答える 2

3

通常、これを行うには、最初にテキストを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);
}
于 2013-05-08T18:02:29.037 に答える
2

知りませんでしたがQGLWidget クラスにもrenderTextメソッドが組み込まれています。

于 2013-05-12T09:16:46.657 に答える