CSharpGL(10)两个纹理叠加
本文很简单,只说明如何用shader实现叠加两个纹理的效果。
另外,最近CSharpGL对渲染框架做了修改,清理一些别扭的内容(DoRender()前后的事件都去掉了,明确了Renderer的概念)。本文顺带也成了对新框架的一个应用过程的例子。
这个示例是CSharpGL的一部分,CSharpGL已在GitHub开源,欢迎对OpenGL有兴趣的同学加入( https://github.com/bitzhuwei/CSharpGL )
Shader是算法,VBO是数据结构。数据结构常有,而算法不常有。先写shader,万事可定。
顶点shader用来设定顶点位置,传递贴图的UV坐标到fragment shader。
1 #version 150 core 2 3 in vec3 in_Position; 4 in vec2 in_UV; 5 out vec2 pass_UV; 6 7 uniform mat4 projectionMatrix; 8 uniform mat4 viewMatrix; 9 uniform mat4 modelMatrix; 10 11 void main(void) 12 { 13 gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(in_Position, 1.0); 14 15 pass_UV = in_UV; 16 }
片段shader根据UV坐标获取两个贴图上的颜色,然后按指定比例叠加。
1 #version 150 core 2 3 in vec2 pass_UV;//从vertex shader传来的UV坐标 4 out vec4 out_Color;//fragment shader的输出,名字不必是out_Color 5 uniform sampler2D texture1; 6 uniform sampler2D texture2; 7 uniform float percent;//叠加比例 8 9 void main(void) 10 { 11 out_Color = texture(texture1, pass_UV) * percent + texture(texture2, pass_UV) * (1.0 - percent); 12 }
一个Renderer对应一个(vertex shader+fragment shader+.. shader)组成的shader program。指定两个纹理的关键步骤见下面的代码。
1 protected override void DoRender(RenderEventArgs e) 2 { 3 ShaderProgram program = this.shaderProgram; 4 // 绑定shader 5 program.Bind(); 6 7 program.SetUniformMatrix4(strprojectionMatrix, projectionMatrix.to_array()); 8 program.SetUniformMatrix4(strviewMatrix, viewMatrix.to_array()); 9 program.SetUniformMatrix4(strmodelMatrix, modelMatrix.to_array()); 10 11 //设定第一个贴图 12 program.SetUniform(strtexture1, 0);//texture1.Name); 13 GL.ActiveTexture(GL.GL_TEXTURE0); 14 GL.Enable(GL.GL_TEXTURE_2D); 15 texture1.Bind(); 16 17 //设定第二个贴图 18 program.SetUniform(strtexture2, 1);//texture2.Name); 19 GL.ActiveTexture(GL.GL_TEXTURE1); 20 GL.Enable(GL.GL_TEXTURE_2D); 21 texture2.Bind(); 22 23 program.SetUniform(strpercent, percent); 24 25 if (this.vertexArrayObject == null) 26 { 27 var vertexArrayObject = new VertexArrayObject( 28 this.positionBufferRenderer, 29 this.colorBufferRenderer, 30 //this.normalBufferRenderer, 31 this.indexBufferRenderer); 32 //创建的过程就是执行一次渲染的过程,所以不必再调用Render(e, program); 33 vertexArrayObject.Create(e, program); 34 35 this.vertexArrayObject = vertexArrayObject; 36 } 37 else 38 { 39 this.vertexArrayObject.Render(e, program); 40 } 41 42 // 解绑shader 43 program.Unbind(); 44 45 texture2.Unbind(); 46 texture1.Unbind(); 47 } Renderer.DoRender(RenderEventArgs e)
要同时使用多个贴图的关键是调用 GL .ActiveTexture( GL .GL_TEXTURE0);
// 设定第一个贴图
program.SetUniform(strtexture1, 0); //texture1.Name);
GL .ActiveTexture( GL .GL_TEXTURE0);
GL .Enable( GL .GL_TEXTURE_2D);
texture1.Bind();