2016-05-28 23 views
1

Ich versuche multitextured Gelände zu machen. Aber wenn ich versuche, 3 Texturen zu binden, wird nur eine Textur angezeigt. C# -Code hier:OpenTK binden mehrere Texturen auf Shader

GL.UseProgram(program); 
//Active textures, glId - is texture id, generated by GL.GenTexture() 
GL.BindTextures(0,3,new int[3]{grass.glId,grass_normal.glId,stone.glId}); 
//Set shaders uniform, diffuse is a shader class 
diffuse.SetUniform("mainTexture",grass.glId); 
diffuse.SetUniform("gNormalMap",grass_normal.glId); 
diffuse.SetUniform("stoneTexture",stone.glId);  
//Just some render code, for example 
GL.BindVertexArray(mesh.vao); 
GL.DrawElements(PrimitiveType.Triangles, 
mesh.triangles.Count,DrawElementsType.UnsignedInt, IntPtr.Zero);   
//Unbind all 
GL.UseProgram(0); 
GL.BindVertexArray(0); 
GL.BindBuffer(BufferTarget.ArrayBuffer, 0); 
GL.BindBuffer(BufferTarget.ElementArrayBuffer,0); 
GL.BindTextures(0,3,new int[3]{0,0,0}); 

Es gibt Shader-Fragment Programm:

#version 140 
uniform sampler2D mainTexture;//grass 
uniform sampler2D gNormalMap;//grass normal 
uniform sampler2D stoneTexture;//stone 
out vec4 FragColor; 
//hide other uniforms and inputs 

void main (void){ 
//Some light code 
vec4 x = texture2D(stoneTexture, fract(vTexCoord.st * texSize)); 
vec4 y = texture2D(mainTexture, fract(vTexCoord.st * texSize)); 
vec4 tex = x;//display stone, but i want to mix textures later 
//I don't know why, but there is no difference, 
//if i use stone - 'tex = x', or grass - 'tex = y' 
//in both cases, only grass is displayed 
FragColor = color*tex*(diffuse+ambient);//Color 
} 

ich zum ersten Mal versucht, Stein dann Gras zu binden, und es ist ein Stein ohne Gras angezeigt. Ich meine so:

GL.BindTextures(0,3,new int[3]{stone.glId,grass_normal.glId,grass.glId}); 

Es gibt keinen Effekt, nur eine Textur wird angezeigt.

+0

Ich möchte nur sicherstellen, dass ich verstehe. Sie fragen, warum das passiert, oder? –

+0

Ja, aber jetzt repariere ich es (lesen Sie den nächsten Beitrag) –

Antwort

2
GL.BindTextures(0,3,new int[3]{grass.glId,grass_normal.glId,stone.glId}); 

Ist diese Funktion sinnvoll ist, die Ihre glId Felder sind OpenGL Objektnamen bedeutet.

Was bedeutet:

diffuse.SetUniform("mainTexture",grass.glId); 
diffuse.SetUniform("gNormalMap",grass_normal.glId); 
diffuse.SetUniform("stoneTexture",stone.glId); 

Dieser Code jetzt keinen Sinn macht.

Sampler-Uniform-Werte sind nicht die tatsächlichen OpenGL-Texturnamen. Wenn ja, wäre es nicht nötig, sie an den Kontext zu binden.

Sampler-Uniformen werden auf die Textureinheit Indizes gesetzt. Somit wird der Sampler von jeder Textur abrufen, die an die gegebene Textureinheit gebunden ist. Da Ihre glBindTextures Aufruf verwendet, um Texturbildeinheiten [0,2], sollte Ihre einheitliche Einstellung widerspiegelt:

diffuse.SetUniform("mainTexture", 0); 
diffuse.SetUniform("gNormalMap", 1); 
diffuse.SetUniform("stoneTexture", 2); 

Meine Vermutung, warum dies schien für einen Fall zu arbeiten, wäre, dass Sie Glück gehabt. Viele OpenGL-Implementierungen geben Texturnamen zurück, die mit 1 beginnen. Sie haben also wahrscheinlich einen Texturnamen erhalten, der genauso mit der Textureinheit übereinstimmt, an die Sie die Textur gebunden haben.

Verwandte Themen