这一节开始学习opengl的几何图形绘制。借助opengl提供的图元绘制函数,可是实现GUI的功能。
顶点是最基本的图元,是所有opengl图元的最小公约数。顶点的几何意义不仅仅是空间的一个点,而是两条直线或曲线相交的点。这是图元的本质。图元只是一组顶点的集合,他们构成了在屏幕上所绘制的形状。opengl共有10种图元。
绘制图元其中的一种方式是使用glBegin()命令告诉opengl开始对一组顶点进行解释。
点为最简单的图元:
glBegin(GL_POINTS);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(50.0f, 50.0f, 50.0f);
glEnd();
GL_POINTS告诉opengl对接下来的顶点如何解释。
本节源码如下:
//实现本函数功能使用到了greeglut.h提供的函数声明以及freeglut.lib的函数实现,初次之外没有用到别的任何库支持。
#include "GL/freeglut.h"
#include <math.h>
#define GL_PI 3.1416f
GLfloat g_fXRot = 0.0f;
GLfloat g_fYRot = 0.0f;
void RenderScene(void)
{
//clear the window use the current color
glClear(GL_COLOR_BUFFER_BIT);
GLfloat x, y, z, angle;
GLfloat sizes[2];
GLfloat step;
GLfloat curSize;
glGetFloatv(GL_POINT_SIZE_RANGE, sizes);
glGetFloatv(GL_POINT_SIZE_GRANULARITY, &step);
curSize = sizes[0];
//
glPushMatrix();
glRotatef(g_fXRot, 1.0f, 0.0f, 0.0f);
glRotatef(g_fYRot, 0.0f, 1.0f, 0.0f);
z = -50.0f;
glBegin(GL_POINTS);
for (angle = 0.0f; angle <= 2.0f*GL_PI*3.0f; angle += 0.1f)
{
x = (GLfloat)50.0*sin(angle);
y = (GLfloat)50.0*cos(angle);
glPointSize(curSize);
curSize += step;
z += 0.5f;
glVertex3f(x, y, z);
}
glEnd();
glPopMatrix();
//
glutSwapBuffers();
}
void SetupRC(void)
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f);
}
//
void ChangeSize(GLsizei w, GLsizei h)
{
//
if (h == 0)
{
h = 1;
}
glViewport(0, 0, w, h);
//reset coordinate system
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//build clipping region(left, right, bottom, top, near, far)
GLfloat aspectRatio = (GLfloat)w/h;
GLfloat nRange = 100.0f;
if (w <= h)
{
glOrtho(-nRange, nRange, -nRange/aspectRatio, nRange/aspectRatio, nRange, -nRange);
}
else
{
glOrtho(-nRange*aspectRatio, nRange*aspectRatio, -nRange, nRange, nRange, -nRange);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void SpecialKey(int key, int x, int y)
{
//X,Y轴的偏转角度方向。正时,沿Y轴向X正方向偏转。
switch (key)
{
case GLUT_KEY_UP:
{
g_fYRot += 5.0f;
if (g_fYRot > 360.0f)
{
g_fYRot = 0.0f;
}
}
break;
case GLUT_KEY_DOWN:
{
g_fYRot -= 5.0f;
if (g_fYRot <= -360.0f)
{
g_fYRot = 0.0f;
}
}
break;
case GLUT_KEY_LEFT:
{
g_fXRot -= 5.0f;
if (g_fXRot <= -360.0f)
{
g_fXRot = 0.0f;
}
}
break;
case GLUT_KEY_RIGHT:
{
g_fXRot += 5.0f;
if (g_fXRot > 360.0f)
{
g_fXRot = 0.0f;
}
}
break;
default:
break;
}
// Refresh the Window
glutPostRedisplay();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowSize(1024, 768);
glutCreateWindow("Chapter3_DrawPoint");
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
glutSpecialFunc(SpecialKey);
SetupRC();
glutMainLoop();
return 0;
}
本节代码下载地址(visual studio 2012工程):http://download.csdn.net/detail/airbigboy/6343873
本节中用到了几个新的函数:glutSpecialFunc(),这是glut库的案件相应的函数,相信用一次就ok了。
glutPostRedisplay()函数,发送重绘指令。
glPushMatrix()和glPopMatrix()两个函数维护opengl的矩阵堆栈,用于在我们设置了一个变化之后,绘制不同物体是对同一变化的重置,在下一章中会用到,并详细解释,而在本章中,其作用和glLoadIdentify()函数是一样的。