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

3D概念

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

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

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()之间的缩进,这样是为了更容易寻找顶点源。是不成文的约定。
OpenGL超级宝典学习笔记——空间绘图画点

 

绘制图形

我们知道如何在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; 
     
}

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

点的大小如果不指定的画,默认是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所指定的点的大小并不是以像素为单位的,而是一个圆的近似直径,这个圆包含了这个点所使用的像素。

相关推荐