OpenGL超级宝典学习笔记——空间绘图画点


3D概念

  1. 像素,计算机显示器中的最小元素。
  2. 3D画布,把可视区域看成一个3维的画布,可以用OpenGL命令在上面进行绘图。例如:glOrtho可以设置一个长方体的可视区域。谨记第二章说的:glOrtho是对之前的矩阵进行运算,所以一般都会在此函数之前调用glMatrixMode(GL_PROJECTION); glLoadIdentity();

image

3D空间中的顶点

我们可以通过glVertex这个函数来设置多个参数多个类型的点。例如:glVertex2f(0.0f, 1.0f); glVertex3f(1.0f, 0.5f, 0.0f);

在图形学中点不仅仅是一个点, OpenGL如何解释一个点,决定了根据这个点画出的几何图元。这里的点一般是图元中的顶点,比如矩形的顶点,曲线的顶点,线段的端点等。我们可以通过glBegin(GLenum mode); glEnd(); 来说明这两个函数之间顶点应当如何被解释。glBegin,glEnd像似{} 在此区域内的点将被解释。例如:

 

//画点
glBegin(GL_POINTS);
glVertex2f(3.0f, 4.0f);
glVertex2f(5.0f, 8.0f);
glEnd()
//画线,偶数2n个点画成 n条直线 2n+1奇数个的话,最后一个将被忽略
glBegin(GL_LINES);
glVertex2f(3.0f, 4.0f);
glVertex2f(5.0f, 8.0f);
glVertex2f(7.0f, 12.0f);//此点将被忽略
glEnd();
注意glBegin()和glEnd()之间的缩进,这样是为了更容易寻找顶点源。是不成文的约定。 image
 

绘制图形

我们知道如何在OpenGL中指定一个点,并且告诉OpenGL如何对它进行操作。顶点的几何定义不仅仅是空间中的一个点,而是两条直线或曲线的交点。这就是图元的本质。

图元是顶点的集合,它们构成了在屏幕上所绘制的形状。

例子:

用简单的三角方法绘制一些点,使它们绕着z轴呈现螺旋状。

#include 

  

  
 
   
 
   
#include
#include

static GLfloat GL_PI = 3.14159f;

//绘制场景
static void RenderSences()
{
GLfloat z = -50.0f;
//清空画布
glClear(GL_COLOR_BUFFER_BIT);
//设置画图使用的颜色
glColor3f(1.0f, 0.0f, 0.0f);
//保存矩阵
glPushMatrix();
//旋转, 如果不旋转,那些不同层次的点都重叠在一起,看不出3D效果了。
glRotatef(200.0f, 1.0f, 0.0f, 0.0f);
glRotatef(120.5f, 0.0f, 1.0f, 0.0f);
//获取点的大小的范围,以及增长的步长
GLfloat size[2];
GLfloat sizeStep;
glGetFloatv(GL_POINT_SIZE_RANGE, size);
glGetFloatv(GL_POINT_SIZE_GRANULARITY, &sizeStep);
GLfloat curStep = size[0];
for (GLfloat a = 0.0; a < GL_PI * 3.0f; a += 0.1f)
{
GLfloat x = 50.0f * cos(a);
GLfloat y = 50.0f * sin(a);
//设置点的大小
glPointSize(curStep);
curStep += sizeStep;
//设置顶点
glBegin(GL_POINTS);
glVertex3f(x, y, z);
glEnd();
//调整z值
z += 0.5f;
}
glPopMatrix();
glFlush();
}

void ChangeSize(GLsizei w, GLsizei h)
{
GLfloat nRange = 100.0f;
if (h == 0)
{
h = 1;
}
//设置视口
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

//设置可视区域
GLfloat aspect = (GLfloat)w / (GLfloat)h;
if (w <= h)
{
glOrtho(-nRange, nRange, -nRange/aspect, nRange/aspect, -nRange, nRange);
}
else
{
glOrtho(-nRange*aspect, nRange*aspect, -nRange, nRange, -nRange, nRange);
}

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
//初始化工作
static void SetupRC()
{
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
}
//创建窗口
static void CreateWindow() {
glutInitWindowSize(200, 200);
glutCreateWindow( "3d Points");
}

int main( int args, char **argv)
{
glutInit(&args, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(200, 200);
glutCreateWindow( "draw points");
SetupRC();
glutDisplayFunc(RenderSences);
glutReshapeFunc(ChangeSize);
glutMainLoop();
return 0;
}

image

点的大小如果不指定的画,默认是1。点的大小的设置是存在限制的,不同的实现限制不同。可以通过

glGetFloatv(GL_POINT_SIZE_RANGE, size);

获得点的大小的范围,size[0]为最小值,size[1]为最大值。

通过  glGetFloatv(GL_POINT_SIZE_GRANULARITY, &sizeStep); 获得点大小之间的最小间隔。

PS:点和其他的几何图元不同,点不受透视除法的影响,即点离观察点近或远并不影响点最终投影到2d屏幕上的大小。另外点总是正方形的元素。为了获得圆点,必须在抗锯齿模式下绘制点。

另外需要注意的是glPointSize必须在glBegin和glEnd之外调用,并不是所有的函数在glBegin和glEnd之间调用都是合法的。 glPointSize所指定的点的大小并不是以像素为单位的,而是一个圆的近似直径,这个圆包含了这个点所使用的像素。

OpenGL超级宝典 第4版 中文版PDF+英文版+源代码 见 

OpenGL编程指南(原书第7版)中文扫描版PDF 下载

OpenGL 渲染篇

Ubuntu 13.04 安装 OpenGL

OpenGL三维球体数据生成与绘制【附源码】

Ubuntu下OpenGL编程基础解析

如何在Ubuntu使用eclipse for c++配置OpenGL  

更多《OpenGL超级宝典学习笔记》相关知识 见 

相关内容