Qt实现3D照片墙代码项目
时间: 2024-05-18 12:18:14 浏览: 90
3D照片墙图片展示特效代码
5星 · 资源好评率100%
以下是一个简单的Qt实现3D照片墙的代码项目,供参考:
main.cpp:
```
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
```
mainwindow.h:
```
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLTexture>
class MainWindow : public QMainWindow, protected QOpenGLFunctions
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
protected:
void initializeGL();
void resizeGL(int w, int h);
void paintGL();
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void wheelEvent(QWheelEvent *event);
private:
QOpenGLWidget *m_widget;
QOpenGLTexture *m_texture;
GLuint m_program;
GLuint m_vbo;
GLuint m_ibo;
GLfloat m_angleX;
GLfloat m_angleY;
QPoint m_lastPos;
};
#endif // MAINWINDOW_H
```
mainwindow.cpp:
```
#include "mainwindow.h"
#include <QMouseEvent>
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>
const char *vertexShaderSource =
"attribute vec3 a_position;\n"
"attribute vec2 a_texCoord;\n"
"uniform mat4 u_modelViewProjectionMatrix;\n"
"varying vec2 v_texCoord;\n"
"void main()\n"
"{\n"
" gl_Position = u_modelViewProjectionMatrix * vec4(a_position, 1.0);\n"
" v_texCoord = a_texCoord;\n"
"}\n";
const char *fragmentShaderSource =
"varying vec2 v_texCoord;\n"
"uniform sampler2D u_texture;\n"
"void main()\n"
"{\n"
" gl_FragColor = texture2D(u_texture, v_texCoord);\n"
"}\n";
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), m_widget(nullptr), m_texture(nullptr), m_program(0), m_vbo(0), m_ibo(0), m_angleX(0.0f), m_angleY(0.0f)
{
m_widget = new QOpenGLWidget(this);
setCentralWidget(m_widget);
}
MainWindow::~MainWindow()
{
makeCurrent();
glDeleteProgram(m_program);
glDeleteBuffers(1, &m_vbo);
glDeleteBuffers(1, &m_ibo);
delete m_texture;
doneCurrent();
}
void MainWindow::initializeGL()
{
initializeOpenGLFunctions();
// load texture
m_texture = new QOpenGLTexture(QImage(":/images/image.png").mirrored());
// shader program
QOpenGLShaderProgram program;
program.addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
program.link();
m_program = program.programId();
// vertex data
GLfloat vertices[] = {
-1.0f, 1.0f, -1.0f, 0.0f, 1.0f,
1.0f, 1.0f, -1.0f, 1.0f, 1.0f,
1.0f, -1.0f, -1.0f, 1.0f, 0.0f,
-1.0f, -1.0f, -1.0f, 0.0f, 0.0f,
-1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, -1.0f, 1.0f, 1.0f, 0.0f,
-1.0f, -1.0f, 1.0f, 0.0f, 0.0f,
};
// index data
GLuint indices[] = {
0, 1, 2, 0, 2, 3,
1, 5, 6, 1, 6, 2,
5, 4, 7, 5, 7, 6,
4, 0, 3, 4, 3, 7,
4, 5, 1, 4, 1, 0,
3, 2, 6, 3, 6, 7,
};
// vertex buffer object
glGenBuffers(1, &m_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// index buffer object
glGenBuffers(1, &m_ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// attribute location
GLuint positionLocation = glGetAttribLocation(m_program, "a_position");
GLuint texCoordLocation = glGetAttribLocation(m_program, "a_texCoord");
// vertex array object
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
glEnableVertexAttribArray(positionLocation);
glEnableVertexAttribArray(texCoordLocation);
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), nullptr);
glVertexAttribPointer(texCoordLocation, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (const void *)(3 * sizeof(GLfloat)));
glBindVertexArray(0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
void MainWindow::resizeGL(int w, int h)
{
glViewport(0, 0, w, h);
}
void MainWindow::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// model view projection matrix
GLfloat aspectRatio = (GLfloat)m_widget->width() / (GLfloat)m_widget->height();
QMatrix4x4 projectionMatrix;
projectionMatrix.perspective(45.0f, aspectRatio, 0.1f, 100.0f);
QMatrix4x4 modelViewMatrix;
modelViewMatrix.translate(0.0f, 0.0f, -5.0f);
modelViewMatrix.rotate(m_angleX, 0.0f, 1.0f, 0.0f);
modelViewMatrix.rotate(m_angleY, 1.0f, 0.0f, 0.0f);
QMatrix4x4 modelViewProjectionMatrix = projectionMatrix * modelViewMatrix;
// shader program
glUseProgram(m_program);
glUniformMatrix4fv(glGetUniformLocation(m_program, "u_modelViewProjectionMatrix"), 1, GL_FALSE, modelViewProjectionMatrix.constData());
// texture
m_texture->bind();
glUniform1i(glGetUniformLocation(m_program, "u_texture"), 0);
// draw
glBindVertexArray(0);
glBindVertexArray(m_vao);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, nullptr);
glBindVertexArray(0);
// release resources
glUseProgram(0);
m_texture->release();
}
void MainWindow::mousePressEvent(QMouseEvent *event)
{
m_lastPos = event->pos();
}
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
GLfloat dx = (GLfloat)(event->x() - m_lastPos.x()) / (GLfloat)m_widget->width();
GLfloat dy = (GLfloat)(event->y() - m_lastPos.y()) / (GLfloat)m_widget->height();
m_angleX += 180.0f * dx;
m_angleY += 180.0f * dy;
m_lastPos = event->pos();
update();
}
void MainWindow::wheelEvent(QWheelEvent *event)
{
GLfloat delta = (GLfloat)event->delta() / (GLfloat)120.0f;
GLfloat distance = 0.1f * delta;
QMatrix4x4 modelViewMatrix;
modelViewMatrix.translate(0.0f, 0.0f, distance);
QMatrix4x4 rotationMatrix;
rotationMatrix.rotate(m_angleX, 0.0f, 1.0f, 0.0f);
rotationMatrix.rotate(m_angleY, 1.0f, 0.0f, 0.0f);
modelViewMatrix = rotationMatrix * modelViewMatrix;
GLfloat z = modelViewMatrix.column(3).z();
if (z > -1.0f && z < -0.3f)
{
m_angleX /= 2.0f;
m_angleY /= 2.0f;
modelViewMatrix.setToIdentity();
modelViewMatrix.translate(0.0f, 0.0f, distance);
modelViewMatrix = rotationMatrix * modelViewMatrix;
}
update();
}
```
在工程中添加资源文件image.png,代码中用到了这张图片作为纹理。
阅读全文