internal void Draw(GameObject g, ref Matrix4 viewProjection, HelperFrustum frustum, float zNear, float zFar, bool isSun) { if (g == null || !g.HasModel) { return; } bool isInsideFrustum = frustum.SphereVsFrustum(g.GetCenterPointForAllHitboxes(), g.GetMaxDiameter() / 2); GL.Uniform3(KWEngine.RendererShadow.GetUniformHandleNearFarSun(), zNear, zFar, isSun ? 1f : 0f); lock (g) { int index = -1; foreach (string meshName in g.Model.Meshes.Keys) { index++; GeoMesh mesh = g.Model.Meshes[meshName]; bool useMeshTransform = mesh.BoneNames.Count == 0 || !(g.AnimationID >= 0 && g.Model.Animations != null && g.Model.Animations.Count > 0); if (mesh.Material.Opacity <= 0 || !isInsideFrustum) { continue; } if (g.IsShadowCaster && g.Opacity > 0f) { if (useMeshTransform == false) { GL.Uniform1(mUniform_UseAnimations, 1); for (int i = 0; i < g.BoneTranslationMatrices[meshName].Length; i++) { Matrix4 tmp = g.BoneTranslationMatrices[meshName][i]; GL.UniformMatrix4(mUniform_BoneTransforms + i, false, ref tmp); } } else { GL.Uniform1(mUniform_UseAnimations, 0); } Matrix4.Mult(ref g.ModelMatrixForRenderPass[g.Model.IsKWCube6 ? 0 : index], ref viewProjection, out _modelViewProjection); GL.UniformMatrix4(mUniform_MVP, false, ref _modelViewProjection); GL.BindVertexArray(mesh.VAO); GL.BindBuffer(BufferTarget.ElementArrayBuffer, mesh.VBOIndex); GL.DrawElements(mesh.Primitive, mesh.IndexCount, DrawElementsType.UnsignedInt, 0); GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); GL.BindVertexArray(0); } } } }
internal void Draw(GameObject g, ref Matrix4 viewProjection, HelperFrustum frustum, float zNear, float zFar, bool isSun) { if (g == null || !g.HasModel) { return; } bool isInsideFrustum = frustum.SphereVsFrustum(g.GetCenterPointForAllHitboxes(), g.GetMaxDiameter() / 2); GL.Uniform3(KWEngine.RendererShadowQuad.GetUniformHandleNearFarSun(), zNear, zFar, isSun ? 1f : 0f); lock (g) { int index = -1; foreach (string meshName in g.Model.Meshes.Keys) { index++; GeoMesh mesh = g.Model.Meshes[meshName]; if (mesh.Material.Opacity <= 0 || !isInsideFrustum) { continue; } if (g.IsShadowCaster && g.Opacity > 0f) { int texId = g._materials[index].TextureAlbedo.OpenGLID; GL.ActiveTexture(TextureUnit.Texture0); if (texId > 0) { GL.BindTexture(TextureTarget.Texture2D, texId); GL.Uniform1(mUniform_Texture, 0); } else { GL.BindTexture(TextureTarget.Texture2D, KWEngine.TextureWhite); GL.Uniform1(mUniform_Texture, 0); } GL.Uniform4(mUniform_TextureTransform, mesh.Material.TextureAlbedo.UVTransform.X == 0 ? 1 : mesh.Material.TextureAlbedo.UVTransform.X, mesh.Material.TextureAlbedo.UVTransform.Y == 0 ? 1 : mesh.Material.TextureAlbedo.UVTransform.Y, g.mTextureOffset.X, g.mTextureOffset.Y); Matrix4.Mult(ref g.ModelMatrixForRenderPass[g.Model.IsKWCube6 ? 0 : index], ref viewProjection, out _modelViewProjection); GL.UniformMatrix4(mUniform_MVP, false, ref _modelViewProjection); GL.BindVertexArray(mesh.VAO); GL.BindBuffer(BufferTarget.ElementArrayBuffer, mesh.VBOIndex); GL.DrawElements(mesh.Primitive, mesh.IndexCount, DrawElementsType.UnsignedInt, 0); GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); GL.BindVertexArray(0); } } } }
internal override void Draw(GameObject g, ref Matrix4 viewProjection, HelperFrustum frustum) { throw new NotImplementedException(); }
internal override void Draw(GameObject g, ref Matrix4 viewProjection, ref Matrix4 viewProjectionShadowBiased, ref Matrix4 viewProjectionShadowBiased2, HelperFrustum frustum, ref float[] lightColors, ref float[] lightTargets, ref float[] lightPositions, int lightCount, ref int lightShadow) { if (g == null || !g.HasModel || g.CurrentWorld == null || g.Opacity <= 0) { return; } g.IsInsideScreenSpace = frustum.SphereVsFrustum(g.GetCenterPointForAllHitboxes(), g.GetMaxDiameter() / 2); if (!g.IsInsideScreenSpace) { return; } GL.UseProgram(mProgramId); lock (g) { int index = 0; foreach (string meshName in g.Model.Meshes.Keys) { if (g._cubeModel is GeoModelCube6) { index = 0; } Matrix4.Mult(ref g.ModelMatrixForRenderPass[index], ref viewProjection, out _modelViewProjection); GL.UniformMatrix4(mUniform_MVP, false, ref _modelViewProjection); index++; GL.Disable(EnableCap.Blend); GeoMesh mesh = g.Model.Meshes[meshName]; if (mesh.Material.Opacity <= 0) { continue; } if (g._cubeModel != null) { UploadMaterialForKWCube(g._cubeModel, mesh, g); } else { GL.Uniform3(mUniform_BaseColor, mesh.Material.ColorDiffuse.X, mesh.Material.ColorDiffuse.Y, mesh.Material.ColorDiffuse.Z); } HelperGL.CheckGLErrors(); GL.BindVertexArray(mesh.VAO); GL.BindBuffer(BufferTarget.ElementArrayBuffer, mesh.VBOIndex); GL.DrawElements(mesh.Primitive, mesh.IndexCount, DrawElementsType.UnsignedInt, 0); HelperGL.CheckGLErrors(); GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); GL.BindVertexArray(0); } } GL.UseProgram(0); }
internal override void Draw(GameObject g, ref Matrix4 viewProjection, ref Matrix4 viewProjectionShadow, ref Matrix4 viewProjectionShadow2, HelperFrustum frustum, ref float[] lightColors, ref float[] lightTargets, ref float[] lightPositions, int lightCount, ref int lightShadow) { throw new NotImplementedException(); }
internal override void Draw(GameObject g, ref Matrix4 viewProjection, ref Matrix4 viewProjectionShadowBiased, ref Matrix4 viewProjectionShadowBiased2, HelperFrustum frustum, ref float[] lightColors, ref float[] lightTargets, ref float[] lightPositions, int lightCount, ref int lightShadow) { if (g == null || !g.HasModel || g.CurrentWorld == null || g.Opacity <= 0) { return; } g.IsInsideScreenSpace = frustum.SphereVsFrustum(g.GetCenterPointForAllHitboxes(), g.GetMaxDiameter() / 2); if (!g.IsInsideScreenSpace) { return; } GL.UseProgram(mProgramId); GL.Disable(EnableCap.Blend); lock (g) { GL.Uniform1(mUniform_BiasCoefficient, KWEngine.ShadowMapCoefficient); GL.Uniform4(mUniform_Glow, g.Glow.X, g.Glow.Y, g.Glow.Z, g.Glow.W); GL.Uniform3(mUniform_TintColor, g.Color.X, g.Color.Y, g.Color.Z); // How many lights are there? GL.Uniform1(mUniform_LightCount, lightCount); GL.Uniform4(mUniform_LightsColors, KWEngine.MAX_LIGHTS, lightColors); GL.Uniform4(mUniform_LightsTargets, KWEngine.MAX_LIGHTS, lightTargets); GL.Uniform4(mUniform_LightsPositions, KWEngine.MAX_LIGHTS, lightPositions); // Sun GL.Uniform4(mUniform_SunIntensity, g.CurrentWorld.GetSunColor()); GL.Uniform3(mUniform_SunPosition, g.CurrentWorld.GetSunPosition().X, g.CurrentWorld.GetSunPosition().Y, g.CurrentWorld.GetSunPosition().Z); Vector3 sunDirection = g.CurrentWorld.GetSunPosition() - g.CurrentWorld.GetSunTarget(); sunDirection.NormalizeFast(); GL.Uniform3(mUniform_SunDirection, ref sunDirection); GL.Uniform1(mUniform_SunAmbient, g.CurrentWorld.SunAmbientFactor); GL.Uniform1(mUniform_SunAffection, g.IsAffectedBySun ? 1 : 0); GL.Uniform1(mUniform_LightAffection, g.IsAffectedByLight ? 1 : 0); // Camera if (!CurrentWorld.IsFirstPersonMode) { GL.Uniform3(mUniform_uCameraPos, g.CurrentWorld.GetCameraPosition().X, g.CurrentWorld.GetCameraPosition().Y, g.CurrentWorld.GetCameraPosition().Z); GL.Uniform3(mUniform_uCameraDirection, g.CurrentWorld.GetCameraLookAtVector()); } else { GL.Uniform3(mUniform_uCameraPos, g.CurrentWorld.GetFirstPersonObject().Position.X, g.CurrentWorld.GetFirstPersonObject().Position.Y + g.CurrentWorld.GetFirstPersonObject().FPSEyeOffset, g.CurrentWorld.GetFirstPersonObject().Position.Z); GL.Uniform3(mUniform_uCameraDirection, HelperCamera.GetLookAtVector()); } // Upload depth texture (shadow mapping) GL.ActiveTexture(TextureUnit.Texture3); GL.BindTexture(TextureTarget.Texture2D, GLWindow.CurrentWindow.TextureShadowMap); GL.Uniform1(mUniform_TextureShadowMap, 3); try { Matrix4.Mult(ref g.ModelMatrixForRenderPass[0], ref viewProjection, out _modelViewProjection); Matrix4.Transpose(ref g.ModelMatrixForRenderPass[0], out _normalMatrix); Matrix4.Invert(ref _normalMatrix, out _normalMatrix); } catch (Exception) { _normalMatrix = g.ModelMatrixForRenderPass[0]; } GL.UniformMatrix4(mUniform_ModelMatrix, false, ref g.ModelMatrixForRenderPass[0]); GL.UniformMatrix4(mUniform_NormalMatrix, false, ref _normalMatrix); GL.UniformMatrix4(mUniform_MVP, false, ref _modelViewProjection); if (lightShadow >= 0) { Matrix4 modelViewProjectionMatrixBiased2 = g.ModelMatrixForRenderPass[0] * viewProjectionShadowBiased2; GL.ActiveTexture(TextureUnit.Texture5); GL.BindTexture(TextureTarget.Texture2D, GLWindow.CurrentWindow.TextureShadowMap2); GL.Uniform1(mUniform_TextureShadowMap2, 5); GL.Uniform1(mUniform_ShadowLightPosition, lightShadow); GL.UniformMatrix4(mUniform_MVPShadowMap2, false, ref modelViewProjectionMatrixBiased2); GL.Uniform1(mUniform_BiasCoefficient2, CurrentWorld.GetLightObjects().ElementAt(lightShadow).ShadowMapBiasCoefficient); } else { GL.Uniform1(mUniform_ShadowLightPosition, -1); GL.ActiveTexture(TextureUnit.Texture5); GL.BindTexture(TextureTarget.Texture2D, GLWindow.CurrentWindow.TextureShadowMap2); GL.Uniform1(mUniform_TextureShadowMap2, 5); } foreach (string meshName in g.Model.Meshes.Keys) { GeoMesh mesh = g.Model.Meshes[meshName]; GL.Uniform1(mUniform_SpecularPower, mesh.Material.SpecularPower); GL.Uniform1(mUniform_SpecularArea, mesh.Material.SpecularArea); // Shadow mapping Matrix4 modelViewProjectionMatrixBiased = g.ModelMatrixForRenderPass[0] * viewProjectionShadowBiased; GL.UniformMatrix4(mUniform_MVPShadowMap, false, ref modelViewProjectionMatrixBiased); GL.Uniform2(mUniform_TextureTransform, mesh.Terrain.mTexX, mesh.Terrain.mTexY); int texId = mesh.Material.TextureDiffuse.OpenGLID; if (texId > 0) { GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, texId); GL.Uniform1(mUniform_Texture, 0); GL.Uniform1(mUniform_TextureUse, 1); } else { GL.Uniform1(mUniform_TextureUse, 0); } texId = mesh.Material.TextureNormal.OpenGLID; if (texId > 0) { GL.ActiveTexture(TextureUnit.Texture1); GL.BindTexture(TextureTarget.Texture2D, texId); GL.Uniform1(mUniform_TextureNormalMap, 1); GL.Uniform1(mUniform_TextureUseNormalMap, 1); } else { GL.Uniform1(mUniform_TextureUseNormalMap, 0); } texId = mesh.Material.TextureSpecular.OpenGLID; if (texId > 0) { GL.ActiveTexture(TextureUnit.Texture2); GL.BindTexture(TextureTarget.Texture2D, texId); GL.Uniform1(mUniform_TextureSpecularMap, 2); GL.Uniform1(mUniform_TextureUseSpecularMap, 1); } else { GL.Uniform1(mUniform_TextureUseSpecularMap, 0); } // Blendmapping: if (mesh.Terrain._texBlend > 0 && mesh.Terrain._texBlend != KWEngine.TextureBlack) { GL.ActiveTexture(TextureUnit.Texture10); GL.BindTexture(TextureTarget.Texture2D, mesh.Terrain._texBlend); GL.Uniform1(mUniform_TextureBlend, 10); GL.ActiveTexture(TextureUnit.Texture11); GL.BindTexture(TextureTarget.Texture2D, mesh.Terrain._texR); GL.Uniform1(mUniform_TextureRed, 11); if (mesh.Terrain._texG > 0 && mesh.Terrain._texG != KWEngine.TextureAlpha) { GL.ActiveTexture(TextureUnit.Texture12); GL.BindTexture(TextureTarget.Texture2D, mesh.Terrain._texG); GL.Uniform1(mUniform_TextureGreen, 12); } if (mesh.Terrain._texB > 0 && mesh.Terrain._texB != KWEngine.TextureAlpha) { GL.ActiveTexture(TextureUnit.Texture13); GL.BindTexture(TextureTarget.Texture2D, mesh.Terrain._texB); GL.Uniform1(mUniform_TextureBlue, 13); } GL.Uniform1(mUniform_UseBlend, 1); } else { GL.Uniform1(mUniform_UseBlend, 0); } GL.BindVertexArray(mesh.VAO); GL.BindBuffer(BufferTarget.ElementArrayBuffer, mesh.VBOIndex); GL.DrawElements(mesh.Primitive, mesh.IndexCount, DrawElementsType.UnsignedInt, 0); GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); GL.BindTexture(TextureTarget.Texture2D, 0); GL.BindVertexArray(0); } } GL.UseProgram(0); }
internal override void Draw(GameObject g, ref Matrix4 viewProjection, ref Matrix4 viewProjectionShadowBiased, ref Matrix4 viewProjectionShadowBiased2, HelperFrustum frustum, ref float[] lightColors, ref float[] lightTargets, ref float[] lightPositions, int lightCount, ref int lightShadow) { throw new Exception("not implemented yet."); /* * if (g == null || !g.HasModel || g.CurrentWorld == null || g.Opacity <= 0) * return; * * g.IsInsideScreenSpace = frustum.SphereVsFrustum(g.GetCenterPointForAllHitboxes(), g.GetMaxDiameter() / 2); * if (!g.IsInsideScreenSpace) * return; * * GL.UseProgram(mProgramId); * * lock (g) * { * GL.Uniform1(mUniform_BiasCoefficient, KWEngine.ShadowMapCoefficient); * GL.Uniform4(mUniform_Glow, g.Glow.X, g.Glow.Y, g.Glow.Z, g.Glow.W); * GL.Uniform3(mUniform_TintColor, g.Color.X, g.Color.Y, g.Color.Z); * * // How many lights are there? * GL.Uniform1(mUniform_LightCount, lightCount); * GL.Uniform4(mUniform_LightsColors, KWEngine.MAX_LIGHTS, lightColors); * GL.Uniform4(mUniform_LightsTargets, KWEngine.MAX_LIGHTS, lightTargets); * GL.Uniform4(mUniform_LightsPositions, KWEngine.MAX_LIGHTS, lightPositions); * * // Sun * GL.Uniform4(mUniform_SunIntensity, g.CurrentWorld.GetSunColor()); * GL.Uniform3(mUniform_SunPosition, g.CurrentWorld.GetSunPosition().X, g.CurrentWorld.GetSunPosition().Y, g.CurrentWorld.GetSunPosition().Z); * Vector3 sunDirection = g.CurrentWorld.GetSunPosition() - g.CurrentWorld.GetSunTarget(); * sunDirection.NormalizeFast(); * GL.Uniform3(mUniform_SunDirection, ref sunDirection); * GL.Uniform1(mUniform_SunAmbient, g.CurrentWorld.SunAmbientFactor); * * GL.Uniform1(mUniform_SunAffection, g.IsAffectedBySun ? 1 : 0); * GL.Uniform1(mUniform_LightAffection, g.IsAffectedByLight ? 1 : 0); * * // Camera * if (!CurrentWorld.IsFirstPersonMode) * { * GL.Uniform3(mUniform_uCameraPos, g.CurrentWorld.GetCameraPosition().X, g.CurrentWorld.GetCameraPosition().Y, g.CurrentWorld.GetCameraPosition().Z); * GL.Uniform3(mUniform_uCameraDirection, g.CurrentWorld.GetCameraLookAtVector()); * } * else * { * GL.Uniform3(mUniform_uCameraPos, g.CurrentWorld.GetFirstPersonObject().Position.X, g.CurrentWorld.GetFirstPersonObject().Position.Y + g.CurrentWorld.GetFirstPersonObject().FPSEyeOffset, g.CurrentWorld.GetFirstPersonObject().Position.Z); * GL.Uniform3(mUniform_uCameraDirection, HelperCamera.GetLookAtVector()); * } * * // Upload depth texture (shadow mapping) * GL.ActiveTexture(TextureUnit.Texture3); * GL.BindTexture(TextureTarget.Texture2D, GLWindow.CurrentWindow.TextureShadowMap); * GL.Uniform1(mUniform_TextureShadowMap, 3); * * * foreach (string meshName in g.Model.Meshes.Keys) * { * GL.Disable(EnableCap.Blend); * GeoMesh mesh = g.Model.Meshes[meshName]; * if(mesh.Material.Opacity <= 0) * { * continue; * } * * if (mesh.Material.Opacity < 1 || g.Opacity < 1) * { * GL.Enable(EnableCap.Blend); * } * if (g.Opacity < mesh.Material.Opacity) * GL.Uniform1(mUniform_Opacity, g.Opacity); * else * GL.Uniform1(mUniform_Opacity, mesh.Material.Opacity); * * * Dictionary<GameObject.Override, object> overrides = null; * if (g._overrides.ContainsKey(mesh.Name)) * { * overrides = g._overrides[mesh.Name]; * } * * if (g.AnimationID >= 0 && g.Model.Animations != null && g.Model.Animations.Count > 0) * { * GL.Uniform1(mUniform_UseAnimations, 1); * lock (g.BoneTranslationMatrices) * { * for (int i = 0; i < g.BoneTranslationMatrices[meshName].Length; i++) * { * Matrix4 tmp = g.BoneTranslationMatrices[meshName][i]; * GL.UniformMatrix4(mUniform_BoneTransforms + i, false, ref tmp); * } * } * } * else * { * GL.Uniform1(mUniform_UseAnimations, 0); * } * * if (g._cubeModel != null) * { * GL.Uniform1(mUniform_SpecularPower, g._cubeModel.SpecularPower); * GL.Uniform1(mUniform_SpecularArea, g._cubeModel.SpecularArea); * } * else * { * if (overrides == null || overrides.Count == 0) * GL.Uniform1(mUniform_SpecularPower, mesh.Material.SpecularPower); * else * { * bool found = overrides.TryGetValue(GameObject.Override.SpecularPower, out object value); * if (found) * GL.Uniform1(mUniform_SpecularPower, (float)value); * else * GL.Uniform1(mUniform_SpecularPower, mesh.Material.SpecularPower); * * * } * * if (overrides == null || overrides.Count == 0) * GL.Uniform1(mUniform_SpecularArea, mesh.Material.SpecularArea); * else * { * bool found = overrides.TryGetValue(GameObject.Override.SpecularArea, out object value); * if (found) * GL.Uniform1(mUniform_SpecularArea, (float)value); * else * GL.Uniform1(mUniform_SpecularArea, mesh.Material.SpecularArea); * } * } * * Matrix4.Mult(ref g.ModelMatrixForRenderPass, ref viewProjection, out _modelViewProjection); * Matrix4.Transpose(ref g.ModelMatrixForRenderPass, out _normalMatrix); * Matrix4.Invert(ref _normalMatrix, out _normalMatrix); * * GL.UniformMatrix4(mUniform_ModelMatrix, false, ref g.ModelMatrixForRenderPass); * GL.UniformMatrix4(mUniform_NormalMatrix, false, ref _normalMatrix); * GL.UniformMatrix4(mUniform_MVP, false, ref _modelViewProjection); * * // Shadow mapping * Matrix4 modelViewProjectionMatrixBiased = g.ModelMatrixForRenderPass * viewProjectionShadowBiased; * GL.UniformMatrix4(mUniform_MVPShadowMap, false, ref modelViewProjectionMatrixBiased); * * * if (g._cubeModel != null) * { * UploadMaterialForKWCube(g._cubeModel, mesh, g); * GL.Uniform1(mUniform_TextureUseLightMap, 0); * } * else * { * if (mesh.Material.TextureLight.OpenGLID > 0) * { * GL.ActiveTexture(TextureUnit.Texture8); * GL.BindTexture(TextureTarget.Texture2D, mesh.Material.TextureLight.OpenGLID); * GL.Uniform1(mUniform_TextureLightMap, 8); * GL.Uniform1(mUniform_TextureUseLightMap, 1); * } * else * { * GL.Uniform1(mUniform_TextureUseLightMap, 0); * } * * * * * bool found = false; * object overrideValue = null; * if (overrides != null && overrides.Count > 0) * found = overrides.TryGetValue(GameObject.Override.TextureTransform, out overrideValue); * * if (found) * { * Vector2 uvTransform = (Vector2)overrideValue; * GL.Uniform2(mUniform_TextureTransform, uvTransform.X, uvTransform.Y); * } * else * GL.Uniform2(mUniform_TextureTransform, mesh.Material.TextureDiffuse.UVTransform.X, mesh.Material.TextureDiffuse.UVTransform.Y); * * // Diffuse texture: * overrideValue = null; * found = false; * int texId = -1; * if (overrides != null && overrides.Count > 0) * { * found = overrides.TryGetValue(GameObject.Override.TextureDiffuse, out overrideValue); * } * if (found) * texId = ((GeoTexture)overrideValue).OpenGLID; * else * texId = mesh.Material.TextureDiffuse.OpenGLID; * * if (texId > 0) * { * GL.ActiveTexture(TextureUnit.Texture0); * GL.BindTexture(TextureTarget.Texture2D, texId); * GL.Uniform1(mUniform_Texture, 0); * GL.Uniform1(mUniform_TextureUse, 1); * GL.Uniform3(mUniform_BaseColor, 1f, 1f, 1f); * } * else * { * GL.Uniform1(mUniform_TextureUse, 0); * GL.Uniform3(mUniform_BaseColor, mesh.Material.ColorDiffuse.X, mesh.Material.ColorDiffuse.Y, mesh.Material.ColorDiffuse.Z); * } * * overrideValue = null; * found = false; * texId = -1; * if (overrides != null && overrides.Count > 0) * { * found = overrides.TryGetValue(GameObject.Override.TextureNormal, out overrideValue); * } * if (found) * texId = ((GeoTexture)overrideValue).OpenGLID; * else * texId = mesh.Material.TextureNormal.OpenGLID; * if (texId > 0) * { * GL.ActiveTexture(TextureUnit.Texture1); * GL.BindTexture(TextureTarget.Texture2D, texId); * GL.Uniform1(mUniform_TextureNormalMap, 1); * GL.Uniform1(mUniform_TextureUseNormalMap, 1); * } * else * { * GL.Uniform1(mUniform_TextureUseNormalMap, 0); * } * * overrideValue = null; * found = false; * texId = -1; * if (overrides != null) * { * found = overrides.TryGetValue(GameObject.Override.TextureSpecular, out overrideValue); * } * if (found) * texId = ((GeoTexture)overrideValue).OpenGLID; * else * texId = mesh.Material.TextureSpecular.OpenGLID; * if (texId > 0) * { * GL.ActiveTexture(TextureUnit.Texture2); * GL.BindTexture(TextureTarget.Texture2D, texId); * GL.Uniform1(mUniform_TextureSpecularMap, 2); * GL.Uniform1(mUniform_TextureUseSpecularMap, 1); * if (!found && mesh.Material.TextureSpecularIsRoughness) * GL.Uniform1(mUniform_TextureSpecularIsRoughness, mesh.Material.TextureSpecularIsRoughness ? 1 : 0); * else * GL.Uniform1(mUniform_TextureSpecularIsRoughness, 0); * } * else * { * GL.Uniform1(mUniform_TextureUseSpecularMap, 0); * GL.Uniform1(mUniform_TextureSpecularIsRoughness, 0); * } * * * if (mesh.Material.TextureEmissive.OpenGLID > 0) * { * GL.ActiveTexture(TextureUnit.Texture4); * GL.BindTexture(TextureTarget.Texture2D, mesh.Material.TextureEmissive.OpenGLID); * GL.Uniform1(mUniform_TextureSpecularMap, 4); * GL.Uniform1(mUniform_TextureUseEmissiveMap, 1); * } * else * { * GL.Uniform1(mUniform_TextureUseEmissiveMap, 0); * } * * if (g.ColorEmissive.W > 0) * { * GL.Uniform4(mUniform_EmissiveColor, g.ColorEmissive); * } * else * { * GL.Uniform4(mUniform_EmissiveColor, mesh.Material.ColorEmissive); * } * } * * GL.BindVertexArray(mesh.VAO); * GL.BindBuffer(BufferTarget.ElementArrayBuffer, mesh.VBOIndex); * GL.DrawElements(mesh.Primitive, mesh.IndexCount, DrawElementsType.UnsignedInt, 0); * GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); * * GL.BindVertexArray(0); * * } * * } * GL.UseProgram(0); */ }
internal override void Draw(GameObject g, ref Matrix4 viewProjection, ref Matrix4 viewProjectionShadowBiased, ref Matrix4 viewProjectionShadowBiased2, HelperFrustum frustum, ref float[] lightColors, ref float[] lightTargets, ref float[] lightPositions, int lightCount, ref int lightShadow) { if (g == null || !g.HasModel || g.CurrentWorld == null || g.Opacity <= 0) { return; } g.IsInsideScreenSpace = frustum.VolumeVsFrustum(g.GetCenterPointForAllHitboxes(), g.GetMaxDimensions().X, g.GetMaxDimensions().Y, g.GetMaxDimensions().Z); if (!g.IsInsideScreenSpace) { return; } GL.UseProgram(mProgramId); lock (g) { GL.Uniform1(mUniform_BiasCoefficient, KWEngine.ShadowMapCoefficient); GL.Uniform4(mUniform_Glow, g.Glow); GL.Uniform4(mUniform_Outline, g.ColorOutline); GL.Uniform3(mUniform_TintColor, g.Color); // How many lights are there? GL.Uniform1(mUniform_LightCount, lightCount); GL.Uniform4(mUniform_LightsColors, KWEngine.MAX_LIGHTS, lightColors); GL.Uniform4(mUniform_LightsTargets, KWEngine.MAX_LIGHTS, lightTargets); GL.Uniform4(mUniform_LightsPositions, KWEngine.MAX_LIGHTS, lightPositions); // Sun GL.Uniform4(mUniform_SunIntensity, g.CurrentWorld.GetSunColor()); GL.Uniform3(mUniform_SunPosition, g.CurrentWorld.GetSunPosition().X, g.CurrentWorld.GetSunPosition().Y, g.CurrentWorld.GetSunPosition().Z); Vector3 sunDirection = g.CurrentWorld.GetSunPosition() - g.CurrentWorld.GetSunTarget(); sunDirection.NormalizeFast(); GL.Uniform3(mUniform_SunDirection, ref sunDirection); GL.Uniform1(mUniform_SunAmbient, g.CurrentWorld.SunAmbientFactor); GL.Uniform1(mUniform_SunAffection, g.IsAffectedBySun ? 1 : 0); GL.Uniform1(mUniform_LightAffection, g.IsAffectedByLight ? 1 : 0); // Camera if (!CurrentWorld.IsFirstPersonMode) { GL.Uniform3(mUniform_uCameraPos, g.CurrentWorld.GetCameraPosition().X, g.CurrentWorld.GetCameraPosition().Y, g.CurrentWorld.GetCameraPosition().Z); GL.Uniform3(mUniform_uCameraDirection, g.CurrentWorld.GetCameraLookAtVector()); } else { GL.Uniform3(mUniform_uCameraPos, g.CurrentWorld.GetFirstPersonObject().Position.X, g.CurrentWorld.GetFirstPersonObject().Position.Y + g.CurrentWorld.GetFirstPersonObject().FPSEyeOffset, g.CurrentWorld.GetFirstPersonObject().Position.Z); GL.Uniform3(mUniform_uCameraDirection, HelperCamera.GetLookAtVector()); } // Upload depth texture (shadow mapping) GL.ActiveTexture(TextureUnit.Texture3); GL.BindTexture(TextureTarget.Texture2D, GLWindow.CurrentWindow.TextureShadowMap); GL.Uniform1(mUniform_TextureShadowMap, 3); if (lightShadow >= 0) { GL.ActiveTexture(TextureUnit.Texture5); GL.BindTexture(TextureTarget.Texture2D, GLWindow.CurrentWindow.TextureShadowMap2); GL.Uniform1(mUniform_TextureShadowMap2, 5); GL.Uniform1(mUniform_ShadowLightPosition, lightShadow); GL.Uniform1(mUniform_BiasCoefficient2, CurrentWorld.GetLightObjects().ElementAt(lightShadow).ShadowMapBiasCoefficient); } else { GL.ActiveTexture(TextureUnit.Texture5); GL.BindTexture(TextureTarget.Texture2D, GLWindow.CurrentWindow.TextureShadowMap2); GL.Uniform1(mUniform_TextureShadowMap2, 5); GL.Uniform1(mUniform_ShadowLightPosition, -1); } int index = 0; foreach (string meshName in g.Model.Meshes.Keys) { if (g._cubeModel is GeoModelCube6) { index = 0; } // Matrices: try { Matrix4.Mult(ref g.ModelMatrixForRenderPass[index], ref viewProjection, out _modelViewProjection); Matrix4.Transpose(ref g.ModelMatrixForRenderPass[index], out _normalMatrix); Matrix4.Invert(ref _normalMatrix, out _normalMatrix); } catch (Exception) { continue; } GL.UniformMatrix4(mUniform_ModelMatrix, false, ref g.ModelMatrixForRenderPass[index]); GL.UniformMatrix4(mUniform_NormalMatrix, false, ref _normalMatrix); GL.UniformMatrix4(mUniform_MVP, false, ref _modelViewProjection); // Shadow mapping Matrix4 modelViewProjectionMatrixBiased = g.ModelMatrixForRenderPass[index] * viewProjectionShadowBiased; GL.UniformMatrix4(mUniform_MVPShadowMap, false, ref modelViewProjectionMatrixBiased); if (lightShadow >= 0) { Matrix4 modelViewProjectionMatrixBiased2 = g.ModelMatrixForRenderPass[index] * viewProjectionShadowBiased2; GL.UniformMatrix4(mUniform_MVPShadowMap2, false, ref modelViewProjectionMatrixBiased2); } index++; GL.Disable(EnableCap.Blend); GeoMesh mesh = g.Model.Meshes[meshName]; if (mesh.Material.Opacity <= 0) { continue; } if (mesh.Material.Opacity < 1 || g.Opacity < 1) { GL.Enable(EnableCap.Blend); } if (g.Opacity < mesh.Material.Opacity) { GL.Uniform1(mUniform_Opacity, g.Opacity); } else { GL.Uniform1(mUniform_Opacity, mesh.Material.Opacity); } Dictionary <GameObject.Override, object> overrides = null; if (g._overrides.ContainsKey(mesh.Name)) { overrides = g._overrides[mesh.Name]; } if (mesh.BoneNames.Count > 0 && g.AnimationID >= 0 && g.Model.Animations != null && g.Model.Animations.Count > 0) { GL.Uniform1(mUniform_UseAnimations, 1); for (int i = 0; i < g.BoneTranslationMatrices[meshName].Length; i++) { Matrix4 tmp = g.BoneTranslationMatrices[meshName][i]; GL.UniformMatrix4(mUniform_BoneTransforms + i, false, ref tmp); } } else { GL.Uniform1(mUniform_UseAnimations, 0); } if (g._cubeModel != null) { GL.Uniform1(mUniform_SpecularPower, g._cubeModel.SpecularPower); GL.Uniform1(mUniform_SpecularArea, g._cubeModel.SpecularArea); } else { if (overrides == null || overrides.Count == 0) { GL.Uniform1(mUniform_SpecularPower, mesh.Material.SpecularPower); } else { bool found = overrides.TryGetValue(GameObject.Override.SpecularPower, out object value); if (found) { GL.Uniform1(mUniform_SpecularPower, (float)value); } else { GL.Uniform1(mUniform_SpecularPower, mesh.Material.SpecularPower); } } if (overrides == null || overrides.Count == 0) { GL.Uniform1(mUniform_SpecularArea, mesh.Material.SpecularArea); } else { bool found = overrides.TryGetValue(GameObject.Override.SpecularArea, out object value); if (found) { GL.Uniform1(mUniform_SpecularArea, (float)value); } else { GL.Uniform1(mUniform_SpecularArea, mesh.Material.SpecularArea); } } } if (g._cubeModel != null) { UploadMaterialForKWCube(g._cubeModel, mesh, g); GL.Uniform1(mUniform_TextureUseLightMap, 0); } else { if (mesh.Material.TextureLight.OpenGLID > 0) { GL.ActiveTexture(TextureUnit.Texture8); GL.BindTexture(TextureTarget.Texture2D, mesh.Material.TextureLight.OpenGLID); GL.Uniform1(mUniform_TextureLightMap, 8); GL.Uniform1(mUniform_TextureUseLightMap, 1); } else { GL.Uniform1(mUniform_TextureUseLightMap, 0); } bool found = false; object overrideValue = null; if (overrides != null && overrides.Count > 0) { found = overrides.TryGetValue(GameObject.Override.TextureTransform, out overrideValue); } if (found) { Vector2 uvTransform = (Vector2)overrideValue; GL.Uniform2(mUniform_TextureTransform, uvTransform.X, uvTransform.Y); } else { GL.Uniform2(mUniform_TextureTransform, mesh.Material.TextureDiffuse.UVTransform.X, mesh.Material.TextureDiffuse.UVTransform.Y); } // Diffuse texture: overrideValue = null; found = false; int texId = -1; if (overrides != null && overrides.Count > 0) { found = overrides.TryGetValue(GameObject.Override.TextureDiffuse, out overrideValue); } if (found) { texId = ((GeoTexture)overrideValue).OpenGLID; } else { texId = mesh.Material.TextureDiffuse.OpenGLID; } if (texId > 0) { GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, texId); GL.Uniform1(mUniform_Texture, 0); GL.Uniform1(mUniform_TextureUse, 1); GL.Uniform3(mUniform_BaseColor, 1f, 1f, 1f); } else { GL.Uniform1(mUniform_TextureUse, 0); GL.Uniform3(mUniform_BaseColor, mesh.Material.ColorDiffuse.X, mesh.Material.ColorDiffuse.Y, mesh.Material.ColorDiffuse.Z); } overrideValue = null; found = false; texId = -1; if (overrides != null && overrides.Count > 0) { found = overrides.TryGetValue(GameObject.Override.TextureNormal, out overrideValue); } if (found) { texId = ((GeoTexture)overrideValue).OpenGLID; } else { texId = mesh.Material.TextureNormal.OpenGLID; } if (texId > 0) { GL.ActiveTexture(TextureUnit.Texture1); GL.BindTexture(TextureTarget.Texture2D, texId); GL.Uniform1(mUniform_TextureNormalMap, 1); GL.Uniform1(mUniform_TextureUseNormalMap, 1); } else { GL.Uniform1(mUniform_TextureUseNormalMap, 0); } overrideValue = null; found = false; texId = -1; if (overrides != null) { found = overrides.TryGetValue(GameObject.Override.TextureSpecular, out overrideValue); } if (found) { texId = ((GeoTexture)overrideValue).OpenGLID; } else { texId = mesh.Material.TextureSpecular.OpenGLID; } if (texId > 0) { GL.ActiveTexture(TextureUnit.Texture2); GL.BindTexture(TextureTarget.Texture2D, texId); GL.Uniform1(mUniform_TextureSpecularMap, 2); GL.Uniform1(mUniform_TextureUseSpecularMap, 1); if (!found && mesh.Material.TextureSpecularIsRoughness) { GL.Uniform1(mUniform_TextureSpecularIsRoughness, mesh.Material.TextureSpecularIsRoughness ? 1 : 0); } else { GL.Uniform1(mUniform_TextureSpecularIsRoughness, 0); } } else { GL.Uniform1(mUniform_TextureUseSpecularMap, 0); GL.Uniform1(mUniform_TextureSpecularIsRoughness, 0); } if (mesh.Material.TextureEmissive.OpenGLID > 0) { GL.ActiveTexture(TextureUnit.Texture4); GL.BindTexture(TextureTarget.Texture2D, mesh.Material.TextureEmissive.OpenGLID); GL.Uniform1(mUniform_TextureEmissiveMap, 4); GL.Uniform1(mUniform_TextureUseEmissiveMap, 1); } else { GL.Uniform1(mUniform_TextureUseEmissiveMap, 0); } if (g.ColorEmissive.W > 0) { GL.Uniform4(mUniform_EmissiveColor, g.ColorEmissive); } else { GL.Uniform4(mUniform_EmissiveColor, mesh.Material.ColorEmissive); } } GL.BindVertexArray(mesh.VAO); GL.BindBuffer(BufferTarget.ElementArrayBuffer, mesh.VBOIndex); GL.DrawElements(mesh.Primitive, mesh.IndexCount, DrawElementsType.UnsignedInt, 0); //HelperGL.CheckGLErrors(); GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); GL.BindVertexArray(0); GL.BindTexture(TextureTarget.Texture2D, 0); } } GL.BindTexture(TextureTarget.Texture2D, 0); GL.UseProgram(0); }
internal abstract void Draw(GameObject g, ref Matrix4 viewProjection, ref Matrix4 viewProjectionShadow, ref Matrix4 viewProjectionShadow2, HelperFrustum frustum, ref float[] lightColors, ref float[] lightTargets, ref float[] lightPositions, int lightCount, ref int lightShadow);
internal abstract void Draw(GameObject g, ref Matrix4 viewProjection, HelperFrustum frustum);
internal void Draw(GameObject g, ref Matrix4 viewProjection, HelperFrustum frustum, int textureIndex) { if (g == null || !g.HasModel || g.CurrentWorld == null || g.Opacity <= 0) { return; } if (KWEngine.Projection == ProjectionType.Perspective) { g.IsInsideScreenSpace = frustum.SphereVsFrustum(g.GetCenterPointForAllHitboxes(), g.GetMaxDiameter() / 2); } else { Vector3 lookAt = CurrentWorld.GetCameraLookAtVectorEitherWay(); Vector3 camPos = CurrentWorld.GetCameraPositionEitherWay(); Vector3 objectCenter = g.GetCenterPointForAllHitboxes(); float dot = Vector3.Dot(objectCenter - camPos, lookAt); g.IsInsideScreenSpace = dot > 0; } if (!g.IsInsideScreenSpace) { return; } GL.Disable(EnableCap.Blend); lock (g) { if (g.Opacity < 1) { GL.Enable(EnableCap.Blend); } GL.Uniform4(mUniform_Glow, g.Glow); GL.Uniform4(mUniform_Outline, g.ColorOutline); GL.Uniform3(mUniform_TintColor, g.Color); GL.Uniform1(mUniform_LightAffection, g.IsAffectedByLight ? 1 : 0); // Camera if (!CurrentWorld.IsFirstPersonMode) { GL.Uniform3(mUniform_uCameraPos, g.CurrentWorld.GetCameraPosition().X, g.CurrentWorld.GetCameraPosition().Y, g.CurrentWorld.GetCameraPosition().Z); GL.Uniform3(mUniform_uCameraDirection, g.CurrentWorld.GetCameraLookAtVector()); } else { GL.Uniform3(mUniform_uCameraPos, g.CurrentWorld.GetFirstPersonObject().Position.X, g.CurrentWorld.GetFirstPersonObject().Position.Y + g.CurrentWorld.GetFirstPersonObject().FPSEyeOffset, g.CurrentWorld.GetFirstPersonObject().Position.Z); GL.Uniform3(mUniform_uCameraDirection, HelperCamera.GetLookAtVector()); } Matrix4.Mult(ref g.ModelMatrixForRenderPass[0], ref viewProjection, out _modelViewProjection); Matrix4.Transpose(ref g.ModelMatrixForRenderPass[0], out _normalMatrix); Matrix4.Invert(ref _normalMatrix, out _normalMatrix); GL.UniformMatrix4(mUniform_ModelMatrix, false, ref g.ModelMatrixForRenderPass[0]); GL.UniformMatrix4(mUniform_NormalMatrix, false, ref _normalMatrix); GL.UniformMatrix4(mUniform_MVP, false, ref _modelViewProjection); if (g.ColorEmissive.W > 0) { GL.Uniform4(mUniform_EmissiveColor, g.ColorEmissive); } else { GL.Uniform4(mUniform_EmissiveColor, Vector4.Zero); } string meshName = g.Model.Meshes.Keys.ElementAt(0); GeoMesh mesh = g.Model.Meshes[meshName]; GeoMaterial meshMaterial = mesh.Material; GL.Uniform1(mUniform_Roughness, meshMaterial.Roughness); GL.Uniform1(mUniform_Metalness, meshMaterial.Metalness); GL.Uniform4(mUniform_TextureTransform, mesh.Terrain.mTexX, mesh.Terrain.mTexY, g.mTextureOffset.X, g.mTextureOffset.Y); // albedo map: int texId = -1; texId = mesh.Material.TextureAlbedo.OpenGLID; GL.ActiveTexture(TextureUnit.Texture0 + textureIndex); GL.BindTexture(TextureTarget.Texture2D, texId > 0 ? texId : KWEngine.TextureWhite); GL.Uniform1(mUniform_Texture, textureIndex); GL.Uniform1(mUniform_TextureUse, texId > 0 ? 1 : 0); GL.Uniform3(mUniform_BaseColor, texId > 0 ? new Vector3(1f, 1f, 1f) : new Vector3(meshMaterial.ColorAlbedo.X, meshMaterial.ColorAlbedo.Y, meshMaterial.ColorAlbedo.Z)); textureIndex++; // normal map: texId = meshMaterial.TextureNormal.OpenGLID; GL.ActiveTexture(TextureUnit.Texture0 + textureIndex); GL.BindTexture(TextureTarget.Texture2D, texId > 0 ? texId : KWEngine.TextureWhite); GL.Uniform1(mUniform_TextureNormalMap, textureIndex); GL.Uniform1(mUniform_TextureUseNormalMap, texId > 0 ? 1 : 0); textureIndex++; // roughness map: GL.ActiveTexture(TextureUnit.Texture0 + textureIndex); if (meshMaterial.TextureRoughness.OpenGLID > 0) { GL.BindTexture(TextureTarget.Texture2D, meshMaterial.TextureRoughness.OpenGLID); GL.Uniform1(mUniform_TextureRoughnessMap, textureIndex); GL.Uniform1(mUniform_TextureUseRoughnessMap, 1); GL.Uniform1(mUniform_TextureRoughnessIsSpecular, meshMaterial.TextureRoughnessIsSpecular ? 1 : 0); } else { if (meshMaterial.TextureRoughnessInMetalness && meshMaterial.TextureMetalness.OpenGLID > 0) { GL.BindTexture(TextureTarget.Texture2D, KWEngine.TextureWhite); GL.Uniform1(mUniform_TextureRoughnessMap, textureIndex); GL.Uniform1(mUniform_TextureUseRoughnessMap, 0); GL.Uniform1(mUniform_TextureRoughnessIsSpecular, 1); } else { GL.BindTexture(TextureTarget.Texture2D, KWEngine.TextureWhite); GL.Uniform1(mUniform_TextureRoughnessMap, textureIndex); GL.Uniform1(mUniform_TextureUseRoughnessMap, 0); GL.Uniform1(mUniform_TextureRoughnessIsSpecular, 0); } } textureIndex++; // metalness map: GL.ActiveTexture(TextureUnit.Texture0 + textureIndex); if (meshMaterial.TextureMetalness.OpenGLID > 0) { GL.BindTexture(TextureTarget.Texture2D, meshMaterial.TextureMetalness.OpenGLID); GL.Uniform1(mUniform_TextureMetalnessMap, textureIndex); GL.Uniform1(mUniform_TextureUseMetalnessMap, 1); } else { GL.BindTexture(TextureTarget.Texture2D, KWEngine.TextureBlack); GL.Uniform1(mUniform_TextureMetalnessMap, textureIndex); GL.Uniform1(mUniform_TextureUseMetalnessMap, 0); } textureIndex++; // emissive map: GL.ActiveTexture(TextureUnit.Texture0 + textureIndex); if (meshMaterial.TextureEmissive.OpenGLID > 0) { GL.BindTexture(TextureTarget.Texture2D, meshMaterial.TextureEmissive.OpenGLID); GL.Uniform1(mUniform_TextureEmissiveMap, textureIndex); GL.Uniform1(mUniform_TextureUseEmissiveMap, 1); } else { GL.BindTexture(TextureTarget.Texture2D, KWEngine.TextureBlack); GL.Uniform1(mUniform_TextureEmissiveMap, textureIndex); GL.Uniform1(mUniform_TextureUseEmissiveMap, 0); } textureIndex++; // Blendmapping: if (mesh.Terrain._texBlend > 0 && mesh.Terrain._texBlend != KWEngine.TextureBlack) { GL.ActiveTexture(TextureUnit.Texture0 + textureIndex); GL.BindTexture(TextureTarget.Texture2D, mesh.Terrain._texBlend); GL.Uniform1(mUniform_TextureBlend, textureIndex); textureIndex++; GL.ActiveTexture(TextureUnit.Texture0 + textureIndex); GL.BindTexture(TextureTarget.Texture2D, mesh.Terrain._texR); GL.Uniform1(mUniform_TextureRed, textureIndex); textureIndex++; GL.ActiveTexture(TextureUnit.Texture0 + textureIndex); if (mesh.Terrain._texG > 0 && mesh.Terrain._texG != KWEngine.TextureAlpha) { GL.BindTexture(TextureTarget.Texture2D, mesh.Terrain._texG); } else { GL.BindTexture(TextureTarget.Texture2D, KWEngine.TextureAlpha); } GL.Uniform1(mUniform_TextureGreen, textureIndex); textureIndex++; GL.ActiveTexture(TextureUnit.Texture0 + textureIndex); if (mesh.Terrain._texB > 0 && mesh.Terrain._texB != KWEngine.TextureAlpha) { GL.BindTexture(TextureTarget.Texture2D, mesh.Terrain._texB); } else { GL.BindTexture(TextureTarget.Texture2D, KWEngine.TextureAlpha); } GL.Uniform1(mUniform_TextureBlue, textureIndex); textureIndex++; GL.Uniform1(mUniform_UseBlend, 1); } else { GL.ActiveTexture(TextureUnit.Texture0 + textureIndex); GL.BindTexture(TextureTarget.Texture2D, KWEngine.TextureBlack); GL.Uniform1(mUniform_TextureBlend, textureIndex); textureIndex++; GL.ActiveTexture(TextureUnit.Texture0 + textureIndex); GL.BindTexture(TextureTarget.Texture2D, KWEngine.TextureBlack); GL.Uniform1(mUniform_TextureRed, textureIndex); textureIndex++; GL.ActiveTexture(TextureUnit.Texture0 + textureIndex); GL.BindTexture(TextureTarget.Texture2D, KWEngine.TextureBlack); GL.Uniform1(mUniform_TextureGreen, textureIndex); textureIndex++; GL.ActiveTexture(TextureUnit.Texture0 + textureIndex); GL.BindTexture(TextureTarget.Texture2D, KWEngine.TextureBlack); GL.Uniform1(mUniform_TextureBlue, textureIndex); textureIndex++; GL.Uniform1(mUniform_UseBlend, 0); } GL.BindVertexArray(mesh.VAO); GL.BindBuffer(BufferTarget.ElementArrayBuffer, mesh.VBOIndex); GL.DrawElements(mesh.Primitive, mesh.IndexCount, DrawElementsType.UnsignedInt, 0); GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); GL.BindVertexArray(0); } if (g.Opacity < 1) { GL.Disable(EnableCap.Blend); } }