NIG*_*IGO 27 c++ opengl geometry plane gl-triangle-strip
生成使用三角形条绘制平面的顶点列表的最佳算法是什么?
我正在寻找一个接收平面宽度和高度的函数,并返回一个包含正确索引顶点的浮点数组.
width表示每行的顶点数.
height表示每列的顶点数.
float* getVertices( int width, int height ) {
...
}
void render() {
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, getVertices(width,heigth));
glDrawArrays(GL_TRIANGLE_STRIP, 0, width*height);
glDisableClientState(GL_VERTEX_ARRAY);
}
Run Code Online (Sandbox Code Playgroud)
NIG*_*IGO 29
谢谢大家.我编码了这个.这是对的吗?或者生成的条带有点错误?
int width;
int height;
float* vertices = 0;
int* indices = 0;
int getVerticesCount( int width, int height ) {
return width * height * 3;
}
int getIndicesCount( int width, int height ) {
return (width*height) + (width-1)*(height-2);
}
float* getVertices( int width, int height ) {
if ( vertices ) return vertices;
vertices = new float[ getVerticesCount( width, height ) ];
int i = 0;
for ( int row=0; row<height; row++ ) {
for ( int col=0; col<width; col++ ) {
vertices[i++] = (float) col;
vertices[i++] = 0.0f;
vertices[i++] = (float) row;
}
}
return vertices;
}
int* getIndices( int width, int height ) {
if ( indices ) return indices;
indices = new int[ iSize ];
int i = 0;
for ( int row=0; row<height-1; row++ ) {
if ( (row&1)==0 ) { // even rows
for ( int col=0; col<width; col++ ) {
indices[i++] = col + row * width;
indices[i++] = col + (row+1) * width;
}
} else { // odd rows
for ( int col=width-1; col>0; col-- ) {
indices[i++] = col + (row+1) * width;
indices[i++] = col - 1 + + row * width;
}
}
}
if ( (mHeight&1) && mHeight>2 ) {
mpIndices[i++] = (mHeight-1) * mWidth;
}
return indices;
}
void render() {
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer( 3, GL_FLOAT, 0, getVertices(width,height) );
glDrawElements( GL_TRIANGLE_STRIP, getIndicesCount(width,height), GL_UNSIGNED_INT, getIndices(width,height) );
glDisableClientState( GL_VERTEX_ARRAY );
}
Run Code Online (Sandbox Code Playgroud)
宽度= 4,高度= 4这是我得到的:
在这里我修改一些顶点高度:
Jay*_*rod 13
这里有一些代码执行此操作(未经过测试,但至少可以获得这个想法):
void make_plane(int rows, int columns, float *vertices, int *indices) {
// Set up vertices
for (int r = 0; r < rows; ++r) {
for (int c = 0; c < columns; ++c) {
int index = r*columns + c;
vertices[3*index + 0] = (float) c;
vertices[3*index + 1] = (float) r;
vertices[3*index + 2] = 0.0f;
}
}
// Set up indices
int i = 0;
for (int r = 0; r < rows - 1; ++r) {
indices[i++] = r * columns;
for (int c = 0; c < columns; ++c) {
indices[i++] = r * columns + c;
indices[i++] = (r + 1) * columns + c;
}
indices[i++] = (r + 1) * columns + (columns - 1);
}
}
Run Code Online (Sandbox Code Playgroud)
第一个循环在标准矩形网格中设置顶点数组.有R*C顶点.
第二个循环设置索引.通常,网格中每个方格有两个顶点.每个顶点将导致绘制一个新的三角形(使用前两个顶点),因此每个正方形用两个三角形绘制.
每行开头和结尾的第一个和最后一个顶点是重复的.这意味着每行之间有两个零区域(简并三角形).这允许我们在一个大三角形条带中绘制整个网格.这种技术称为拼接.
上面的代码都没有给出正确的网格生成.关于如何在简单的平面上制作三角形条带的非常好的文章:http://www.learnopengles.com/android-lesson-eight-an-introduction-to-index-buffer-objects-ibos/
这是我的测试代码,实际测试和完全工作:
int plane_width = 4; // amount of columns
int plane_height = 2; // amount of rows
int total_vertices = (plane_width + 1) * (plane_height + 1);
planeVert = new CIwFVec2[total_vertices];
memset(planeVert, 0, sizeof(CIwFVec2) * total_vertices);
int numIndPerRow = plane_width * 2 + 2;
int numIndDegensReq = (plane_height - 1) * 2;
int total_indices = numIndPerRow * plane_height + numIndDegensReq;
planeInd = new uint16[total_indices];
make_plane(plane_width, plane_height, planeVert, planeInd);
...
void make_plane(int width, int height, CIwFVec2 *vertices, uint16 *indices)
{
width++;
height++;
int size = sizeof(CIwFVec2);
// Set up vertices
for(int y = 0; y < height; y++)
{
int base = y * width;
for(int x = 0; x < width; x++)
{
int index = base + x;
CIwFVec2 *v = vertices + index;
v->x = (float) x;
v->y = (float) y;
Debug::PrintDebug("%d: %f, %f", index, v->x, v->y);
}
}
Debug::PrintDebug("-------------------------");
// Set up indices
int i = 0;
height--;
for(int y = 0; y < height; y++)
{
int base = y * width;
//indices[i++] = (uint16)base;
for(int x = 0; x < width; x++)
{
indices[i++] = (uint16)(base + x);
indices[i++] = (uint16)(base + width + x);
}
// add a degenerate triangle (except in a last row)
if(y < height - 1)
{
indices[i++] = (uint16)((y + 1) * width + (width - 1));
indices[i++] = (uint16)((y + 1) * width);
}
}
for(int ind=0; ind < i; ind++)
Debug::PrintDebug("%d ", indices[ind]);
}
Run Code Online (Sandbox Code Playgroud)