一步步写水面渲染(二)
2017-03-04 09:14
162 查看
第六步:计算纹理坐标
因为,先前没有思考完善,所以导致需要修改一些代码从而更加方便的存储顶点位置数据、顶点法线数据、顶点纹理坐标数据struct DATAS { GLfloat vertex_data[3]; GLfloat normal_data[3]; GLfloat texcoord_data[2]; }VBOdata[DATA_LENGTH]; //先前,我是直接用两个数组来存储位置和法线数据,现在为了在传递数据时便于计算,我用一个结构体来存储一个顶点的所有信息 int pt; for (int c = 0; c<(STRIP_COUNT - 1); c++) { for (int l = 0; l<2 * STRIP_LENGTH; l++) { if (l % 2 == 1) { pt = c*STRIP_LENGTH + l / 2; } else { pt = c*STRIP_LENGTH + l / 2 + STRIP_LENGTH; } index = STRIP_LENGTH * 2 * c + l; for (int i = 0; i<3; i++) { VBOdata[index].vertex_data[i] = pt_strip[pt * 3 + i]; VBOdata[index].normal_data[i] = pt_normal[pt * 3 + i]; if (i < 2) VBOdata[index].texcoord_data[i] = (pt_strip[pt * 3 + i] + 1)/2; } } } //上述是修改后的对顶点进行排序的代码 //因为我的顶点位置坐标的值在[-1,1]范围内,且我偷懒直接对整个海面用一张纹理贴图,又因为纹理坐标的值在[0,1]的范围内,所以我直接将位置坐标中的x轴坐标和y轴坐标通过+1再除以2的方式将其改变为[0,1]的区间范围中。 //接下来更改一下传递数据的代码 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, 8 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * 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); }
第七步:vertexshader
#version 330 core layout (location = 0) in vec3 position; layout (location = 1) in vec3 normal; layout (location = 2) in vec2 texCoords; out VS_OUT { vec3 FragPos; vec3 Normal; vec2 TexCoords; } vs_out; uniform mat4 projection; uniform mat4 view; uniform mat4 model; void main() { gl_Position = projection * view * model * vec4(position, 1.0f); vs_out.FragPos = position; vs_out.Normal = normal; vs_out.TexCoords = texCoords; }
第八步:fragmentshader
//这里采用了Blinn-Phong光照模型 #version 330 core out vec4 FragColor; in VS_OUT { vec3 FragPos; vec3 Normal; vec2 TexCoords; } fs_in; uniform sampler2D floorTexture; uniform vec3 lightPos; uniform vec3 viewPos; void main() { vec3 color = texture(floorTexture, fs_in.TexCoords).rgb; vec3 ambient = 0.05 * color; vec3 lightDir = normalize(lightPos - fs_in.FragPos); vec3 normal = normalize(fs_in.Normal); float diff = max(dot(lightDir, normal), 0.0); vec3 diffuse = diff * color; vec3 viewDir = normalize(viewPos - fs_in.FragPos); vec3 reflectDir = reflect(-lightDir, normal); float spec = 0.0; vec3 halfwayDir = normalize(lightDir + viewDir); spec = pow(max(dot(normal, halfwayDir), 0.0), 32.0); vec3 specular = vec3(0.3) * spec; // assuming bright white light color FragColor = vec4(ambient + diffuse + specular, 1.0f); }
完成以上步骤后会得到如下效果:
现在,模拟海平面已经初见其效果,还需要更多的代码进行完善
ps:纹理贴图可以随便找一张海面效果图
相关文章推荐
- 一步步写水面渲染(三)
- 一步步写水面渲染(一)
- irrlicht引擎:真实的水面渲染
- 我的3D引擎----水面渲染
- 我的3D引擎----水面渲染
- 我的3D引擎----水面渲染
- 水面渲染小结
- 水面渲染
- 水面渲染小结
- (转)水面渲染小结
- 水面渲染
- Unity3D-实现水面渲染
- irrlicht引擎:真实的水面渲染
- 水面的简单渲染 – Gerstner波
- 一步步学习微软InfoPath2010和SP2010--第三章节--表单设计基础:处理InfoPath布局、控件和视图(9)--添加第二个视图到Flight Delay表单
- android ndk 快速渲染yuv数据
- 一步步学习微软InfoPath2010和SP2010--第四章节--处理SP列表表单(5)--列表表单页面
- 女性是如何一步步远离编程的?
- 在C#中应用MapObjects(渲染效果)
- 一步步了解ESB (二) Mule ESB-Basic Studio Tutorial