【发布时间】:2016-06-18 21:27:19
【问题描述】:
我正在尝试使用帧缓冲区进行屏幕外渲染立方体。然后我尝试使用其纹理将其转换为纹理。我遇到的问题是当我尝试将该纹理放在飞机上时。纹理颜色基于一种原色:芦苇、绿色或蓝色。我不知道问题出在哪里,也许是从浮动到加倍的演员问题?我真的不知道该怎么想或去哪里探索。
这是我得到的 gif 图像。在这个 gif 中,您可以看到没有离屏渲染的普通立方体。第二个绿色立方体是打印在平面上的帧缓冲区纹理:
这是我使用的代码。它基于Qt,但与过剩没有区别。我解释它是为了更容易理解:
- initializeGL:我声明了帧缓冲区及其附件
- PaintGL:如果我不“左键单击”启用此功能,则无需使用 FB 即可绘制立方体(gif 的第一部分,效果很好)。如果我左键单击,则例程会更改并在 FrameBuffer 上绘制立方体,然后我在平面上绘制其纹理。 (gif 的第二部分,它将我的纹理涂成绿色)
- setProyection:为普通立方体绘制设置 glOrtho。
#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
【问题讨论】:
-
您好,欢迎来到 StackOverflow。我确实觉得这对于新手来说是一个非常高质量的问题,但请随时花一些时间阅读帮助页面,尤其是名为 "What topics can I ask about here?" 和 "What types of questions should I avoid asking?" 的部分。更重要的是,请阅读the Stack Overflow question checklist。您可能还想了解Minimal, Complete, and Verifiable Examples。
-
如果您有更多想问的问题,您可能会很感激理解这些内容以供以后的问题。
-
“i”需要大写,否则您的问题将不会被验证。
标签: c++ qt opengl framebuffer