顶点数组函数可以在一个数组里包含大量的与顶点相关的数据,并且可以减少函数的调用。使用顶点数组需要先启用顶点数组功能,使用glEnableClientState函数启用顶点数组,参数可以是GL_VERTEX_ARRAY(顶点数据)和GL_COLOR_ARRAY(颜色数组),颜色数组可以为每个顶点分别分配颜色。
glVertexPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
第一个参数size,代表顶点数组中数据的维度,只能是2,3或4,即二维、三维、四维;
第二个参数type,代表顶点数组中每个数据的类型,如GL_INT,GL_FLOAT;
第三个参数stride,代表连续顶点之间的字节偏移量,经常使用一个int型常量乘以sizeof(int/float)来表示;
第四个参数pointer,指向数组数据的起始位置;
glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
第一个参数mode指定用顶点数组创建的图元的类型;
第二个参数count,代表整个图元包含的顶点数;
第三个参数type,是顶点数组序列数据的类型,GL_UNSIGNED_BYTE或GL_UNSIGNED_INT;
第四个参数indices,顶点数组序列数据的起始位置;
glDrawArrays (GLenum mode, GLint first, GLsizei count);
第二个参数first指定从顶点数组内起始的位置偏移量;
第三个参数count指定顶点数量;
用顶点数组绘制立方体的三个面:
#include <glut.h>
GLsizei windowWidth=400,windowHeight=400;
GLfloat data[]={-10,-10,10,1,0,0,
10,-10,10,0,1,0,
10,10,10,0,0,1,
-10,10,10,1,1,0,
-10,-10,-10,1,0,1,
10,-10,-10,0,1,1,
10,10,-10,1,1,1};
GLubyte index[]={0,1,2,3,4,5,1,0,2,1,5,6};
void Init()
{
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(75,1,1,50);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(20,-20,30,0,0,0,0,1,0);
}
void Display()
{
glClearColor(1,1,1,1);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(3,GL_FLOAT,6*sizeof(GLfloat),&data[3]);
glVertexPointer(3,GL_FLOAT,6*sizeof(GLfloat),&data[0]);
//glDrawArrays(GL_QUADS,0,8);
glDrawElements(GL_QUADS,12,GL_UNSIGNED_BYTE,index);
glutSwapBuffers();
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv); //初始化GLUT
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowPosition(500, 200);
glutInitWindowSize(windowWidth, windowHeight);
glutCreateWindow("OpenGL");
Init();
glutDisplayFunc(&Display); //回调函数
glutMainLoop();
}
光栅是一个一个离散的单元,在显示的时候具有锯齿形或阶梯状外观,这种由于低频取样(不充分取样)导致的信息失真的情况称为走样,OpenGL中可以对走样进行校正。
对于点的反锯齿校正使用glEnable(GL_POINT_SMOOTH)启用对点的锯齿校正,glHint (GL_POINT_SMOOTH, GL_NICEST)函数来进行校正。
glHint函数的第一个参数是校正的图元类型:
- GL_POINT_SMOOTH 点
- GL_LINE_SMOOTH 线
- GL_POLYGON_SMOOTH 多边形
第二个参数是对校正效果的设定:
- GL_DONT_CARE 不校正
- GL_FASTEST 优先考虑处理速度
- GL_NICEST 优先考虑显示质量
#include <glut.h>
GLsizei windowWidth=400,windowHeight=400;
void Init()
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluOrtho2D(0,400,0,400);
}
void Display()
{
glClearColor(1,1,1,1);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0,0,1);
glPointSize(10);
glBegin(GL_POINTS);
glVertex2f(100,300);
glEnd();
glEnable(GL_POINT_SMOOTH);
glHint(GL_POINT_SMOOTH,GL_NICEST);
glBegin(GL_POINTS);
glVertex2f(130,300);
glEnd();
glDisable(GL_POINT_SMOOTH);
glColor3f(1,0,0);
glLineWidth(10);
glBegin(GL_LINES);
glVertex2f(80,120);
glVertex2f(280,320);
glEnd();
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH,GL_FASTEST);
glBegin(GL_LINES);
glVertex2f(80,80);
glVertex2f(280,280);
glEnd();
glDisable(GL_LINE_SMOOTH);
glFlush();
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv); //初始化GLUT
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(500, 200);
glutInitWindowSize(windowWidth, windowHeight);
glutCreateWindow("OpenGL");
Init();
glutDisplayFunc(&Display); //回调函数
glutMainLoop();
}
左侧是没有经过反走样校正的点和线,右侧经过校正: