private void SetupVertexFormat(BatchInfo material, VertexDeclaration vertexDeclaration) { DrawTechnique technique = material.Technique.Res ?? DrawTechnique.Solid.Res; NativeShaderProgram nativeProgram = (technique.NativeShader ?? DrawTechnique.Solid.Res.NativeShader) as NativeShaderProgram; VertexElement[] elements = vertexDeclaration.Elements; for (int elementIndex = 0; elementIndex < elements.Length; elementIndex++) { int fieldIndex = nativeProgram.SelectField(ref elements[elementIndex]); if (fieldIndex == -1) { continue; } VertexAttribPointerType attribType; switch (elements[elementIndex].Type) { default: case VertexElementType.Float: attribType = VertexAttribPointerType.Float; break; case VertexElementType.Byte: attribType = VertexAttribPointerType.UnsignedByte; break; } int fieldLocation = nativeProgram.FieldLocations[fieldIndex]; GL.EnableVertexAttribArray(fieldLocation); GL.VertexAttribPointer( fieldLocation, elements[elementIndex].Count, attribType, true, vertexDeclaration.Size, elements[elementIndex].Offset); } }
private void FinishMaterial(BatchInfo material) { DrawTechnique tech = material.Technique.Res; this.SetupBlendType(BlendMode.Reset); NativeShaderProgram.Bind(null as NativeShaderProgram); NativeTexture.ResetBinding(); }
private void FinishMaterial(BatchInfo material) { DrawTechnique tech = material.Technique.Res; this.FinishBlendState(); NativeShaderProgram.Bind(null); NativeTexture.ResetBinding(this.sharedSamplerBindings); }
/// <summary> /// Applies the specified parameter values to all currently active shaders. /// </summary> /// <param name="sharedParams"></param> /// <seealso cref="RetrieveActiveShaders"/> private void SetupSharedParameters(ShaderParameterCollection sharedParams) { this.sharedSamplerBindings = 0; this.sharedShaderParameters.Clear(); if (sharedParams == null) { return; } foreach (NativeShaderProgram shader in this.activeShaders) { NativeShaderProgram.Bind(shader); ShaderFieldInfo[] varInfo = shader.Fields; int[] locations = shader.FieldLocations; // Setup shared sampler bindings and uniform data for (int i = 0; i < varInfo.Length; i++) { ShaderFieldInfo field = varInfo[i]; int location = locations[i]; if (field.Scope == ShaderFieldScope.Attribute) { continue; } if (field.Type == ShaderFieldType.Sampler2D) { ContentRef <Texture> texRef; if (!sharedParams.TryGetInternal(field.Name, out texRef)) { continue; } NativeTexture.Bind(texRef, this.sharedSamplerBindings); GL.Uniform1(location, this.sharedSamplerBindings); this.sharedSamplerBindings++; } else { float[] data; if (!sharedParams.TryGetInternal(field.Name, out data)) { continue; } NativeShaderProgram.SetUniform(field, location, data); } this.sharedShaderParameters.Add(field.Name); } } NativeShaderProgram.Bind(null); }
public static void Bind(NativeShaderProgram prog) { if (curBound == prog) return; if (prog == null) { GL.UseProgram(0); curBound = null; } else { GL.UseProgram(prog.Handle); curBound = prog; } }
public static void Bind(NativeShaderProgram prog) { if (curBound == prog) { return; } if (prog == null) { GL.UseProgram(0); curBound = null; } else { GL.UseProgram(prog.Handle); curBound = prog; } }
private void FinishVertexFormat(BatchInfo material, VertexDeclaration vertexDeclaration) { DrawTechnique technique = material.Technique.Res ?? DrawTechnique.Solid.Res; NativeShaderProgram nativeProgram = (technique.NativeShader ?? DrawTechnique.Solid.Res.NativeShader) as NativeShaderProgram; VertexElement[] elements = vertexDeclaration.Elements; for (int elementIndex = 0; elementIndex < elements.Length; elementIndex++) { int fieldIndex = nativeProgram.SelectField(ref elements[elementIndex]); if (fieldIndex == -1) { break; } int fieldLocation = nativeProgram.FieldLocations[fieldIndex]; GL.DisableVertexAttribArray(fieldLocation); } }
private void SetupMaterial(BatchInfo material, BatchInfo lastMaterial) { if (material == lastMaterial) { return; } DrawTechnique tech = material.Technique.Res ?? DrawTechnique.Solid.Res; DrawTechnique lastTech = lastMaterial != null ? lastMaterial.Technique.Res : null; // Prepare Rendering if (tech.NeedsPreparation) { material = new BatchInfo(material); tech.PrepareRendering(this.currentDevice, material); } // Setup BlendType if (lastTech == null || tech.Blending != lastTech.Blending) { this.SetupBlendType(tech.Blending, this.currentDevice.DepthWrite); } // Bind Shader NativeShaderProgram shader = (tech.Shader.Res != null ? tech.Shader.Res.Native : null) as NativeShaderProgram; NativeShaderProgram.Bind(shader); // Setup shader data if (shader != null) { ShaderFieldInfo[] varInfo = shader.Fields; int[] locations = shader.FieldLocations; int[] builtinIndices = shader.BuiltinVariableIndex; // Setup sampler bindings automatically int curSamplerIndex = 0; if (material.Textures != null) { for (int i = 0; i < varInfo.Length; i++) { if (locations[i] == -1) { continue; } if (varInfo[i].Type != ShaderFieldType.Sampler2D) { continue; } // Bind Texture ContentRef <Texture> texRef = material.GetTexture(varInfo[i].Name); NativeTexture.Bind(texRef, curSamplerIndex); GL.Uniform1(locations[i], curSamplerIndex); curSamplerIndex++; } } NativeTexture.ResetBinding(curSamplerIndex); // Transfer uniform data from material to actual shader if (material.Uniforms != null) { for (int i = 0; i < varInfo.Length; i++) { if (locations[i] == -1) { continue; } float[] data = material.GetUniform(varInfo[i].Name); if (data == null) { continue; } NativeShaderProgram.SetUniform(ref varInfo[i], locations[i], data); } } // Specify builtin shader variables, if requested float[] fieldValue = null; for (int i = 0; i < builtinIndices.Length; i++) { if (BuiltinShaderFields.TryGetValue(this.currentDevice, builtinIndices[i], ref fieldValue)) { NativeShaderProgram.SetUniform(ref varInfo[i], locations[i], fieldValue); } } } // Setup fixed function data else { // Fixed function texture binding if (material.Textures != null) { int samplerIndex = 0; foreach (var pair in material.Textures) { NativeTexture.Bind(pair.Value, samplerIndex); samplerIndex++; } NativeTexture.ResetBinding(samplerIndex); } else { NativeTexture.ResetBinding(); } } }
private void FinishRenderBatch(IDrawBatch renderBatch) { DrawTechnique technique = renderBatch.Material.Technique.Res ?? DrawTechnique.Solid.Res; NativeShaderProgram program = (technique.Shader.Res != null ? technique.Shader.Res.Native : null) as NativeShaderProgram; VertexDeclaration vertexDeclaration = renderBatch.VertexDeclaration; VertexElement[] elements = vertexDeclaration.Elements; for (int elementIndex = 0; elementIndex < elements.Length; elementIndex++) { switch (elements[elementIndex].Role) { case VertexElementRole.Position: { GL.DisableClientState(ArrayCap.VertexArray); break; } case VertexElementRole.TexCoord: { GL.DisableClientState(ArrayCap.TextureCoordArray); break; } case VertexElementRole.Color: { GL.DisableClientState(ArrayCap.ColorArray); break; } default: { if (program != null) { ShaderFieldInfo[] varInfo = program.Fields; int[] locations = program.FieldLocations; int selectedVar = -1; for (int varIndex = 0; varIndex < varInfo.Length; varIndex++) { if (locations[varIndex] == -1) { continue; } if (!ShaderVarMatches( ref varInfo[varIndex], elements[elementIndex].Type, elements[elementIndex].Count)) { continue; } selectedVar = varIndex; break; } if (selectedVar == -1) { break; } GL.DisableVertexAttribArray(locations[selectedVar]); } break; } } } }
private void PrepareRenderBatch(IDrawBatch renderBatch) { DrawTechnique technique = renderBatch.Material.Technique.Res ?? DrawTechnique.Solid.Res; NativeShaderProgram program = (technique.Shader.Res != null ? technique.Shader.Res.Native : null) as NativeShaderProgram; VertexDeclaration vertexDeclaration = renderBatch.VertexDeclaration; VertexElement[] elements = vertexDeclaration.Elements; for (int elementIndex = 0; elementIndex < elements.Length; elementIndex++) { switch (elements[elementIndex].Role) { case VertexElementRole.Position: { GL.EnableClientState(ArrayCap.VertexArray); GL.VertexPointer( elements[elementIndex].Count, VertexPointerType.Float, vertexDeclaration.Size, elements[elementIndex].Offset); break; } case VertexElementRole.TexCoord: { GL.EnableClientState(ArrayCap.TextureCoordArray); GL.TexCoordPointer( elements[elementIndex].Count, TexCoordPointerType.Float, vertexDeclaration.Size, elements[elementIndex].Offset); break; } case VertexElementRole.Color: { ColorPointerType attribType; switch (elements[elementIndex].Type) { default: case VertexElementType.Float: attribType = ColorPointerType.Float; break; case VertexElementType.Byte: attribType = ColorPointerType.UnsignedByte; break; } GL.EnableClientState(ArrayCap.ColorArray); GL.ColorPointer( elements[elementIndex].Count, attribType, vertexDeclaration.Size, elements[elementIndex].Offset); break; } default: { if (program != null) { ShaderFieldInfo[] varInfo = program.Fields; int[] locations = program.FieldLocations; int selectedVar = -1; for (int varIndex = 0; varIndex < varInfo.Length; varIndex++) { if (locations[varIndex] == -1) { continue; } if (!ShaderVarMatches( ref varInfo[varIndex], elements[elementIndex].Type, elements[elementIndex].Count)) { continue; } selectedVar = varIndex; break; } if (selectedVar == -1) { break; } VertexAttribPointerType attribType; switch (elements[elementIndex].Type) { default: case VertexElementType.Float: attribType = VertexAttribPointerType.Float; break; case VertexElementType.Byte: attribType = VertexAttribPointerType.UnsignedByte; break; } GL.EnableVertexAttribArray(locations[selectedVar]); GL.VertexAttribPointer( locations[selectedVar], elements[elementIndex].Count, attribType, false, vertexDeclaration.Size, elements[elementIndex].Offset); } break; } } } }
private void SetupMaterial(BatchInfo material, BatchInfo lastMaterial) { DrawTechnique tech = material.Technique.Res ?? DrawTechnique.Solid.Res; DrawTechnique lastTech = lastMaterial != null ? lastMaterial.Technique.Res : null; // Setup BlendType if (lastTech == null || tech.Blending != lastTech.Blending) { this.SetupBlendState(tech.Blending); } // Bind Shader NativeShaderProgram nativeShader = tech.NativeShader as NativeShaderProgram; NativeShaderProgram.Bind(nativeShader); // Setup shader data ShaderFieldInfo[] varInfo = nativeShader.Fields; int[] locations = nativeShader.FieldLocations; // Setup sampler bindings and uniform data int curSamplerIndex = this.sharedSamplerBindings; for (int i = 0; i < varInfo.Length; i++) { ShaderFieldInfo field = varInfo[i]; int location = locations[i]; if (field.Scope == ShaderFieldScope.Attribute) { continue; } if (this.sharedShaderParameters.Contains(field.Name)) { continue; } if (field.Type == ShaderFieldType.Sampler2D) { ContentRef <Texture> texRef = material.GetInternalTexture(field.Name); if (texRef == null) { this.internalShaderState.TryGetInternal(field.Name, out texRef); } NativeTexture.Bind(texRef, curSamplerIndex); GL.Uniform1(location, curSamplerIndex); curSamplerIndex++; } else { float[] data = material.GetInternalData(field.Name); if (data == null && !this.internalShaderState.TryGetInternal(field.Name, out data)) { continue; } NativeShaderProgram.SetUniform(field, location, data); } } NativeTexture.ResetBinding(curSamplerIndex); }