网站建设佰首选金手指二五,百度做的网站一般在什么后台,wordpress 安装 空白,电脑设计培训学校推荐1. 说明#xff1a;
整体思路#xff1a;如果想实现动态#xff0c;可以使用一个矩阵和我们给定的坐标值进行相乘#xff0c;实时的改变坐标值 类似于坐标的齐次变换#xff0c;然后使用一个定时器#xff0c;在规定时间内触发重新绘制的函数。 实际效果#xff1a; OP…1. 说明
整体思路如果想实现动态可以使用一个矩阵和我们给定的坐标值进行相乘实时的改变坐标值 类似于坐标的齐次变换然后使用一个定时器在规定时间内触发重新绘制的函数。 实际效果
OPenGL移动旋转图形2. 实现步骤
第一步 在MyOpenGLWidget.h文件中添加一个定时器变量用来实时的调用更新函数让画布在规定的间隔时间内重绘
#ifndef MYOPENGLWIDGET_H
#define MYOPENGLWIDGET_H#include QObject
#include QWidget
#include QTimer
#include QTime#include QOpenGLWidget
#include QOpenGLFunctions_3_3_Core
#include QOpenGLShaderProgram
#include QOpenGLTextureclass MyOpenGLWidget : public QOpenGLWidget,QOpenGLFunctions_3_3_Core
{Q_OBJECT
public:enum Shape{None,Rect,Circle,Triangle};explicit MyOpenGLWidget(QWidget *parent nullptr);void drawShape(Shape shape);void clearGraphic();void setWireFrame(bool wireFrame);protected:virtual void initializeGL() override;virtual void resizeGL(int w, int h) override;virtual void paintGL() override;signals:public slots:void on_timeout();private:Shape m_shape;QOpenGLShaderProgram shaderProgram;QOpenGLTexture *textureStar;QTimer timer; //在之前的基础上再添加一个 定时器 变量
};
#endif // MYOPENGLWIDGET_H第二步 在MyOpenGLWidget.cpp文件中的paintGL()函数内部声明一个矩阵使这个矩阵位移一段距离然后随着时间不停的做旋转最后将这个矩阵作用在顶点着色器的位置坐标上即可实现物体的平移和旋转。 注意矩阵要用左乘且矩阵matrix在代码的体现上应该先平移再旋转否则会乱掉 paintGL()函数代码如下:
void MyOpenGLWidget::paintGL()
{QMatrix4x4 matrix;unsigned int time QTime::currentTime().msec();matrix.translate(0.5,-0.5,0.0);//先写平移的代码matrix.rotate(time,0.0f,0.0f,1.0f);//再写旋转的代码glClearColor(0.5f,0.9f,0.4f,1.0f);glClear(GL_COLOR_BUFFER_BIT);shaderProgram.bind();textureStar-bind(0);//在渲染前只需开启对应的VAO即可glBindVertexArray(VAO);switch (m_shape) {case Rect://将变量matrix传输到顶点着色器中的变量theMatrix中shaderProgram.setUniformValue(theMatrix,matrix);glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,indices);break;default:break;}}第三步 在顶点着色器文件中定义变量theMatrix用来接收来自外界数据的传入(matrix)并将变量theMatrix作用在顶点位置坐标上注意是左乘代码如下
#version 330 corelayout(location 0) in vec3 aPos;
layout(location 1) in vec3 aColor;
layout(location 2) in vec2 aTexCord;out vec3 ourColor;
out vec2 texCord;uniform mat4 theMatrix;//定义变量接收外界数据void main()
{//将矩阵变换作用在位置坐标上gl_Position theMatrix * vec4(aPos.x,aPos.y,aPos.z,1.0f);ourColor aColor;texCord aTexCord;
}MyOpenGLWidget.cpp整天代码
#include myopenglwidget.hunsigned int VBO,VAO;//添加一个索引控制器
unsigned int EBO;float vertices[] {-0.5f,-0.5f,0.0f,0.5f,-0.5f,0.0f,0.0f,0.5f,0.0f
};float verticesColorTexture[] { //每一行数据的前三个是位置坐标后三个是颜色值0.5f,0.5f,0.5f,1.0f,0.0f,0.0f,1.0f,1.0f,0.5f,-0.5f,0.0f,0.0f,1.0f,0.0f,1.0f,0.0f,-0.5f,-0.5f,0.0f,0.0f,0.0f,1.0f,0.0f,0.0f,-0.5f,0.5f,0.0f,0.5f,0.5f,0.5f,0.0f,1.0f
};//添加索引数据
unsigned int indices[]{0,1,3,1,2,3
};MyOpenGLWidget::MyOpenGLWidget(QWidget *parent) : QOpenGLWidget(parent)
{connect(timer,SIGNAL(timeout()),this,SLOT(on_timeout()));//定时器触发连接槽函数timer.start(100);//启动定时器
}void MyOpenGLWidget::drawShape(MyOpenGLWidget::Shape shape)
{makeCurrent();m_shape shape;update();doneCurrent();
}void MyOpenGLWidget::clearGraphic()
{makeCurrent();drawShape(MyOpenGLWidget::None);makeCurrent();glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);update();doneCurrent();
}void MyOpenGLWidget::setWireFrame(bool wireFrame)
{makeCurrent();if(wireFrame){glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);}else{glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);}update();doneCurrent();
}void MyOpenGLWidget::initializeGL()
{initializeOpenGLFunctions();//void glGenVertexArrays(GLsizei n, GLuint *arrays)生成顶点数组对象名称// n: 要产生的VAO对象的数量// arrays: 存放产生的VAO对象的名称glGenVertexArrays(1,VAO);// void glGenBuffers(GLsizei n,GLuint *buffers)生成顶点缓冲对象// n: 要产生的VBO对象的数量// arrays: 存放产生的VBO对象的名称glGenBuffers(1,VBO);//初始化索引器glGenBuffers(1,EBO);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof (indices),indices,GL_STATIC_DRAW);//绑定VAO和VBOglBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER,VBO);//在VBO中存入顶点数据glBufferData(GL_ARRAY_BUFFER,sizeof (verticesColorTexture),verticesColorTexture,GL_STATIC_DRAW);//告诉VAO怎么在VBO中拿数据(顶点位置数据)glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,8*sizeof (float),(void*)0);//开启第一个VAOglEnableVertexAttribArray(0);//告诉VAO怎么在VBO中拿数据(颜色数据)glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,8*sizeof (float),(void*)(3*sizeof(float)));//开启第二个VAOglEnableVertexAttribArray(1);//告诉VAO怎么在VBO中拿数据(纹理数据)glVertexAttribPointer(2,2,GL_FLOAT,GL_FALSE,8*sizeof (float),(void*)(6*sizeof(float)));//开启第三个VAOglEnableVertexAttribArray(2);//用完之后解除绑定(信息已经被记录下来了)glBindBuffer(GL_ARRAY_BUFFER,0);glBindVertexArray(0);//添加着色器shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex,:/shaders/Shaders/shape.vert);shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment,:/shaders/Shaders/shape.frag);shaderProgram.link();//添加纹理数据textureStar new QOpenGLTexture(QImage(:/img/images/water.jpg).mirrored());shaderProgram.setUniformValue(textureStar,0);
}void MyOpenGLWidget::resizeGL(int w, int h)
{Q_UNUSED(w);Q_UNUSED(h);}void MyOpenGLWidget::paintGL()
{QMatrix4x4 matrix;unsigned int time QTime::currentTime().msec();matrix.translate(0.5,-0.5,0.0);matrix.rotate(time,0.0f,0.0f,1.0f);glClearColor(0.5f,0.9f,0.4f,1.0f);glClear(GL_COLOR_BUFFER_BIT);shaderProgram.bind();textureStar-bind(0);//在渲染前只需开启对应的VAO即可glBindVertexArray(VAO);switch (m_shape) {case Rect:shaderProgram.setUniformValue(theMatrix,matrix);glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,indices);break;default:break;}}
//定时器槽函数内调用opengl的更新函数
void MyOpenGLWidget::on_timeout()
{update();
}持续更新中请大家多多关注…