RTT OpenGL不起作用

时间:2017-09-26 07:32:13

标签: c++ qt opengl opengl-3 fbo

我正试图用Qt在opengl中使用rtt。为了测试我尝试将红色三角形渲染到FBO,然后将其作为纹理并渲染纹理矩形。我希望它看起来像enter image description here

我可以渲染给FBO。如果我将它渲染到屏幕上,我可以看到: enter image description here

纹理大小64x64。它看起来不错,不是吗?

然后我将它渲染到FBO,然后将矩形渲染到屏幕和上一个陡峭创建的纹理。我得到了这个: enter image description here

看起来像纹理的大小非常巨大,它覆盖所有矩形或这样的想法,我不知道。我究竟做错了什么?我的三角形在哪里? =)

感谢您的帮助。

我的代码:

class TriangleWindow : public QOpenGLWidget, protected QOpenGLFunctions_3_3_Core
{
public:
    TriangleWindow();

private:
    GLuint m_posAttr;
    GLuint m_text_pos;
    GLuint VBO[2];
    QOpenGLShaderProgram* render_texture_program;
    GLuint FBO;

    QOpenGLShaderProgram* m_program;
    GLuint texture1, texture2;

    // QOpenGLWidget interface
protected:
    void initializeGL();

    void paintGL();
    void render();
    void init_FBO();
};

TriangleWindow::TriangleWindow()
    : m_program(0)
{
}
int main(int argc, char** argv)
{
    QApplication app(argc, argv);

    QSurfaceFormat format;
    format.setSamples(16);

    TriangleWindow window;
    window.setFormat(format);
    window.resize(640, 480);
    window.show();

    return app.exec();
}
const char* vertexShaderSource_tex = "attribute highp vec4 posAttr;\n"
                                     "void main() {\n"
                                     "   gl_Position =  posAttr;\n"
                                     "}\n";

const char* fragmentShaderSource_tex = "out varying vec4 flatColor;\n"
                                       "void main() {\n"
                                       "   flatColor = vec4(0.2,0.0,0.0,1.0);\n"
                                       "}\n";

const char* vertexShaderSource = "attribute highp vec4 posAttr;\n"
                                 "attribute highp vec2 text_pos;\n"
                                 "varying highp vec2 t_pos;\n"
                                 "void main() {\n"
                                 "   t_pos = vec2(text_pos.x, 1.0-text_pos.y);//posAttr.xy;//text_pos;\n"
                                 "   gl_Position =  posAttr;\n"
                                 "}\n";

const char* fragmentShaderSource = "varying highp vec2 t_pos;\n"
                                   "out varying vec4 flatColor;\n"
                                   "uniform sampler2D ourTexture;\n"
                                   "void main() {\n"
                                   "   flatColor = texture2D(ourTexture,t_pos);\n"
                                   "}\n";

void TriangleWindow::init_FBO()
{
    render_texture_program = new QOpenGLShaderProgram(this);

    render_texture_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource_tex);
    render_texture_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource_tex);
    render_texture_program->link();

    render_texture_program->bind();

    // ====================
    // Texture 2
    // ====================
    glGenTextures(1, &texture2);
    glBindTexture(GL_TEXTURE_2D, texture2); // All upcoming GL_TEXTURE_2D operations now have effect on our texture object
    //    // Set our texture parameters
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    // Set texture filtering
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    // Load, create texture and generate mipmaps
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); // texture_data);
    glBindTexture(GL_TEXTURE_2D, 0); // Unbind texture when done, so we won't accidentily mess up our texture.

    glGenFramebuffers(1, &FBO);
    glBindFramebuffer(GL_FRAMEBUFFER, FBO);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture2, 0);
    GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
    glDrawBuffers(1, DrawBuffers);
    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
        qDebug() << glCheckFramebufferStatus(GL_FRAMEBUFFER);

    GLfloat vertices[]
        = {
            -0.9f, 0.9f,
            -0.9f, -0.9f,
            0.9f, -0.9f,
            0.9f, 0.9f,
          };

    glGenBuffers(1, &VBO[1]);

    glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glVertexAttribPointer(render_texture_program->attributeLocation("posAttr"),
        2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void TriangleWindow::initializeGL()
{

    initializeOpenGLFunctions();

    m_program = new QOpenGLShaderProgram(this);

    m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
    m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);

    m_program->link();

    m_posAttr = m_program->attributeLocation("posAttr");
    m_text_pos = m_program->attributeLocation("text_pos");

    const qreal retinaScale = devicePixelRatio();
    glEnable(GL_TEXTURE_2D);
    glViewport(0, 0, width() * retinaScale, height() * retinaScale);

    m_program->bind();

    glGenBuffers(2, VBO);

    GLfloat vertices[] = {
        -0.85f, 0.85f, 0.0f, 1.0f,
        -0.85f, -0.85f, 0.0f, 0.0f,
        0.85f, -0.85f, 1.0f, 0.0f,
        0.85f, 0.85f, 1.0f, 1.0f,
    };

    glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glVertexAttribPointer(m_posAttr, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)0);
    glVertexAttribPointer(m_text_pos, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)(2 * sizeof(GLfloat)));
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    init_FBO();
}

void TriangleWindow::render()
{
    glBindFramebuffer(GL_FRAMEBUFFER, FBO);
    render_texture_program->bind();
    glViewport(0, 0, 64, 64);
    glClearColor(0.3f, 0.3f, 0.1f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(render_texture_program->attributeLocation("posAttr"),
        2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)0);
    glDrawArrays(GL_POLYGON, 0, 3);
    glDisableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    render_texture_program->release();
    glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject());
}

void TriangleWindow::paintGL()
{
    render();
    glViewport(0, 0, width(), height());
    glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
    glVertexAttribPointer(m_posAttr, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)0);
    glVertexAttribPointer(m_text_pos, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)(2 * sizeof(GLfloat)));
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);

    glBindTexture(GL_TEXTURE_2D, texture2);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture wrapping to GL_REPEAT
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glClearColor(0.1f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glActiveTexture(GL_TEXTURE1);

    glDrawArrays(GL_POLYGON, 0, 4);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);

    glBindTexture(GL_TEXTURE_2D, 0);
}

0 个答案:

没有答案