如何仅绘制填充了顶点数据的数组的某些部分

时间:2019-01-18 09:42:36

标签: c++ opengl

上下文:

我正在尝试在openGL中创建一个类似于自然界的开放世界场景。长度为terrainVertices的数组3*NUM_OF_VERTICES包含地形的顶点数据,这是一个噪声生成的高度图。每个顶点都有x,y,z坐标,并根据y的值为顶点指定某种颜色,从而在深水和山峰之间产生某种平滑过渡。

问题:

当顶点附近具有y值(例如y<0)时,形成了色淀。着色是按预期执行的,但是结果不现实。看起来像个蓝坑:

enter image description here

我决定解决此问题的方法是通过创建一层顶点,这些顶点出现在湖上,具有y=0和具有低alpha值的浅蓝色,从而在下面形成一个表面错觉这就是真正的湖泊。

terrainVertices数组由元素数组elements[NUM_OF_ELEMENTS]索引。我遍历元素数组并尝试查找索引的三元组,这些索引对应于带有y<0的顶点。我将与该条件匹配的每个三元组收集到一个向量中,然后创建一个新的顶点数组对象,该顶点数组对象具有与terrain相同的顶点数据,但具有我刚刚描述的新元素缓冲区对象。将位于“水下”的顶点的y值替换为0,以便粘贴到湖面。

这是我用来完成此操作的代码:

std::vector<GLuint> waterElementsV;

//iterating over every triangle
for (int i = 0; i < NUM_OF_ELEMENTS / 3; i++) {

    //accessing each vertex based on its index from the element array
    //checking if its height is lower than zero
    //elements[3*i+0, +1, +2] represents the indices for a triangle
    //terrainVertices[index + 1] represents the height of the vertex
    if (terrainVertices[3 * (elements[3 * i]) + 1] < 0 &&
        terrainVertices[3 * (elements[3 * i + 1]) + 1] < 0 &&
        terrainVertices[3 * (elements[3 * i + 2]) + 1] < 0) {


        //since its a valid triangle, add its indices in the elements array.
        waterElementsV.push_back(elements[3 * i]);
        waterElementsV.push_back(elements[3 * i + 1]);
        waterElementsV.push_back(elements[3 * i + 2]);

    }

}


//iterating through the terrain vertices, and setting
//each appropriate vertex's y value to water surface level y = 0
for (unsigned int i = 0; i < waterElementsV.size(); i++) {

    currentIndex = waterElementsV[i];

    terrainVertices[3 * currentIndex + 1] = 0;

}

//get the vector's underlying array
waterElements = waterElementsV.data();


glGenVertexArrays(1, &waterVAO);
glBindVertexArray(waterVAO);

glGenBuffers(1, &waterVerticesVBO);
glBindBuffer(GL_ARRAY_BUFFER, waterVerticesVBO);
glBufferData(GL_ARRAY_BUFFER, NUM_OF_VERTICES, terrainVertices, GL_STATIC_DRAW);

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);


glGenBuffers(1, &waterEBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, waterEBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(waterElements), waterElements, GL_STATIC_DRAW);

着色器非常简单,因为我只需要分配一个位置和一种颜色即可。没有使用世界视图投影矩阵,因为无论如何,每个对象都是相对于地形绘制的。

顶点着色器:

#version 330 core

layout (location = 0) in vec3 pos;

void main()
{
    gl_Position = vec4(pos, 1.0);
}  

片段着色器:

#version 330 core

out vec4 fragColor;

void main()
{
    fragColor = vec4(0, 0, 0, 1);
}  

结果与上图完全相同。我一直在思考发生了什么事,但似乎无法弄清楚……请注意,这些湖泊分布在随机的地方,不一定彼此相邻。

任何帮助或提示都将不胜感激:)

0 个答案:

没有答案