LearnOpenGL
QOpenGLWidget使用(1): Hello三角形
QOpenGLWidget使用(2): 着色器
QOpenGLWidget使用(3): 纹理
QOpenGLWidget使用(4): 变换
QOpenGLWidget使用(5): 坐标系统
QOpenGLWidget使用(6): 摄像机
QOpenGLWidget使用(7): 颜色
QOpenGLWidget使用(8): 基础光照
QOpenGLWidget使用(9):材质光照贴图
Qt中的OpenGL(系列文章)
Qt OpenGL绘制三维图形(立方体、圆柱体、圆锥、球体、圆环等等)
vao、vbo、ebo使用
openGL画基本图形
openGL画表
openGL画圆的三种方法
一、qt使用opengl(Qt自带例子cube)
1、创建窗体
//.h
#include <QOpenGLWidget>
#include <QOpenGLFuctions>
#include <QOpenGLShaderProgram>
#include <QOpenGLTexture>
#include <QBasicTimer>
class MainWidget : public QOpenglWidget, protected QOpenglFunctions
{
Q_OBJECT
public:
explicit MainWidget(QWidget *parent = 0);
~MainWidget();
protected:
void mousePressEvent(QMouseEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override;
void timerEvent(QTimerEvent *e) override;
void initializeGL() override;
void resizeGL(int w, int h) override;
void paintGL() override;
void initShaders();
void initTextures();
private:
QOpenGLShaderProgram program;
QOpenGLTexture *texture;
}
//.cpp
MainWidget::MainWidget(QWidget *parent) : QOpenGLWidget(parent)
{
}
void MainWidget::initializeGL()
{
initializeOpenGLFunctions();
glClearColor(0,0,0,1);
initShaders(); //自定义
initTextures(); //自定义
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
timer.start(12,this);
}
void MainWidget::initShaders()
{
if(!program.addShaderFromSourceFile(QOpenglShader::Vertex, ":/vshader.glsl"))
close();
if(!program.addShaderFromSourceFile(QOpenglShader::Frgment, ":/fshader.glsl"))
close();
if(!program.link())
close();
if(!program.bind())
close();
}
void MainWidget::initTextures()
{
texture = new QOpenGLTexture(QImage(":/cube.bng").mirrored());
texture->setMinificationFilter(QOpenGLTexture::Nearest);
texture->setMagnificationFilter(QOpenGLTexture::Linear);
texture->setWrapMode(QOpenGLTexture::Repeat);
}
void MainWidget::resizeGL(int w, int h)
{
}
void MainWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
program.setUniformValue("texture",0);
arrayBuf.bind();//QOpenGLBuffer
quintptr offset = 0;
int vertexLocation = program.attributeLocation("a_position");
program.enableAttributeArray(vertexLocation);
program.setAttributeBuffer(vertexLocation,GL_FLOAT,offset,3,sizeof(VertexData));
glDrawElement(GL_TRIANGLE_STRIP,34,GL_UNSIGNED_SHORT,0);
}
//vshader.glsl 顶点着色器
#ifdef GL_ES
precision mediump int;
precision mediump float;
#endif
uniform mat4 mvp_matrix;
attribute vec4 a_position;
attribute vec2 a_texcoord;
varying vec2 v_texcoord;
void main()
{
gl_Position = mvp_matrix * a_position;
v_texcoord = a_texcoord;
}
//fshader.glsl 片段着色器
#ifdef GL_ES
precision mediump int;
precision mediump float;
#endif
uniform sampler2D texture;
varying vec2 v_texcoord;
void main()
{
gl_FragColor = texture2D(texture, v_texcoord);
}
2、着色器GLSL
(1)使用uniform
//程序中
QOpenglShaderProgram program;
program.setUniformValue("mvp_matrix",matrix);
//在着色器中声明使用mvp_matrix
uniform mat4 mvp_matrix;
二、qt使用openGL(视频教程)
阿西拜讲openGL
(1)拖入OpenGLWidget,提升为下面新建的类AXBOpenGLWidget
(2)在MainWindow()的构造函数中 setCentralWidget(ui->openGLWidget);
(3)新建AXBOpenGLWidget类
1、使用VAO、VBO画三角形,没写着色器
GLuint VBO, VAO, EBO;
float vertices[] = {
//position
-0.5f,-0.5f, 0.0f, //左下
0.5f,-0.5f, 0.0f, //右下
0.0f, 0.5f, 0.0f, //上
};
COpenGLWidget::COpenGLWidget(QWidget *parent):QOpenGLWidget (parent)
{
}
COpenGLWidget::~COpenGLWidget()
{
}
void COpenGLWidget::initializeGL()
{
initializeOpenGLFunctions(); //
glGenVertexArrays(1, &VAO); //创建VAO
glBindVertexArray(VAO); //绑定VAO
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void *)0);
glEnableVertexAttribArray(0); //开户VAO的第一个属性
glBindBuffer(GL_ARRAY_BUFFER, 0); //解绑VBO
glBindVertexArray(0); //解绑VAO
}
void COpenGLWidget::resizeGL(int w, int h)
{
qDebug()<<QString("w=%1 h=%2").arg(w).arg(h);
}
void COpenGLWidget::paintGL()
{
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(VAO); //开启VAO
glDrawArrays(GL_TRIANGLES, 0, 3); //画
}
2、使用VAO、VBO画三角形,原生glCreateProgram
GLuint VBO, VAO, EBO;
float vertices[] = {
//position //colors //texture coordinations
-0.5f,-0.5f, 0.0f, //右上
0.5f,-0.5f, 0.0f, //右下
0.0f, 0.5f, 0.0f, //左下
};
const char *vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0";
const char *fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
"FragColor = vec4(1.0, 0.5f, 0.3f, 1.0);\n"
"}\0";
unsigned int shaderProgram;
COpenGLWidget::COpenGLWidget(QWidget *parent):QOpenGLWidget (parent)
{
}
COpenGLWidget::~COpenGLWidget()
{
}
void COpenGLWidget::initializeGL()
{
initializeOpenGLFunctions();
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void *)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
//以下是着色器的,不写也能出结果-------
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
glCompileShader(vertexShader);
unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
glCompileShader(fragmentShader);
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}
void COpenGLWidget::resizeGL(int w, int h)
{
qDebug()<<QString("w=%1 h=%2").arg(w).arg(h);
}
void COpenGLWidget::paintGL()
{
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
3、使用EBO画矩形,原生glCreateProgram
GLuint VBO, VAO, EBO;
float vertices[] = {
//position //colors //texture coordinations
0.5f, 0.5f, 0.0f, //右上
0.5f,-0.5f, 0.0f, //右下
-0.5f,-0.5f, 0.0f, //左下
-0.5f, 0.5f, 0.0f //左上
};
unsigned int indices[] = {
0,1,3,
1,2,3
};
const char *vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0";
const char *fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
"FragColor = vec4(1.0, 0.5f, 0.3f, 1.0);\n"
"}\0";
unsigned int shaderProgram;
COpenGLWidget::COpenGLWidget(QWidget *parent):QOpenGLWidget (parent)
{
}
COpenGLWidget::~COpenGLWidget()
{
makeCurrent();
glDeleteBuffers(1,&VBO);
glDeleteBuffers(1,&EBO);
glDeleteVertexArrays(1,&VAO);
glDeleteProgram(shaderProgram);
doneCurrent();
}
void COpenGLWidget::initializeGL()
{
initializeOpenGLFunctions();
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void *)0);
glEnableVertexAttribArray(0);
glGenBuffers(1,&EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices),indices,GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
//以下是着色器的,不写也能出结果-------
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
glCompileShader(vertexShader);
unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
glCompileShader(fragmentShader);
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
void COpenGLWidget::resizeGL(int w, int h)
{
qDebug()<<QString("w=%1 h=%2").arg(w).arg(h);
}
void COpenGLWidget::paintGL()
{
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(VAO); //VAO同时记录了VBO、EVO的状态
//glDrawArrays(GL_TRIANGLES, 0, 3);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);
}
4、EBO综合带颜色的,QOpenGLShaderProgram
//axbopenglwidget.h
#ifndef AXBOPENGLWIDGET_H
#define AXBOPENGLWIDGET_H
#include <QOpenGLWidget>
#include <QOpenGLFunctions_3_3_Core>
#include <QOpenGLShaderProgram>
#include <QOpenGLTexture>
class AXBOpenGLWidget:public QOpenGLWidget, QOpenGLFunctios_3_3_Core
{
Q_OBJECT
public:
enum Shape{None,Rect,Circle,Triangle};
explicit AXBOpenGLWidget(QWidget *parent = nullptr);
~AXBOpenGLWidget();
void drawShape(Shape shape);
void setWireframe(bool wireframe);
protected:
virtual void initializeGL();
virtual void resizeGL(int w, int h);
virtual void paintGL();
void keyPressEvent(QKeyEvent *event);
private:
Shape m_shape;
QOpenGLShaderProgram shaderProgram;
QOpenGLTexture * textureWall;
QOpenGLTexture * textureSmile;
}
#endif
//axbopenglwidget.cpp
#include "axbopenglwidget.h"
unsigned int VBO, VAO, EBO;
float vertices[] = {
//position //colors //texture coordinations
0.5f, 0.5f, 0.0f, 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, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, //左上
};
unsigned int indices[] = {
0,1,3,
1,2,3
};
float ratio = 0.5;
//----------------------
AXBOpenGLWidget::AXBOpenGLWidget(QWidget *parent)
{
setFocusPolicy(Qt::StrongFocus);//使opengl窗口能响应键盘事件
}
AXBOpenGLWidget::~AXBOpenGLWidget()
{
makeCurrent();
glDeleteBuffers(1,&VBO);
glDeleteBuffers(1,&EBO);
glDeleteVertexArrays(1,&VAO);
doneCurrent();
}
void AXBOpenGLWidget::drawShape(AXBOpenGLWidget::Shape shape)
{
m_shape = shape;
update();
}
void AXBOpenGLWidget::setWireframe(bool wireframe)
{
makeCurrent();
if(wireframe)
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
else
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
update();
doneCurrent();
}
void AXBOpenGLWidget::initializeGL()
{
initializeOpenGLFunctions();
glGenVertexArrays(1, &VAO); //创建VAO
glBindVertexArray(VAO); //绑定VAO
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void *)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void *)(3*sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void *)(6*sizeof(float)));
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0);
bool success;
shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/shapes.vert");
shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/shapes.frag");
success = shaderProgram.link();
if(!success)
qDebug()<<"Error:"<<shaderProgram.log();
glGenBuffers(1,&EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices),indices,GL_STATIC_DRAW);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
textureWall = new QOpenGLTexture(QImage(":/Images/Images/wall.jpg").mirrored()); //cpu端
textureSmile = new QOpenGLTexture(QImage(":/Images/Images/smile.png").mirrored());
shaderProgram.bind();
shaderProgram.setUniformValue("textureWall",0); //gpu端的名字绑定通道
shaderProgram.setUniformValue("textureSmile",1);
glBindVertexArray(0);
}
void AXBOpenGLWidget::resizeGL(int w, int h)
{
Q_UNUSED(w);Q_UNUSED(h);
//glViewport(0, 0, w, h);
}
void AXBOpenGLWidget::paintGL()
{
//QMatrix4x4 matrix;
//unsigned int time = QTime::currentTime().msec();
//matrix.translate(0.5, -0.5, 0); //后位移(写在前)
//matrix.rotate(time, 0.0f, 0.0f, 1.0f); //先旋转(写在后)
QMatrix4x4 model;
QMatrix4x4 view;
QMatrix4x4 projection;
model.rotate(-45, 1.0f, 0.0f, 0.0f);
view.translate(0.0, 0.0, -3);
projection.perspective(45, (float)width/height, 0.1, 100);
glClearColor(0.2f, 0.3f, 0.3, 1.0f);
//glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
shaderProgram.bind();
shaderProgram.setUniformValue("ratio",ratio);
//shaderProgram.setUniformValue("theMatrix",matrix);//第1个是shader里的变量,第2个是cpu里的变量
shaderProgram.setUniformValue("model",model);
shaderProgram.setUniformValue("view",view);
shaderProgram.setUniformValue("projection",projection);
glBindVertexArray(VAO);
switch(m_shape)
{
case Rect:
textureWall->bind(0); //cpu端绑定并激活通道
textureSmile->bind(1);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);
break;
default:
break;
}
}
void AXBOpenGLWidget::keyPressEvent(QKeyEvent *event)
{
switch(event->key())
{
case Qt::Key_Up:
ratio+=0.1;
break;
case Qt::Key_Down:
ratio-=0.1;
break;
default:
break;
}
if(ratio>1) ratio=1;
if(ratio<0) ratio=0;
shaderProgram.bind();
shaderProgram.setUniformValue("ratio",ratio);
update();
}
//shapes.vert 顶点着色器
#version 330 core
layout(location = 0) in vec3 aPos; //对应的arrayBuffer里的属性
layout(location = 1) in vec3 aColor;
layout(location = 2) in vec2 aTexCord;
out vec3 ourColor;
out vec2 TexCord;
//uniform mat4 theMatrix;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
//gl_Position = theMatrix*vec4(aPos.x, aPos.y, aPos.z, 1.0f);
gl_Position = projection*view*model*vec4(aPos.x, aPos.y, aPos.z, 1.0f);
ourColor = aColor;
TexCord = aTexCord;
}
//shapes.frag 片段着色器
#version 330 core
in vec3 ourColor;
in vec2 TexCord;
out vec4 FragColor;
uniform sampler2D textureWall;
uniform sampler2D textureSmile;
uniform float ratio;
void main()
{
//FragColor = vec4(ourColor, 1.0f);
//FragColor = texture(textureWall,TexCord);
//FragColor = texture(textureWall,TexCord)*vec4(1.0, 1, 0, 0.2);
FragColor = mix(texture(textureWall,TexCord),texture(textureSmile,TexCord),ratio);
}
6、顶点着色器中位置的获取
(1)指明位置,使用vao,vbo(上面已用到)
//shader中定义
layout(location = 0) in vec3 aPos; //对应的arrayBuffer里的属性
//cpu中指定并开启
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void *)0);
glEnableVertexAttribArray(0);
(2)顶点着色器中只定义,未指定位置(不使用vao vbo)
//顶点着色器
attribute highp vec4 posAttr;
attribute lowp vec4 colAttr;
varying lowp vec4 col;
uniform highp mat4 matrix;
void main()
{
gl_Position = matrix * posAttr;
col = colAttr;
}
//片段着色器
varying lowp vec4 col;
void main()
{
gl_FragColor = col;
}
//cpu中
GLuint m_posAttr, m_colAttr, m_matrixUniform;
//取得位置
QOpenGLShaderProgram *m_program = new QOpenGLShaderProgram(this);
m_program->bind();
m_posAttr = m_program->attributeLocation("posAttr");
m_colAttr = m_program->attributeLocation("colAttr");
m_matrixUniform = m_program->uniformLocation("matrix");
//指明位置并开启,没用
QMatrx4x4 matrix;
m_program->setUniformValue(m_matrixUniform, matrix); //参数(位置,值)
GLfloat vertices[] = {};
GLfloat colors[] = {};
glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, 0, vertices);
glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, 0, colors);
glEnablegVertexAttribArray(0);
glEnablegVertexAttribArray(1);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisablegVertexAttribArray(1);
glDisablegVertexAttribArray(0);
m_program->release();
三、基本流程
1、VAO、VBO、EBO
顶点缓冲对象VBO(Vertex Buffer Objects): 类型为GL_ARRAY_BUFFER的显存。
顶点数组对象VAO(Vertex Array Objects): 存放顶点结构定义,解析VBO中的数据。
索引缓冲对象EBO(Element Buffer Object): 减少重复的顶点
//创建VAO和VBO对象,并赋予ID
unsigned int VBO,VAO;
glGenVertexArrays(1,&VAO);//顶点数组用来存数据的结构
glGenBuffers(1,&VBO);//缓冲区用来存放顶点数据
//绑定VBO和VAO对象
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER,VBO);
//为当前绑定到数据的缓冲区对象开辟一个新的数据空间,如果数据不为空,则数据从内存传到显存
glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW);
//告知显卡如何解析传过去的数据,该过程会被VAO偷偷记录
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,3*sizeof(float),(void*)0);//第0个属性、三个值、浮点型、不需要标准化,步长,偏移量
//开启VAO管理的第一个属性值
glEnableVertexAttribArray(0);
//小助理可以休息了,养成好习惯,因为以后有很多的小助理
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindVertexArray(0);
2、背景透明、抗锯齿
setAttribute(Qt::WA_AlwaysStackOnTop);//背景透明
setFocusPolicy(Qt::StrongFocus);//响应键盘事件
QSurfaceFormat format;
format.setSamples(16); //抗锯齿
this->setFormat(format);
QOpenGLWidget背景透明的原理:
当使用 QQuickWidget 或 QOpenGLWidget 作为子部件时,半透明有一个限制。对于绝对需要此功能的应用程序,Qt 5.4 提供了一种解决方法:新引入的 Qt::WA_AlwaysStackOnTop 小部件属性。这以破坏其他类型布局的堆叠顺序为代价,使得半透明的 QQuickWidget 或 QOpenGLWidget 与其他可见的小部件成为可能。当然,如果只是为了让桌面上的其他应用在下方可见,那么Qt::WA_TranslucentBackground属性就足够了
3、画圆
const GLfloat Pi = 3.1415926536;
const int n = 50;
const GLfloat R = 0.5f;
void myDisplay(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
for (int i = 0; i < n; i++)
{
glVertex2f(R*cos(2 * Pi / n*i), R*sin(2 * Pi/n*i));//连续的画点
}
glEnd();
glFlush();
}
const int n = 100;
const GLfloat R = 0.5f;
const GLfloat pi = 3.1415926536f;
void display()
{
int i = 0;
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
for (i = 0; i < n; i++)
{
glVertex2f(R*cos(2*pi/n*i), R*sin(2*pi/n*i));
}
glEnd();
glFlush();
}
三、各种操作
1、环绕方式
设置两个轴的wrap方式
2、QMatrix4x4常用方法
//缩放
scale(float factor);
scale(float x, float y);
scale(float x, float y, float z);
//透视
perspective(float verticalAngle, float aspectRatio, float nearPlane, float farPlane);
//平移
translate(float x, float y, float z);
translate(0, 0, -2); //物体沿Z轴往后移
//旋转
rotate(float angle, float x, float y, float z);//角度:℃,正为逆时针,负为顺时针。
rotate(-30, 0, 0, 1); //沿Z轴向右旋转30℃
m_program.bind();
QMatrix4x4 matrix;
matrix.perspectiv(60.0f, 4.0f/3.0f, 0.1f, 100.0f);
matrix.translate(0, 0, -2);
matrix.rotat(100.0f * i / screen()->refreshRate(), 0, 0, 1);
m_program->setUniformValue(m_matrixUniform, matrix);
3、openGL绘制文字
openGL绘制汉字(使用Freetype)