opengl Framebuffer offscreen到纹理,颜色错误

时间:2016-06-18 21:27:19

标签: c++ qt opengl framebuffer

我试图使用帧缓冲来进行屏幕外渲染立方体。然后我尝试使用其纹理将其转换为纹理。我得到的问题是当我尝试将该纹理放在一个平面上时。纹理颜色基于一种主要颜色是完整的:芦苇,绿色或蓝色。我不知道问题出在哪里,也许是浮动到双重的投射问题?我真的不知道该想什么或在哪里探索。

这是我得到的gif。在这个gif中你可以看到没有屏幕外渲染的普通立方体。第二个绿色立方体是打印在平面上的帧缓冲纹理:

Cube error

这是我使用的代码。它基于Qt,但这与过剩没有区别。我解释一下是为了更容易理解:

  1. initializeGL:我声明了帧缓冲及其附件
  2. PaintGL:在不使用FB的情况下绘制立方体,如果我没有"左键单击"启用此(gif的第一部分,它完美无缺)。如果我左键单击,则例程更改并在FrameBuffer上绘制立方体,然后在平面上绘制其纹理。 (gif的第二部分,它将我的纹理描绘成绿色)
  3. setProyection:设置正常立方体绘制的glOrtho。

  4. #include "WidgetOpenGL.h"
    
    WidgetOpenGL::WidgetOpenGL(QWidget *parent) : QOpenGLWidget(parent)
    {
    
    }
    
    void WidgetOpenGL::initializeGL()
    {
        desplazamientoX = 1;
        desplazamientoY = 0;
        initializeOpenGLFunctions();
        glClearColor(0.0, 0.0, 0.0, 0.0);
        glEnable(GL_DEPTH_TEST);
        buttonpressed = false;
        glGenFramebuffers(1, &buffer);
        glBindFramebuffer(GL_FRAMEBUFFER, buffer);
        glGenTextures(1, &renderedTexture);
        glBindTexture(GL_TEXTURE_2D, renderedTexture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 768, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glGenRenderbuffers(1, &renderedDepth);
        glBindRenderbuffer(GL_RENDERBUFFER, renderedDepth);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 1024, 768);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderedDepth);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderedTexture, 0);
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        setProyection();
        setModelView();
    }
    
    void WidgetOpenGL::paintGL()
    {
        if (buttonpressed)
        {
            glBindFramebuffer(GL_FRAMEBUFFER, buffer);
            glViewport(0, 0, 1024, 768);
        }
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        setProyection();
        setModelView();
        glTranslatef(0.0, 0.0, -2.0);
        setRotation();
    
        glBegin(GL_QUADS);
        // top
        glColor3f(1.0f, 0.0f, 0.0f);
        glNormal3f(0.0f, 1.0f, 0.0f);
        glVertex3f(-0.5f, 0.5f, 0.5f);
        glVertex3f(0.5f, 0.5f, 0.5f);
        glVertex3f(0.5f, 0.5f, -0.5f);
        glVertex3f(-0.5f, 0.5f, -0.5f);
    
        glEnd();
    
        glBegin(GL_QUADS);
        // front
        glColor3f(0.0f, 1.0f, 0.0f);
        glNormal3f(0.0f, 0.0f, 1.0f);
        glVertex3f(-0.5f, -0.5f, 0.5f);
        glVertex3f(0.5f, -0.5f, 0.5f);
        glVertex3f(0.5f, 0.5f, 0.5f);
        glVertex3f(-0.5f, 0.5f, 0.5f);
    
        glEnd();
    
        glBegin(GL_QUADS);
        // right
        glColor3f(0.0f, 0.0f, 1.0f);
        glNormal3f(1.0f, 0.0f, 0.0f);
        glVertex3f(0.5f, -0.5f, 0.5f);
        glVertex3f(0.5f, -0.5f, -0.5f);
        glVertex3f(0.5f, 0.5f, -0.5f);
        glVertex3f(0.5f, 0.5f, 0.5f);
    
        glEnd();
    
        glBegin(GL_QUADS);
        // left
        glColor3f(0.0f, 0.0f, 0.5f);
        glNormal3f(-1.0f, 0.0f, 0.0f);
        glVertex3f(-0.5f, -0.5f, 0.5f);
        glVertex3f(-0.5f, 0.5f, 0.5f);
        glVertex3f(-0.5f, 0.5f, -0.5f);
        glVertex3f(-0.5f, -0.5f, -0.5f);
    
        glEnd();
    
        glBegin(GL_QUADS);
        // bottom
        glColor3f(0.5f, 0.0f, 0.0f);
        glNormal3f(0.0f, -1.0f, 0.0f);
        glVertex3f(-0.5f, -0.5f, 0.5f);
        glVertex3f(0.5f, -0.5f, 0.5f);
        glVertex3f(0.5f, -0.5f, -0.5f);
        glVertex3f(-0.5f, -0.5f, -0.5f);
    
        glEnd();
    
        glBegin(GL_QUADS);
        // back
        glColor3f(0.0f, 0.5f, 0.0f);
        glNormal3f(0.0f, 0.0f, -1.0f);
        glVertex3f(0.5f, 0.5f, -0.5f);
        glVertex3f(0.5f, -0.5f, -0.5f);
        glVertex3f(-0.5f, -0.5f, -0.5f);
        glVertex3f(-0.5f, 0.5f, -0.5f);
    
        glEnd();
        glFlush();
    
        if (buttonpressed)
        {
            glBindFramebuffer(GL_FRAMEBUFFER, 0);
            //      QImage img = frameBuffer->toImage();
            //      img.save("Hola.jpg");
    
            //draw plane with texture
            setViewport();
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            glOrtho(-2.0, 2.0, -2.0, 2.0, -2.0, 2.0);
            glMatrixMode(GL_MODELVIEW);
            glLoadIdentity();
            glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            glEnable(GL_TEXTURE_2D);
            glBindTexture(GL_TEXTURE_2D, renderedTexture);
            glBegin(GL_QUADS);
            glTexCoord2d(0.0f, 0.0f);
            glVertex3f(-1.0, -1.0, -1.0);
            glTexCoord2d(1.0f, 0.0f);
            glVertex3f(1.0, -1.0, -1);
            glTexCoord2d(1.0f, 1.0f);
            glVertex3f(1.0, 1.0, -1.0);
            glTexCoord2d(0.0f, 1.0f);
            glVertex3f(-1.0, 1.0, -1.0);
            glEnd();
            glBindTexture(GL_TEXTURE_2D, 0);
            glDisable(GL_TEXTURE_2D);
            glFlush();
        }
    }
    
    void WidgetOpenGL::resizeGL(int w, int h)
    {
        setViewport();
        setProyection();
        setModelView();
    }
    
    void WidgetOpenGL::setViewport()
    {
        int ancho = this->width();
        int alto = this->height();
        glViewport(0, 0, ancho, alto);
    }
    
    void WidgetOpenGL::setProyection()
    {
        int ancho = this->width();
        int alto = this->height();
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 10.0);
        //gluPerspective(90.0f, ancho / (GLdouble)alto, 0.0f, 10.0f);
    }
    
    void WidgetOpenGL::setModelView()
    {
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
    }
    
    void WidgetOpenGL::mouseMoveEvent(QMouseEvent *event)
    {
        desplazamientoY += ((event->x() - initX) * 360) / (GLdouble)width();
        desplazamientoX += ((event->y() - initY) * 360) / (GLdouble)height();
        initX = event->x();
        initY = event->y();
    
        if (((int)desplazamientoX % 360) == 0) desplazamientoX = 0;
        if (((int)desplazamientoY % 360) == 0) desplazamientoY = 0;
        repaint();
    
    }
    
    void WidgetOpenGL::mousePressEvent(QMouseEvent *event)
    {
        if (event->button() == Qt::LeftButton)
        {
            initX = event->x();
            initY = event->y();
        }
        else
        {
            buttonpressed = !buttonpressed;
            repaint();
        }
    }
    
    void WidgetOpenGL::setRotation()
    {
        glRotatef(desplazamientoX, 1.0, 0.0, 0.0);
        glRotatef(desplazamientoY, 0.0, 1.0, 0.0);
    }
    

    如果需要,这是头文件:

    #ifndef WIDGETOPENGL_H
    #define WIDGETOPENGL_H
    #include <QtWidgets/QMainWindow>
    #include <QtWidgets/qopenglwidget.h>
    #include <QtOpenGL>
    #include <GL/GLU.h>
    
    
    class WidgetOpenGL : public QOpenGLWidget, protected QOpenGLFunctions
    {
        Q_OBJECT
    
    public:
        WidgetOpenGL(QWidget *parent);
    
    signals:
        void screenClicked();
    protected:
        void initializeGL();
        void paintGL();
        void resizeGL(int w, int h);
    
        void setViewport();
        void setProyection();
        void setModelView();
    
    private:
        int initX;
        int initY;
        QOpenGLFramebufferObject *frameBuffer;
        GLuint buffer;
        GLuint renderedTexture;
        GLuint renderedDepth;
        bool buttonpressed;
        QImage image;
        GLdouble desplazamientoX;
        GLdouble desplazamientoY;
        void setRotation();
        void mouseMoveEvent(QMouseEvent *event);
        void mousePressEvent(QMouseEvent *event);
    
    };
    
    #endif
    

1 个答案:

答案 0 :(得分:0)

解决!问题是我在绿色平面上绘制纹理。那是因为最后的glcolor3f是绿色的(当我绘制真实立方体的背板时使用)。

我只需要在绘制平面之前添加glColor3f(1.0,1.0,1.0),以制作白色平面。