opengl中有一个重启图元的函数:
glEnable(GL_PRIMITIVE_RESTART)
glPrimitiveRestartIndex(GLuint index)
//实例中定义为0xffff
当绘制大量相同类型的图元时,例如GL_TRIANGLE_STRIP,GL_LINE_STRIP等等,使用glDrawElement函数时,有些点是链接不上的,需要重新开始一个新的点然后继续绘图,因此就需要这个重启
图源,就是在索引或者顶点数组中没一部分绘图结束后再数组中加入特定值0xffff,然后继续画就会把下一个点当作起始点
#include "glut.h"
#include <QDebug>
#define BUFFER_OFFSET(offset) ((GLvoid*)nullptr+offset)
#define XStart -0.8
#define XEnd 0.8
#define YStart -0.8
#define YEnd 0.8
#define NumXPoints 11
#define NumYPoints 11
#define NumPoints (NumXPoints*NumYPoints)
#define NumPointsPerStrip (2*NumXPoints)
#define NumStrips (NumYPoints-1)
#define RestartIndex 0xffff
GLfloat *vertices;
GLushort *indices;
void Init()
{
GLuint vbo,ebo;
GLfloat *vertices;
GLushort *indices;
vertices = new GLfloat[2*NumPoints];// (GLfloat*)malloc(2*NumPoints*sizeof(GLfloat));
glGenBuffers(1,&vbo);
glBindBuffer(GL_ARRAY_BUFFER,vbo);
glBufferData(GL_ARRAY_BUFFER,2*NumPoints*sizeof(GLfloat),NULL,GL_STATIC_DRAW);
vertices = glMapBuffer(GL_ARRAY_BUFFER,GL_WRITE_ONLY);
if(vertices == NULL)
{
fprintf(stderr,"Unable to map vertex buffer\n"); exit(EXIT_FAILURE);
}
GLfloat dx = (XEnd-XStart) / (NumXPoints - 1); //dx = 0.16
GLfloat dy = (YEnd-YStart) / (NumYPoints -1); //dy = 0.16
GLfloat *tmp = vertices;
//此循环是添加所有的点到顶点数组 vertex { -0.8,-0.8,-0.64,-0.8,...,0,-0.8...........0.8,-0.8,
-0.8,-0.64,-0.64,-0.64,..0,-0.64,..........0.8 ,-0.64,
.
.
-0.8,0.8,-0.64,0.8,......0,0.8,.............0.8,0.8,
}
for(int j = 0; j < NumYPoints;++j)
{
GLfloat y = YStart + j*dy;
for(int i = 0; i < NumXPoints;++i)
{
GLfloat x = XStart +i*dx;
*tmp++ = x;
*tmp++ = y;
}
}
glVertexPointer(2,GL_FLOAT,0,vertices);
glEnableClientState(GL_VERTEX_ARRAY);
indices = new GLushort[NumStrips*(NumPointsPerStrip+1)];//(GLushort*)malloc(NumStrips*(NumPointsPerStrip+1)*sizeof(GLushort));
GLushort *index = indices;
此循环是添加所有的点到顶点数组 index{ 11,0,12,1,13,2,...,.........9,21,10,0xffff,
22,11,23,12,.................,32,21,0xffff,
.
.
121,110,122,111,......................131,120,
}
手动画一下就可知,当画到第一行的 9,21,10结束后,画第二行的22,11,23如果接着画就会从第10个点连接到点22,是不对的的,
但是重启后就会从22开始,这下就完美了,所以就很容易理解为什么要用此函数了
for(int j = 0; j < NumStrips;++j)
{
GLushort bottomRow = j*NumYPoints;
GLushort topRow = bottomRow+NumYPoints;
for(int i = 0; i < NumXPoints;++i)
{
*index++ = topRow + i;
*index++ = bottomRow + i;
}
*index++ = RestartIndex;
}
//此处声明起始值为RestartIndex
glPrimitiveRestartIndex(RestartIndex)
glEnable(GL_PRIMITIVE_RESTART)
}
//-------------------------------------------------------------------------------
void reshape(int w,int h)
{
glViewport(0,0,(GLsizei)w,(GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40,(GLfloat)w/(GLfloat)h,1,20);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glColor3f(1,1,1);
glDrawElements(GL_TRIANGLE_STRIP,NumStrips*(NumPointsPerStrip+1),GL_UNSIGNED_SHORT,indices);
glutSwapBuffers();
}
int main(int argc,char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH);
glutInitWindowSize(640,480);
glutInitWindowPosition(100,100);
glutCreateWindow("Maya Camera");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
Init();
glutMainLoop();
return 0;
}
引用一个别人运行的结果