Я создаю ландшафт из файла .bmp, как очень ранний предшественник для стратегической игры. В моем коде я загружаю файл BMP как текстуру openGL, затем использую двойной цикл для генерации координат (x, y redChannel). Затем я создаю индексы, снова дважды зацикливаясь и генерируя треугольники для квадрата между (x, y) и (x + 1, y + 1). Однако, когда я запускаю код, я получаю дополнительный треугольник, идущий от конца одной строки до начала следующей строки, который я не могу решить. Это происходит только тогда, когда я использую различные высоты и достаточно большую карту, или, по крайней мере, это не видно иначе.
Это код:
void Map::setupVertices(GLsizei* &sizeP, GLint * &vertexArray, GLubyte* &colorArray){
//textureNum is the identifier generated by glGenTextures
GLuint textureNum = loadMap("heightmap.bmp");
//Bind the texture again, and extract the needed data
glBindTexture(GL_TEXTURE_2D, textureNum);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
GLint i = height*width;
GLubyte * imageData = new GLubyte[i+1];
glGetTexImage(GL_TEXTURE_2D,0,GL_RED, GL_UNSIGNED_BYTE, &imageData[0]);
//Setup varibles: counter (used for counting vertices)
//VertexArray: pointer to address for storing the vertices. Size: 3 ints per point, width*height points total
//ColorArray: pointer to address for storing the color data. 3 bytes per point.
int counter = 0;
vertexArray = new GLint[height*width*3];
colorArray = new GLubyte[height*width*3];
srand(time(NULL));
//Loop through rows
for (int y = 0; y < height; y++){
//Loop along the line
for (int x=0; x < width; x++){
//Add vertices: x, y, redChannel
//Add colordata: the common-color.
colorArray[counter] = imageData[x+y*width];
vertexArray[counter++] = x;
colorArray[counter] = imageData[x+y*width];
vertexArray[counter++] = y;
colorArray[counter] = imageData[x+y*width];//(float) (rand() % 255);
vertexArray[counter++] = (float)imageData[x+y*width] /255 * maxHeight;
}
}
//"Return" total vertice amount
sizeP = new GLsizei(counter);
}
void Map::setupIndices(GLsizei* &sizeP, GLuint* &indexArray){
//Pointer to location for storing indices. Size: 2 triangles per square, 3 points per triangle, width*height triangles
indexArray = new GLuint[width*height*2*3];
int counter = 0;
//Loop through rows, don't go to top row (because those triangles are to the row below)
for (int y = 0; y < height-1; y++){
//Loop along the line, don't go to last point (those are connected to second last point)
for (int x=0; x < width-1; x++){
//
// TL___TR
// | / |
// LL___LR
int lowerLeft = x + width*y;
int lowerRight = lowerLeft+1;
int topLeft = lowerLeft + width+1;
int topRight = topLeft + 1;
indexArray[counter++] = lowerLeft;
indexArray[counter++] = lowerRight;
indexArray[counter++] = topLeft;
indexArray[counter++] = topLeft;
indexArray[counter++] = lowerRight;
indexArray[counter++] = topRight;
}
}
//"Return" the amount of indices
sizeP = new GLsizei(counter);
}
Я в конечном итоге нарисовать это с помощью этого кода:
void drawGL(){
glPushMatrix();
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3,GL_INT,0,mapHeight);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(3,GL_UNSIGNED_BYTE,0,mapcolor);
if (totalIndices != 0x00000000){
glDrawElements(GL_TRIANGLES, *totalIndices, GL_UNSIGNED_INT, indices);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glPopMatrix();
}
Вот картина результата:
http://s22.postimg.org/k2qoru3kx/open_GLtriangles.gif
И только с синими линиями и черным фоном.
http://s21.postimg.org/5yw8sz5mv/triangle_Error_Blue_Line.gif
Похоже, что один из них движется в другом направлении, на самом краю справа, но сейчас я предполагаю, что это может быть связано с той же проблемой.
Я бы упростил эту часть:
int lowerLeft = x + width * y;
int lowerRight = (x + 1) + width * y;
int topLeft = x + width * (y + 1);
int topRight = (x + 1) + width * (y + 1);
Проблема выглядит topLeft
имеет дополнительный + 1
когда он должен иметь только + width
,
Это приводит к тому, что обе «верхние» вершины сдвигаются на один столбец. Вы можете не заметить смещения в сетке, и, как вы указали, они не видны, пока высота не изменится.
Кроме того, возвращаясь new GLsizei(counter)
кажется немного круглым. Почему бы просто не пройти GLsizei& counter
,
Это тоже стоит посмотреть. Вы можете сохранить значительную часть данных, используя стрип-примитивы для многих процедурных объектов:
Других решений пока нет …