如何使用opengl 文字绘制绘制不同形状的点

OpenGL中文字的几种常用绘制方法_图文_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
OpenGL中文字的几种常用绘制方法
上传于|0|0|文档简介
&&三堆场景中绘制和标注文字是OpenGL提供的一个强大功能.但是由于国内资料的短缺,几乎所有的
OpenGL参考书文字绘制部分的内容都没有进行详细论述。文章详细介绍了OpenGL中字符串绘制的各种常用方法.并给出了相应的应用实例。
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
定制HR最喜欢的简历
你可能喜欢> 博客详情
之前在知乎上发了一个[帖子](/question/)来询问,有个答主金条回答了而且还带了参考文档,原来在 [specification](https://www.opengl.org/wiki/Vertex_Specification#Vertex_Array_Object) 中有说明(好吧,看见那个一坨我就没有去翻了,后面有问题还是得去这里看看,说不定可以找到答案)。
之前调试一个 opengl 小程序时,我写的临时代码无论如何都绘制不出形状来,检查了顶点数据 N 遍后确认顶点数据无误,于是我把注意点转向了 api 的调用,发现无法绘制出来形状和 opengl 版本是有些关系的。于是想写一篇 blog 整理一下。
opengl 历史就不说了,下面的测试代码用两种方式绘制三角形,一种是 opengl 现代模式绘制,另一种是兼容模式绘制。现代模式就是指定了 opengl 最低版本是 3.3 。
# 问题与结论
我遇见的问题如下。
* 为什么我没有创建 vao 就绘制不出三角形?而在 opengles 中确可以。
* 当我使用 vao 时,我可以不用 bo 来缓存顶点属性数据吗?
* 如果我想在 opengl 中直接调用 `glVertexAttribPointer` 设置属性后调用 draw 函数绘制(调试时,总是想少写些代码),应该在什么环境下?
写代码测试后结论如下。
* 指定 opengl 最低版本号为 3.3 时,这时绘制要创建一个 vertex array object (vao),否则无法绘制出形状。
* 使用 vao 时,此时要使用 buffer object(bo)缓存顶点属性数据,否则无法绘制出形状。
* 使用 vao 时,在 `glBindVertexArray` 后调用 `glEnableVertexAttribArray` 才会使 vao 内的顶点属性有效果。不然会导致顶点着色器无法接收数组属性数据。
* 不指定 opengl 版本时,则没有太多要求,此时可以用最简单的代码来画一个三角形。
为了弄清楚,我想了一个小例子来验证。例子中将绘制 4 个三角形。
* 左上和右上是采用现代 opengl 绘制,这里左右的分别是左边采用了 bo 右边可根据宏定义是否采用 bo 。
* 左下和右下是采用兼容 opengl 绘制。左采用了 bo 而右边未采用 bo 。并且绘制这两个三角形并未显示的创建一个 vao 。
* 为了使现代模式和兼容模式互不影响,绘制时我采用了两个 program ,modern_program 和 compat_program 分别对应现代模式和兼容模式。
**完整的代码在我的博客代码片段[仓库](http://git.oschina.net/iirecord/blogsnippet)中 blogsnippet\opengl\trimodern 目录。**
下面定义了两个宏,默认是定义的,你可以注释掉来查看不同的效果。定义 `USE_OPENGL33` 表示采用现代 opengl 。定义 `VAO_WITH_BO` 表示采用 BO ,可以注释掉来查看三角形还能不能绘制。
#define USE_OPENGL33
#define VAO_WITH_BO
下面是绘制的代码,分成了两部分,首先用 `modern_program` 绘制上方的两个三角形,然后用 `compat_program` 绘制下方的两个三角形。
glUseProgram(modern_program);
glBindVertexArray(vao);
glEnableVertexAttribArray(0); // 两个 program 都使用 0 索引属性,为了不被其他 program 影响,这里再次调用
// draw left up
glBindBuffer(GL_ARRAY_BUFFER, leftup_bo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); // 在绘制时才定义数组属性数据
glDrawArrays(GL_TRIANGLES, 0, 3);
// draw right up
#ifdef VAO_WITH_BO
glBindBuffer(GL_ARRAY_BUFFER, rightup_bo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0); // 测试代码,取消注释着两行,看看不使用 buffer object 能不能成功绘制
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices_rightup);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glUseProgram(0);
glUseProgram(compat_program);
// draw left down
glBindBuffer(GL_ARRAY_BUFFER, leftdown_bo);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindBuffer(GL_ARRAY_BUFFER, 0); // 由于下一个绘制没有用到缓冲区,这里要解绑缓冲区,不然会受到影响
// draw right down
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices_rightdown);
glDrawArrays(GL_TRIANGLES, 0, 3);
glUseProgram(0);
如下图。默认是宏都是定义的。可以发现采用 modern opengl 时,必须要显示创建 vao 才能绘制出图像。
![use modern](https://static.oschina.net/uploads/img/62452_NOYa.png "在这里输入图片标题")
如下图,当采用兼容 opengl 时,4 个三角形都绘制出来了。
![use compat](https://static.oschina.net/uploads/img/63412_PpPl.png "在这里输入图片标题")
可以通过注释 `USE_OPENGL33` 和 `VAO_WITH_BO` 来产生四种效果图。可以手动试试奥。
人打赏支持
码字总数 14677
支付宝支付
微信扫码支付
打赏金额: ¥
已支付成功
打赏金额: ¥
& 开源中国(OSChina.NET) |
开源中国社区(OSChina.net)是工信部
指定的官方社区博客访问: 3585047
博文数量: 399
博客积分: 10059
博客等级: 上将
技术积分: 4655
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: C/C++
&前面的一节, &已经给出了如何利用GLUT创建一个窗口,下面我们在这个窗口里面绘制我们的世界。当然,先从简单开始,绘制一个点。
OpenGL中描述一个顶点的方法是指定其坐标和属性,命令是: glVertex*(Coordination); 该命令以参数指定的坐标和当前颜色、纹理坐标、法向等属性定义一个顶点。 OpenGL中描述一个面(线、点)的方法是glBegin/glEnd命令组: glBegin(形状); glVertex(顶点1); glVertex(顶点2); …… glEnd();
OpenGL支持点(GL_POINTS)、线段(GL_LINES)、三角形(GL_TRIANGLES)、四边形(GL_QUADS)、多边形(GL_POLYGON)等等,请看下面程序绘制一个点。
1、绘制一个点
// Purpose: To show how to draw points and lines in a windows// Author: zieckey// Date: #include "GL/glut.h"void RenderScene(){&&&&//清空颜色缓冲区,填充的颜色由 glClearColor( 0, 0.0, 0.0, 1 ); 指定为黑色&&&&glClear( GL_COLOR_BUFFER_BIT );&&&&glPointSize( 9 );//指定点的大小,9个像素单位&&&&glColor3f( 1.0f, 0.0f, 0.0f );//指定点的颜色&&&&glBegin( GL_POINTS );//开始画点&&&&{&&&&&&&&glVertex3f(0.0f, 0.0f, 0.0f); // 在坐标为(0,0,0)的地方绘制了一个点&&&&}&&&&glEnd();//结束画点&&&&glutSwapBuffers();}void SetupRC(){&&&&glClearColor( 0.0f, 0.0f, 0.0f, 1 );//以RGB(0,0,0)即黑色来清空颜色缓冲区&&&&glColor3f( 1.0f, 0.0f, 0.0f );//以RGB(1,0,0)即红色来绘制图形}void ChangeSize( GLsizei w, GLsizei h ){&&&&GLfloat nRange = 200.0f;&&&&// Prevent a divide by zero&&&&if(h == 0)&&&&&&&&h = 1;&&&&// Set Viewport to window dimensions&&&&glViewport(0, 0, w, h);&&&&// Reset projection matrix stack&&&&glMatrixMode(GL_PROJECTION);&&&&glLoadIdentity();&&&&// Establish clipping volume (left, right, bottom, top, near, far)&&&&if (w <= h) &&&&&&&&glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange);&&&&else &&&&&&&&glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange);&&&&// Reset Model view matrix stack&&&&glMatrixMode(GL_MODELVIEW);&&&&glLoadIdentity();}int main(int argc, char* argv[]){&&&&glutInit(&argc, argv);&&&&glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);&&&&glutInitWindowSize (200, 200);&&&&glutInitWindowPosition (10, 10);&&&&glutCreateWindow( "Point examples" );&&&&glutDisplayFunc( RenderScene );&&&&SetupRC();&&&&glutMainLoop();&&&&return 1;}
程序运行结果如下:
500)this.width=500;" border=0>
2、下面,我们来绘制一个点园
// Purpose: To show how to draw points and lines in a windows// Author: zieckey// Date: #include "GL/glut.h"#include <math.h>void RenderScene(){&&&&//清空颜色缓冲区,填充的颜色由 glClearColor( 0, 0.0, 0.0, 1 ); 指定为黑色&&&&glClear( GL_COLOR_BUFFER_BIT );&&&&glColor3f( 1.0f, 0.0f, 0.0f );//指定点的颜色,红色&&&&glPointSize( 9 );//指定点的大小,9个像素单位&&&&glBegin( GL_POINTS );//开始画点&&&&{&&&&&&&&glVertex3f(0.0f, 0.0f, 0.0f); // 在坐标为(0,0,0)的地方绘制了一个点&&&&}&&&&glEnd();//结束画点&&&&glColor3f( 0.0f, 1.0f, 0.0f );//指定点的颜色,绿色&&&&glPointSize( 3 );//指定点的大小,3个像素单位&&&&glBegin( GL_POINTS );&&&&{&&&&&&&&#define PI 3.14159f&&&&&&&&#define RADIUS 50.f&&&&&&&&GLfloat x = 0, y = 0, angle = 0.0;&&&&&&&&for ( angle = 0; angle <= 2.0f * PI; angle += 0.1f )&&&&&&&&{&&&&&&&&&&&&x = RADIUS * sin( angle );&&&&&&&&&&&&y = RADIUS * cos( angle );&&&&&&&&&&&&glVertex3f( x, y, 0 );&&&&&&&&}&&&&}&&&&glEnd();&&&&glutSwapBuffers();}void SetupRC(){&&&&glClearColor( 0, 0.0, 0.0, 1 );&&&&glColor3f( 1.0f, 0.0f, 0.0f );}void ChangeSize( GLsizei w, GLsizei h ){&&&&GLfloat nRange = 100.0f;&&&&// Prevent a divide by zero&&&&if(h == 0)&&&&&&&&h = 1;&&&&// Set Viewport to window dimensions&&&&glViewport(0, 0, w, h);&&&&// Reset projection matrix stack&&&&glMatrixMode(GL_PROJECTION);&&&&glLoadIdentity();&&&&// Establish clipping volume (left, right, bottom, top, near, far)&&&&if (w <= h) &&&&&&&&glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange);&&&&else &&&&&&&&glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange);&&&&// Reset Model view matrix stack&&&&glMatrixMode(GL_MODELVIEW);&&&&glLoadIdentity();}int main(int argc, char* argv[]){&&&&glutInit(&argc, argv);&&&&glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);&&&&glutInitWindowSize (400, 300);&&&&glutInitWindowPosition (100, 100);&&&&glutCreateWindow( "Point examples" );&&&&glutDisplayFunc( RenderScene );&&&&glutReshapeFunc( ChangeSize );&&&&SetupRC();&&&&glutMainLoop();&&&&return 1;}
程序运行结果如下:
500)this.width=500;" border=0>
3、增加坐标轴
下面我们给上面的图形增加坐标轴,看看如何画线
// Purpose: To show how to draw points and lines in a windows// Author: zieckey// Date: #include "GL/glut.h"#include <math.h>void RenderScene(){&&&&//清空颜色缓冲区,填充的颜色由 glClearColor( 0, 0.0, 0.0, 1 ); 指定为黑色&&&&glClear( GL_COLOR_BUFFER_BIT );&&&&//绘制一个点&&&&{&&&&&&&&glColor3f( 1.0f, 0.0f, 0.0f );//指定点的颜色,红色&&&&&&&&glPointSize( 9 );//指定点的大小,9个像素单位&&&&&&&&glBegin( GL_POINTS );//开始画点&&&&&&&&{&&&&&&&&&&&&glVertex3f(0.0f, 0.0f, 0.0f); // 在坐标为(0,0,0)的地方绘制了一个点&&&&&&&&}&&&&&&&&glEnd();//结束画点&&&&}&&&&//绘制一个点圆&&&&{&&&&&&&&glColor3f( 0.0f, 1.0f, 0.0f );//指定点的颜色,绿色&&&&&&&&glPointSize( 3 );//指定点的大小,3个像素单位&&&&&&&&glBegin( GL_POINTS );&&&&&&&&{&&&&&&&&&&&&#define PI 3.14159f&&&&&&&&&&&&#define RADIUS 50.f&&&&&&&&&&&&GLfloat x = 0, y = 0, angle = 0.0;&&&&&&&&&&&&for ( angle = 0; angle <= 2.0f * PI; angle += 0.1f )&&&&&&&&&&&&{&&&&&&&&&&&&&&&&x = RADIUS * sin( angle );&&&&&&&&&&&&&&&&y = RADIUS * cos( angle );&&&&&&&&&&&&&&&&glVertex3f( x, y, 0 );&&&&&&&&&&&&}&&&&&&&&}&&&&&&&&glEnd();&&&&}&&&&//绘制x、y坐标轴&&&&{&&&&&&&&glColor3f( 0.0f, 0.0f, 1.0f );//指定线的颜色,蓝色&&&&&&&&glBegin( GL_LINES );&&&&&&&&{&&&&&&&&&&&&// x-axis&&&&&&&&&&&&glVertex3f( -100.0f, 0.0f, 0.0f);&&&&&&&&&&&&glVertex3f( 100.0f, 0.0f, 0.0f);&&&&&&&&&&&&// x-axis arrow&&&&&&&&&&&&glVertex3f( 100.0f, 0.0f, 0.0f);&&&&&&&&&&&&glVertex3f( 93.0f, 3.0f, 0.0f);&&&&&&&&&&&&glVertex3f( 100.0f, 0.0f, 0.0f);&&&&&&&&&&&&glVertex3f( 93.0f,-3.0f, 0.0f);&&&&&&&&&&&&// y-axis&&&&&&&&&&&&glVertex3f( 0.0f, -100.0f, 0.0f);&&&&&&&&&&&&glVertex3f( 0.0f, 100.0f, 0.0f);&&&&&&&&&&&&glVertex3f( 0.0f, 100.0f, 0.0f);&&&&&&&&&&&&glVertex3f( 3.0f, 93.0f, 0.0f);&&&&&&&&&&&&glVertex3f( 0.0f, 100.0f, 0.0f);&&&&&&&&&&&&glVertex3f( -3.0f, 93.0f, 0.0f);&&&&&&&&}&&&&&&&&glEnd();&&&&}&&&&glutSwapBuffers();}void SetupRC(){&&&&glClearColor( 0, 0.0, 0.0, 1 );&&&&glColor3f( 1.0f, 0.0f, 0.0f );}void ChangeSize( GLsizei w, GLsizei h ){&&&&GLfloat nRange = 100.0f;&&&&// Prevent a divide by zero&&&&if(h == 0)&&&&&&&&h = 1;&&&&// Set Viewport to window dimensions&&&&glViewport(0, 0, w, h);&&&&// Reset projection matrix stack&&&&glMatrixMode(GL_PROJECTION);&&&&glLoadIdentity();&&&&// Establish clipping volume (left, right, bottom, top, near, far)&&&&if (w <= h) &&&&&&&&glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange);&&&&else &&&&&&&&glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange);&&&&// Reset Model view matrix stack&&&&glMatrixMode(GL_MODELVIEW);&&&&glLoadIdentity();}int main(int argc, char* argv[]){&&&&glutInit(&argc, argv);&&&&glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);&&&&glutInitWindowSize (400, 300);&&&&glutInitWindowPosition (100, 100);&&&&glutCreateWindow( "Point examples" );&&&&glutDisplayFunc( RenderScene );&&&&glutReshapeFunc( ChangeSize );&&&&SetupRC();&&&&glutMainLoop();&&&&return 1;}
程序运行结果如下:
500)this.width=500;" border=0>
4、绘制三维曲线和添加键盘响应
为了从不同的角度观察三维曲线,我们这里可以通过 glRotatef 来旋转OpenGL绘图坐标系,
同时通过 glutSpecialFunc( SpecialKeys ) 设置了方向键的响应&
// Purpose: To show how to draw points and lines in a windows// Author: zieckey// Date: #include "GL/glut.h"#include <math.h>// Rotation amountsstatic GLfloat xRot = 0.0f;static GLfloat yRot = 0.0f;void RenderScene(){&&&&//清空颜色缓冲区,填充的颜色由 glClearColor( 0, 0.0, 0.0, 1 ); 指定为黑色&&&&glClear( GL_COLOR_BUFFER_BIT );&&&&// Save matrix state and do the rotation&&&&glPushMatrix();&&&&glRotatef(xRot, 1.0f, 0.0f, 0.0f);&&&&glRotatef(yRot, 0.0f, 1.0f, 0.0f);&&&&//绘制一个点&&&&{&&&&&&&&glColor3f( 1.0f, 0.0f, 0.0f );//指定点的颜色,红色&&&&&&&&glPointSize( 9 );//指定点的大小,9个像素单位&&&&&&&&glBegin( GL_POINTS );//开始画点&&&&&&&&{&&&&&&&&&&&&glVertex3f(0.0f, 0.0f, 0.0f); // 在坐标为(0,0,0)的地方绘制了一个点&&&&&&&&}&&&&&&&&glEnd();//结束画点&&&&}&&&&//绘制一个点圆&&&&{&&&&&&&&glColor3f( 0.5f, 0.5f, 0.5f );//指定点的颜色,灰白色&&&&&&&&glPointSize( 3 );//指定点的大小,3个像素单位&&&&&&&&glBegin( GL_POINTS );&&&&&&&&{&&&&&&&&&&&&#define PI 3.14159f&&&&&&&&&&&&#define CIRCLE_NUM 5&&&&&&&&&&&&#define RADIUS 100.f&&&&&&&&&&&&#define STEP 0.5f&&&&&&&&&&&&GLfloat x = 0, y = 0, z = -RADIUS, angle = 0.0;&&&&&&&&&&&&for ( angle = 0; angle <= 2.0f * PI * CIRCLE_NUM; angle += 0.1f )&&&&&&&&&&&&{&&&&&&&&&&&&&&&&x = RADIUS * sin( angle );&&&&&&&&&&&&&&&&y = RADIUS * cos( angle );&&&&&&&&&&&&&&&&z += STEP;&&&&&&&&&&&&&&&&glVertex3f( x, y, z );&&&&&&&&&&&&}&&&&&&&&}&&&&&&&&glEnd();&&&&}&&&&//绘制x、y坐标轴&&&&{&&&&&&&&glColor3f( 0.0f, 0.0f, 1.0f );//指定线的颜色,蓝色&&&&&&&&glBegin( GL_LINES );&&&&&&&&{&&&&&&&&&&&&// x-axis&&&&&&&&&&&&glVertex3f( 0.0f, 0.0f, 0.0f);&&&&&&&&&&&&glVertex3f( 200.0f, 0.0f, 0.0f);&&&&&&&&&&&&// x-axis arrow&&&&&&&&&&&&glVertex3f( 200.0f, 0.0f, 0.0f);&&&&&&&&&&&&glVertex3f( 193.0f, 3.0f, 0.0f);&&&&&&&&&&&&glVertex3f( 200.0f, 0.0f, 0.0f);&&&&&&&&&&&&glVertex3f( 193.0f,-3.0f, 0.0f);&&&&&&&&}&&&&&&&&glEnd();&&&&&&&&glColor3f( 0.0f, 1.0f, 0.0f );//指定线的颜色,绿色&&&&&&&&glBegin( GL_LINES );&&&&&&&&{&&&&&&&&&&&&// y-axis&&&&&&&&&&&&glVertex3f( 0.0f, 0.0f, 0.0f);&&&&&&&&&&&&glVertex3f( 0.0f, 200.0f, 0.0f);&&&&&&&&&&&&glVertex3f( 0.0f, 200.0f, 0.0f);&&&&&&&&&&&&glVertex3f( 3.0f, 193.0f, 0.0f);&&&&&&&&&&&&glVertex3f( 0.0f, 200.0f, 0.0f);&&&&&&&&&&&&glVertex3f( -3.0f, 193.0f, 0.0f);&&&&&&&&}&&&&&&&&glEnd();&&&&&&&&glColor3f( 1.0f, 0.0f, 0.0f );//指定线的颜色,红色&&&&&&&&glBegin( GL_LINES );&&&&&&&&{&&&&&&&&&&&&// z-axis&&&&&&&&&&&&glVertex3f( 0.0f, 0.0f, 0.0f );&&&&&&&&&&&&glVertex3f( 0.0f, 0.0f, 200.0f );&&&&&&&&&&&&glVertex3f( 0.0f, 0.0f, 200.0f );&&&&&&&&&&&&glVertex3f( 0.0f, 3.0f, 193.0f );&&&&&&&&&&&&glVertex3f( 0.0f, 0.0f, 200.0f );&&&&&&&&&&&&glVertex3f( 0.0f, -3.0f, 193.0f);&&&&&&&&}&&&&&&&&glEnd();&&&&}&&&&// Restore transformations&&&&glPopMatrix();&&&&glutSwapBuffers();}void SetupRC(){&&&&glClearColor( 0, 0.0, 0.0, 1 );&&&&glColor3f( 1.0f, 0.0f, 0.0f );}void ChangeSize( GLsizei w, GLsizei h ){&&&&GLfloat nRange = 200.0f;&&&&// Prevent a divide by zero&&&&if(h == 0)&&&&&&&&h = 1;&&&&// Set Viewport to window dimensions&&&&glViewport(0, 0, w, h);&&&&// Reset projection matrix stack&&&&glMatrixMode(GL_PROJECTION);&&&&glLoadIdentity();&&&&// Establish clipping volume (left, right, bottom, top, near, far)&&&&if (w <= h) &&&&&&&&glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange);&&&&else &&&&&&&&glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange);&&&&// Reset Model view matrix stack&&&&glMatrixMode(GL_MODELVIEW);&&&&glLoadIdentity();}void SpecialKeys(int key, int x, int y){&&&&if(key == GLUT_KEY_UP)&&&&&&&&xRot-= 5.0f;&&&&if(key == GLUT_KEY_DOWN)&&&&&&&&xRot += 5.0f;&&&&if(key == GLUT_KEY_LEFT)&&&&&&&&yRot -= 5.0f;&&&&if(key == GLUT_KEY_RIGHT)&&&&&&&&yRot += 5.0f;&&&&if(xRot > 356.0f)&&&&&&&&xRot = 0.0f;&&&&if(xRot < -1.0f)&&&&&&&&xRot = 355.0f;&&&&if(yRot > 356.0f)&&&&&&&&yRot = 0.0f;&&&&if(yRot < -1.0f)&&&&&&&&yRot = 355.0f;&&&&// Refresh the Window&&&&glutPostRedisplay();// this will refresh the window, so, it works the same to call RenderScene() directly }int main(int argc, char* argv[]){&&&&glutInit(&argc, argv);&&&&glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);&&&&glutInitWindowSize (800, 600);&&&&glutInitWindowPosition (100, 100);&&&&glutCreateWindow( "Point examples" );&&&&glutDisplayFunc( RenderScene );&&&&glutReshapeFunc( ChangeSize );&&&&glutSpecialFunc( SpecialKeys );&&&&SetupRC();&&&&glutMainLoop();&&&&return 1;}
程序运行结果如下:
500)this.width=500;" border=0>
5、遇到的问题分析
程序运行的时候,如果图形出不来,可能是下面的几个原因
a) 双缓冲和单缓冲的设置问题,例如我们用的是双缓冲,那么就要用 glutSwapBuffers(); 来刷新图形
b) 我们设置了正交投影(glOrtho),请注意下它的参数是不是范围太小,不能全部容纳我们绘制的图形,导致只看到图形的一部分
c) 看看 glutDisplayFunc( RenderScene );&&glutReshapeFunc( ChangeSize );&&glutSpecialFunc( SpecialKeys ); 等回调函数的设置的是否漏掉是否正确
等等吧,呵呵
这里我们知道了如何画点、线等,也知道了如何旋转坐标系,如何捕获键盘信息、如何设置视角等。
阅读(15188) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。12364人阅读
Qt中提供了强大的2D绘图系统,可以使用相同的API在屏幕和绘图设备上进行绘制,它主要基于QPainter、QPaintDevice和QPaintEngine这三个类。
QPainter用来执行绘图操作,其提供的API在GUI或QImage、QOpenGLPaintDevice、QWidget和QPaintDevice显示图形(线、形状、渐变等)、文本和图像。
QPaintDevice不直接绘制物理显示画面,而利用逻辑界面的中间媒介。例如,绘制矩形图形时,为了将对象绘制到QWidget、QGLPixelBuffer、QImage、QPixmap、QPicture等多种界面中间,必须使用QPaintDevice。
QPaintEngine提供了一些接口,可以用于QPainter在不同的设备上进行绘制。
绘图系统由QPainter完成具体的绘制操作,QPainter类提供了大量高度优化的函数来完成GUI编程所需要的大部分绘制工作。它可以绘制一切想要的图形,从最简单的一条直线到其他任何复杂的图形,例如:点、线、矩形、弧形、饼状图、多边形、贝塞尔弧线等。此外,QPainter也支持一些高级特性,例如反走样(针对文字和图形边缘)、像素混合、渐变填充和矢量路径等,QPainter也支持线性变换,例如平移、旋转、缩放。
QPainter可以在继承自QPaintDevice类的任何对象上进行绘制操作。QPainter也可以与QPrinter一起使用来打印文件和创建PDF文档。这意味着通常可以用相同的代码在屏幕上显示数据,也可以生成打印形式的报告。
QPainter一般在部件的绘图事件paintEvent()中进行绘制,首先创建QPainter对象,然后进行图形的绘制,最后记得销毁QPainter对象。当窗口程序需要升级或者重新绘制时,调用此成员函数。使用repaint()和update()后,调用函数paintEvent()。
下面通过简单的示例来介绍成员函数paintEvent()的使用方法。
void MainWindow::paintEvent(QPaintEvent *event)
Q_UNUSED(event);
QPainter painter(this);
painter.setPen(QColor(0, 160, 230));
QFont font;
font.setFamily("Microsoft YaHei");
font.setPointSize(50);
font.setItalic(true);
painter.setFont(font);
painter.drawText(rect(), Qt::AlignCenter, "Qt");
首先为该部件创建了一个QPainter对象,用于后面的绘制。使用setPen()来设置画笔的颜色(淡蓝色)。通过使用QFont来构建我们想要的字体,setFamily()设置字体为微软雅黑、setPointSize()设置点大小30、setItalic()设置斜体, 然后通过setFont()来设置字体,最后调用drawText()来实现文本的绘制,这里的rect()是指当前窗体的显示区域,Qt::AlignCenter指文本居中绘制。
void MainWindow::paintEvent(QPaintEvent *event)
Q_UNUSED(event);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(QColor(0, 160, 230));
painter.drawLine(QPointF(0, height()), QPointF(width() / 2, height() / 2));
首先我们通过setRenderHint()来设置反走样,要么绘制出来的线条会出现锯齿,调用setPen()来设置画笔颜色(淡蓝色)。最后调用drawLine()来实现直线的绘制,其中QPointF(0, height())是指直线的起点坐标、QPointF(width() / 2, height() / 2)是指直线的终点坐标。
void MainWindow::paintEvent(QPaintEvent *event)
Q_UNUSED(event);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(QPen(QColor(0, 160, 230), 2));
painter.setBrush(QColor(255, 160, 90));
painter.drawRect(50, 50, 160, 100);
首先我们使用setPen()来设置画笔颜色(淡蓝色)、宽度(2像素),用来设置矩形区域的边框。然后使用setBrush()来设置画刷颜色(橙色),用来填充矩形区域,最后调用drawRect()来实现矩形的绘制,其中参数依次顺序为x、y、w、h,是指区域从x为50,y为50的坐标点起,宽度为160,高度为100的矩形。
void MainWindow::paintEvent(QPaintEvent *event)
Q_UNUSED(event);
QRectF rect(90.0, 90.0, 80.0, 90.0);
int startAngle = 30 * 16;
int spanAngle = 120 * 16;
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(QPen(QColor(0, 160, 230), 2));
painter.drawArc(rect, startAngle, spanAngle);
画弧线时,角度被分成了十六分之一,就是说,如果要30度,就需是30*16。它有起始角度和跨度,还有位置矩形,所以,要想画出自己想要的弧线,就需要大概估算出各个参数的预估值。
void MainWindow::paintEvent(QPaintEvent *event)
Q_UNUSED(event);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(QPen(QColor(0, 160, 230), 2));
painter.drawEllipse(QPointF(120, 60), 50, 20);
painter.setBrush(QColor(255, 160, 90));
painter.drawEllipse(QPointF(120, 140), 40, 40);
这里我们绘制了一个椭圆和一个圆形,都是调用drawEllipse接口,我们可以很轻易的发现,如果为椭圆的时候,后面两个参数不一样,圆形则相同。首先我们来看第一个参数QPointF是指椭圆的中心点相对当前窗体QPoint(0, 0)点的位置,后面的参数指椭圆的x轴及y轴的半径。
绘制多边形
void MainWindow::paintEvent(QPaintEvent *event)
Q_UNUSED(event);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(QColor(0, 160, 230));
static const QPointF points[4] = {QPointF(30, 40), QPointF(60, 150), QPointF(150, 160), QPointF(220, 100)};
painter.drawPolygon(points, 4);
首先我们顶一个个坐标点的位置,这里有四个点,分别为:QPointF(30, 40)、QPointF(60, 150)、QPointF(150, 160)、 QPointF(220, 100),然后调用drawPolygon将各个点连接起来,绘制为多边形。
void MainWindow::paintEvent(QPaintEvent *event)
Q_UNUSED(event);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.drawPixmap(rect(), QPixmap(":/Images/logo"));
通过drawPixmap()来绘制图片,我们可以指定图片绘制的区域QRect,这里为整个界面的区域,当界面伸缩的时候,图片也会跟着伸缩。
基本的文本、直线、矩形、椭圆、多边形、图片的绘制已经分享完了,还有一些细节我们没有讲解,关于其它图形的绘制也大同小异,这些我们都在后面做详细的讲解。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
Qter,还在等什么,赶快加入吧!
Qt分享&&交流
QML分享&&交流
访问:909222次
积分:13495
积分:13495
排名:第732名
原创:318篇
评论:1147条
本博客中所有原创文章及译文均采用进行许可
阅读:2279
文章:39篇
阅读:44632
文章:11篇
阅读:15558
阅读:22193
阅读:8392
文章:214篇
阅读:627646
(2)(11)(10)(18)(29)(37)(24)(59)(28)(19)(9)(28)(5)(15)(12)(17)

我要回帖

更多关于 opengl绘制b样条曲面 的文章

 

随机推荐