#include "renderer.h"
#include <QDebug>
#include <QElapsedTimer>
#include <QtMath>
#include <QMatrix4x4>
Renderer::Renderer(QObject *parent)
: QObject(parent)
{
init();
}
Renderer::~Renderer()
{
uninit();
}
void Renderer::render(int width, int height)
{
if (m_width != width || m_height != height)
{
m_width = width;
m_height = height;
adjustSize();
}
static float degree = 0.0f;
degree += 1.0f;
QMatrix4x4 rotate;
rotate.setToIdentity();
rotate.rotate(degree, 0, 0, 1);
glViewport(m_viewportX, m_viewportY, m_viewportWidth, m_viewportHeight);
glClear(GL_COLOR_BUFFER_BIT);
m_program.bind();
//设置缩放
m_program.setUniformValue("u_scale", QVector2D(1.0f, 1.0f));
//设置位置
m_program.setUniformValue("u_position", QVector2D(0.0f, 0.0f));
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glDrawArrays(GL_TRIANGLES, 0, 4);
glBindBuffer(GL_ARRAY_BUFFER, 0);
m_program.release();
glFinish();
}
void Renderer::init()
{
initializeOpenGLFunctions();
// glEnable(GL_DEBUG_OUTPUT);
// glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
// glDebugMessageCallback(glDebugOutput, nullptr);
qDebug() << reinterpret_cast<const char *>(glGetString(GL_VERSION));
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glGenFramebuffers(1, &m_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
glGenTextures(1, &m_texture);
glBindTexture(GL_TEXTURE_2D, m_texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
glGenRenderbuffers(1, &m_rbo);
adjustSize();
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_rbo);
// 着色器编译和链接
if (!m_program.addShaderFromSourceFile(QGLShader::Vertex, ":/vertex.glsl")) {
qDebug() << "Vertex shader log:" << m_program.log();
}
if (!m_program.addShaderFromSourceFile(QGLShader::Fragment, ":/fragment.glsl")) {
qDebug() << "Fragment shader log:" << m_program.log();
}
// 绑定属性位置
m_program.bindAttributeLocation("vertexIn", 0);
m_program.bindAttributeLocation("textureIn", 1);
m_program.link();
// 顶点坐标 (x, y) 和纹理坐标 (s, t)
static const GLfloat vertices[] = {
// 顶点坐标 // 纹理坐标
-1.0f, -1.0f, 0.0f, 1.0f, // gl_VertexID=0
1.0f, -1.0f, 1.0f, 1.0f, // gl_VertexID=1
-1.0f, 1.0f, 0.0f, 0.0f, // gl_VertexID=2
1.0f, 1.0f, 1.0f, 0.0f // gl_VertexID=3
};
glGenBuffers(1, &m_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void Renderer::uninit()
{
glDeleteRenderbuffers(1, &m_rbo);
glDeleteTextures(1, &m_texture);
glDeleteFramebuffers(1, &m_fbo);
}
void Renderer::adjustSize()
{
glBindTexture(GL_TEXTURE_2D, m_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_width, m_height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
glBindTexture(GL_TEXTURE_2D, 0);
glBindRenderbuffer(GL_RENDERBUFFER, m_rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_width, m_height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
if (m_width > m_height)
{
m_viewportX = (m_width - m_height) / 2;
m_viewportY = 0;
m_viewportWidth = m_height;
m_viewportHeight = m_height;
}
else
{
m_viewportX = 0;
m_viewportY = (m_height - m_width) / 2;
m_viewportWidth = m_width;
m_viewportHeight = m_width;
}
}
将一张图片离屏渲染到fbo中
最新发布