我正试图用Qt在opengl中使用rtt。为了测试我尝试将红色三角形渲染到FBO,然后将其作为纹理并渲染纹理矩形。我希望它看起来像
纹理大小64x64。它看起来不错,不是吗?
然后我将它渲染到FBO,然后将矩形渲染到屏幕和上一个陡峭创建的纹理。我得到了这个:
看起来像纹理的大小非常巨大,它覆盖所有矩形或这样的想法,我不知道。我究竟做错了什么?我的三角形在哪里? =)
感谢您的帮助。
我的代码:
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);
}