为了使海面更加有真实感,我们还要为其添加法线贴图,使其更具质感。为了保证法线方向的正确性,我们需要引入切线空间,并对于每一个三角面片计算其切线空间中的tangent和bitangent 代码如下:
void tangentandbitangent(GLint x){ int x1, x2, x3; if (x % 2 == 0)//我绘制图像的时候使用的是GL_TRIANGLE_STRip { x1 = x - 2; x2 = x - 1; x3 = x; } else { x1 = x - 1; x2 = x - 2; x3 = x; } vec3 pos1 = vec3(VBOdata[x1].vertex_data[0], VBOdata[x1].vertex_data[1], VBOdata[x1].vertex_data[2]); vec3 pos2 = vec3(VBOdata[x2].vertex_data[0], VBOdata[x2].vertex_data[1], VBOdata[x2].vertex_data[2]); vec3 pos3 = vec3(VBOdata[x3].vertex_data[0], VBOdata[x3].vertex_data[1], VBOdata[x3].vertex_data[2]); vec2 uv1 = vec2(VBOdata[x1].texcoord_data[0], VBOdata[x1].texcoord_data[1]); vec2 uv2 = vec2(VBOdata[x2].texcoord_data[0], VBOdata[x2].texcoord_data[1]); vec2 uv3 = vec2(VBOdata[x3].texcoord_data[0], VBOdata[x3].texcoord_data[1]); vec3 edge1 = pos2 - pos1; vec3 edge2 = pos3 - pos1; vec2 deltaUV1 = uv2 - uv1; vec2 deltaUV2 = uv3 - uv1; GLfloat f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y); vec3 tangent, bitangent; tangent.x = f * (deltaUV2.y * edge1.x - deltaUV1.y * edge2.x); tangent.y = f * (deltaUV2.y * edge1.y - deltaUV1.y * edge2.y); tangent.z = f * (deltaUV2.y * edge1.z - deltaUV1.y * edge2.z); tangent = normalize(tangent); bitangent.x = f * (-deltaUV2.x * edge1.x + deltaUV1.x * edge2.x); bitangent.y = f * (-deltaUV2.x * edge1.y + deltaUV1.x * edge2.y); bitangent.z = f * (-deltaUV2.x * edge1.z + deltaUV1.x * edge2.z); bitangent = normalize(bitangent); VBOdata[x1].tangents[0] = VBOdata[x2].tangents[0] = VBOdata[x3].tangents[0] = tangent.x; VBOdata[x1].tangents[1] = VBOdata[x2].tangents[1] = VBOdata[x3].tangents[1] = tangent.y; VBOdata[x1].tangents[2] = VBOdata[x2].tangents[2] = VBOdata[x3].tangents[2] = tangent.z; VBOdata[x1].bitangents[0] = VBOdata[x2].bitangents[0] = VBOdata[x3].bitangents[0] = bitangent.x; VBOdata[x1].bitangents[1] = VBOdata[x2].bitangents[1] = VBOdata[x3].bitangents[1] = bitangent.y; VBOdata[x1].bitangents[2] = VBOdata[x2].bitangents[2] = VBOdata[x3].bitangents[2] = bitangent.z;}我们需要稍微更新一下传递数据的代码:
void RenderWater(){ glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(VBOdata), VBOdata, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 14 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat))); glEnableVertexAttribArray(3); glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(GLfloat), (GLvoid*)(8 * sizeof(GLfloat))); glEnableVertexAttribArray(4); glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(GLfloat), (GLvoid*)(11 * sizeof(GLfloat))); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); glBindVertexArray(VAO); for (int c = 0; c<(STRIP_COUNT - 1); c++) glDrawArrays(GL_TRIANGLE_STRIP, STRIP_LENGTH * 2 * c, STRIP_LENGTH * 2); glBindVertexArray(0);}
虽然效果还是有点屎,但是终于稍微有点海面的样子了,然而这些还是远远不够。。。。。比如水面倒影、水面折射、水面反射这些还没有进行添加,所以这只能算是我第一个半脱离教程的OpenGL代码,还需要继续努力啊。。。。。
PS:http://download.csdn.net/detail/xiewenzhao123/9770840 整个工程文件
新闻热点
疑难解答