CSharpGL(10)两个纹理叠加

CSharpGL(10)两个纹理叠加

本文很简单,只说明如何用shader实现叠加两个纹理的效果。

另外,最近CSharpGL对渲染框架做了修改,清理一些别扭的内容(DoRender()前后的事件都去掉了,明确了Renderer的概念)。本文顺带也成了对新框架的一个应用过程的例子。

下载

这个示例是CSharpGL的一部分,CSharpGL已在GitHub开源,欢迎对OpenGL有兴趣的同学加入(https://github.com/bitzhuwei/CSharpGL

先写shader

Shader是算法,VBO是数据结构。数据结构常有,而算法不常有。先写shader,万事可定。

Vertex 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 }

Fragment shader

片段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

一个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();

posted @ 2016-01-24 13:03 BIT祝威 阅读(...) 评论(...) 编辑 收藏

Large Visitor Globe

Flag Counter
Flag Counter