QOpenGL入门教程04:基本图形

系列教程索引:QOpenGL入门教程索引

上一篇:QOpenGL入门教程03:设置格式

先把inherit工程复制过来

基本图形

首先先绘制一下基本图形,就是一些点线圆等等。

本部分采用立即渲染模式绘图,仅用于演示立即渲染模式绘图方法,本系列后续所有文章都采用核心模式绘图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
void GLWindow::point()
{
glPointSize(5.0f);//点的大小
glBegin(GL_POINTS);
glVertex2f(0.5f, 0.5f);
glEnd();
glFlush();
}

void GLWindow::line()
{
glEnable(GL_LINE_STIPPLE);//启动虚线模式
glLineStipple(2, 0x0F0F); //0000111100001111
glLineWidth(10.0f);
glBegin(GL_LINES);
glVertex2f(0.0f, 0.0f);
glVertex2f(0.5f, 0.5f);
glEnd();
glDisable(GL_LINE_STIPPLE);//关闭虚线模式
glFlush();
}

void GLWindow::circle()
{
glBegin(GL_POLYGON); //画正n边形
for (int i = 0; i<n; ++i)
glVertex2f(R*qCos(2 * Pi / n*i), R*qSin(2 * Pi / n*i));
glEnd();
glFlush();
}

void GLWindow::triangle()
{
glBegin(GL_TRIANGLES);
glVertex3f(-0.5,0,0);
glVertex3f(0,1,0);
glVertex3f(0.5,0,0);
glEnd();
}

void GLWindow::quad()
{
glBegin(GL_QUADS);
glVertex3f(-0.5,0.5,0);
glVertex3f(0.5,0.5,0);
glVertex3f(0.5,-0.5,0);
glVertex3f(-0.5,-0.5,0);
glEnd();
}

void GLWindow::star()
{
GLfloat a = 1 / (2 - 2 * cos(72 * Pi / 180));
GLfloat bx = a * cos(18 * Pi / 180);
GLfloat by = a * sin(18 * Pi / 180);
GLfloat cy = -a * cos(18 * Pi / 180);
GLfloat
PointA[2] = { 0, a },
PointB[2] = { bx, by },
PointC[2] = { 0.5, cy },
PointD[2] = { -0.5, cy },
PointE[2] = { -bx, by };
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINE_LOOP);
glVertex2fv(PointA);
glVertex2fv(PointC);
glVertex2fv(PointE);
glVertex2fv(PointB);
glVertex2fv(PointD);
glEnd();
glFlush();
}

void GLWindow::mySin()
{
GLfloat x;
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINES);
glVertex2f(-1.0f, 0.0f);// 画x轴
glVertex2f(1.0f, 0.0f);
glVertex2f(0.0f, -1.0f);// 画y轴
glVertex2f(0.0f, 1.0f);
glEnd();
glBegin(GL_LINE_STRIP);
for (x = -1.0f / factor; x<1.0f / factor; x += 0.01f)
{
glVertex2f(x*factor, sin(x)*factor);
}
glEnd();
glFlush();
}

在paintGL函数中调用这些函数绘制图形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
void GLWindow::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

if(i>100){
i=0;
if(j>=6){
j=0;
}else j++;
}

switch(j){
case 0:
point();
break;
case 1:
line();
break;
case 2:
circle();
break;
case 3:
triangle();
break;
case 4:
quad();
break;
case 5:
star();
break;
case 6:
mySin();
break;
}
i++;

update();
}

使用空格键切换显示元素,效果为:

elements

会发现圆不圆,变椭圆了,见OpenGL名称解释中的立体坐标。

VBO方法

绘制三角形

先准备渲染语言

1
2
3
4
5
6
7
8
9
const char* vsrc="#version 330 core\n"
"in vec3 pos;\n"
"void main(){\n"
" gl_Position=vec4(pos,1.0);\n"
"}";

const char* fsrc="void main(){\n"
" gl_FragColor=vec4(1.0f,1.0f,1.0f,1.0f);\n"
"}";

pos是输入(in)

在initializeGL函数中进行初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
program = new QOpenGLShaderProgram;
program->addShaderFromSourceCode(QOpenGLShader::Vertex,vsrc);
program->addShaderFromSourceCode(QOpenGLShader::Fragment,fsrc);
program->bindAttributeLocation("pos",0);
program->link();//激活Program对象
program->bind();

vao.create();
vao.bind();

float vertices[]={
// 位置
0.5f, -0.5f, 0.0f,// 右下
-0.5f, -0.5f, 0.0f, // 左下
0.0f, 0.5f, 0.0f// 顶部
};

vbo.create();
vbo.bind();
vbo.allocate(vertices,sizeof(vertices)*sizeof (float));

program->enableAttributeArray(0);
program->setAttributeBuffer(0,GL_FLOAT,0,3,3*sizeof(float));

vao.release();
vbo.release();
program->release();

将渲染语言的输入pos绑定到AttribteLocation的0位置。然后调用enableAttributeArray(0)激活。

而setAttributeBuffer就是指定0号位置的数据与位置点的关系,位置是0,类型是GL_FLOAT,起始位置为0,数量为3个(一行三个数据,对应三维坐标的xyz),大小为3个GL_FLOAT的大小。

在paintGL函数中调用数据绘制

1
2
3
4
5
program->bind();
vao.bind();
glDrawArrays(GL_TRIANGLES,0,3);
vao.release();
program->release();

绘制三角形,数据位于位置0处,共有三个点数据。

效果为:

triangle vbo

绘制四边形

方法和三角形的类似,就不做详细介绍了,可以查看代码。

quad

同时提供其他两种写法,仅供参考。

源代码地址:OpenGL_Beginner在QOpenGL下的4.figure中

下一篇:QOpenGL入门教程05:多边形上色


QOpenGL入门教程04:基本图形
https://feater.top/qt/basic-qopengl-elements/
作者
JackeyLea
发布于
2020年11月11日
许可协议