文章出處

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


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()