public void Initialize(GeoMaterialName mName) { geoMaterial = gameObject.GetComponentInChildren <GeoMaterial>(); geoMaterial.Initialize(mName); }
internal void DrawAttachedModel(GameObject g, GeoModel attachedModel, ref Matrix4 viewProjection, int textureIndex, ref Matrix4 attachedModelMatrix) { lock (g) { 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()); } int index = 0; for (int i = 0; i < attachedModel.Meshes.Keys.Count; i++) { string meshName = attachedModel.Meshes.Keys.ElementAt(i); if (g.Model.IsKWCube6) { index = 0; } // Matrices: Matrix4 mmPlusAttached = Matrix4.Identity; try { mmPlusAttached = attachedModelMatrix * g.ModelMatrixForRenderPass[index]; Matrix4.Mult(ref mmPlusAttached, ref viewProjection, out _modelViewProjection); Matrix4.Transpose(ref mmPlusAttached, out _normalMatrix); Matrix4.Invert(ref _normalMatrix, out _normalMatrix); } catch (Exception) { continue; } GL.UniformMatrix4(mUniform_ModelMatrix, false, ref mmPlusAttached); GL.UniformMatrix4(mUniform_NormalMatrix, false, ref _normalMatrix); GL.UniformMatrix4(mUniform_MVP, false, ref _modelViewProjection); index++; GeoMesh mesh = attachedModel.Meshes.Values.ElementAt(i); GeoMaterial meshMaterial = g._materials[i]; if (meshMaterial.Opacity <= 0) { continue; } if (meshMaterial.Opacity < 1 || g.Opacity < 1) { GL.Enable(EnableCap.Blend); } else { GL.Disable(EnableCap.Blend); } if (g.ColorEmissive.W > 0) { GL.Uniform4(mUniform_EmissiveColor, g.ColorEmissive); } else { GL.Uniform4(mUniform_EmissiveColor, meshMaterial.ColorEmissive.X, meshMaterial.ColorEmissive.Y, meshMaterial.ColorEmissive.Z, meshMaterial.ColorEmissive.W); } GL.Uniform1(mUniform_Opacity, meshMaterial.Opacity * g.Opacity); GL.Uniform1(mUniform_UseAnimations, 0); GL.Uniform1(mUniform_Roughness, meshMaterial.Roughness); GL.Uniform1(mUniform_Metalness, meshMaterial.Metalness); GL.Uniform2(mUniform_TextureTransform, meshMaterial.TextureAlbedo.UVTransform.X == 0 ? 1 : meshMaterial.TextureAlbedo.UVTransform.X, meshMaterial.TextureAlbedo.UVTransform.Y == 0 ? 1 : meshMaterial.TextureAlbedo.UVTransform.Y); // albedo map: int texId = meshMaterial.TextureAlbedo.OpenGLID; GL.ActiveTexture(TextureUnit.Texture0 + textureIndex); if (texId > 0) { GL.BindTexture(TextureTarget.Texture2D, texId); GL.Uniform1(mUniform_Texture, textureIndex); GL.Uniform1(mUniform_TextureUse, 1); GL.Uniform3(mUniform_BaseColor, 1f, 1f, 1f); } else { GL.BindTexture(TextureTarget.Texture2D, KWEngine.TextureWhite); GL.Uniform1(mUniform_Texture, textureIndex); GL.Uniform1(mUniform_TextureUse, 0); GL.Uniform3(mUniform_BaseColor, meshMaterial.ColorAlbedo.X, meshMaterial.ColorAlbedo.Y, meshMaterial.ColorAlbedo.Z); } // normal map: texId = meshMaterial.TextureNormal.OpenGLID; GL.ActiveTexture(TextureUnit.Texture0 + textureIndex + 1); if (texId > 0) { GL.BindTexture(TextureTarget.Texture2D, texId); GL.Uniform1(mUniform_TextureNormalMap, textureIndex + 1); GL.Uniform1(mUniform_TextureUseNormalMap, 1); } else { GL.BindTexture(TextureTarget.Texture2D, KWEngine.TextureWhite); GL.Uniform1(mUniform_TextureNormalMap, textureIndex + 1); GL.Uniform1(mUniform_TextureUseNormalMap, 0); } // roughness map: GL.ActiveTexture(TextureUnit.Texture0 + textureIndex + 2); if (meshMaterial.TextureRoughness.OpenGLID > 0) { GL.BindTexture(TextureTarget.Texture2D, meshMaterial.TextureRoughness.OpenGLID); GL.Uniform1(mUniform_TextureRoughnessMap, textureIndex + 2); 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 + 2); GL.Uniform1(mUniform_TextureUseRoughnessMap, 0); GL.Uniform1(mUniform_TextureRoughnessIsSpecular, 1); } else { GL.BindTexture(TextureTarget.Texture2D, KWEngine.TextureWhite); GL.Uniform1(mUniform_TextureRoughnessMap, textureIndex + 2); GL.Uniform1(mUniform_TextureUseRoughnessMap, 0); GL.Uniform1(mUniform_TextureRoughnessIsSpecular, 0); } } // metalness map: GL.ActiveTexture(TextureUnit.Texture0 + textureIndex + 3); if (meshMaterial.TextureMetalness.OpenGLID > 0) { GL.BindTexture(TextureTarget.Texture2D, meshMaterial.TextureMetalness.OpenGLID); GL.Uniform1(mUniform_TextureMetalnessMap, textureIndex + 3); GL.Uniform1(mUniform_TextureUseMetalnessMap, 1); } else { GL.BindTexture(TextureTarget.Texture2D, KWEngine.TextureBlack); GL.Uniform1(mUniform_TextureMetalnessMap, textureIndex + 3); GL.Uniform1(mUniform_TextureUseMetalnessMap, 0); } // emissive map: GL.ActiveTexture(TextureUnit.Texture0 + textureIndex + 4); if (meshMaterial.TextureEmissive.OpenGLID > 0) { GL.BindTexture(TextureTarget.Texture2D, meshMaterial.TextureEmissive.OpenGLID); GL.Uniform1(mUniform_TextureEmissiveMap, textureIndex + 4); GL.Uniform1(mUniform_TextureUseEmissiveMap, 1); } else { GL.BindTexture(TextureTarget.Texture2D, KWEngine.TextureBlack); GL.Uniform1(mUniform_TextureEmissiveMap, textureIndex + 4); GL.Uniform1(mUniform_TextureUseEmissiveMap, 0); } // light map: GL.ActiveTexture(TextureUnit.Texture0 + textureIndex + 5); if (meshMaterial.TextureLight.OpenGLID > 0) { GL.BindTexture(TextureTarget.Texture2D, meshMaterial.TextureLight.OpenGLID); GL.Uniform1(mUniform_TextureLightMap, textureIndex + 5); GL.Uniform1(mUniform_TextureUseLightMap, 1); } else { GL.BindTexture(TextureTarget.Texture2D, KWEngine.TextureWhite); GL.Uniform1(mUniform_TextureLightMap, textureIndex + 5); GL.Uniform1(mUniform_TextureUseLightMap, 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); GL.BindTexture(TextureTarget.Texture2D, 0); HelperGeneral.CheckGLErrors(); } } }
internal void Draw(GameObject g, ref Matrix4 viewProjection, int textureIndex, FPVModelObject fpModelObject = null) { lock (g) { 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 { if (fpModelObject != null) { GL.Uniform3(mUniform_uCameraPos, fpModelObject._tmpLAVStartPos); GL.Uniform3(mUniform_uCameraDirection, fpModelObject._tmpLAV); } 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()); } } int index = 0; for (int i = 0; i < g.Model.Meshes.Keys.Count; i++) { string meshName = g.Model.Meshes.Keys.ElementAt(i); if (g.Model.IsKWCube6) { 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); index++; GL.Disable(EnableCap.Blend); GeoMesh mesh = g.Model.Meshes.Values.ElementAt(i); GeoMaterial meshMaterial = g._materials[i]; if (meshMaterial.Opacity <= 0) { continue; } if (meshMaterial.Opacity < 1 || g.Opacity < 1 || g.Model.Name == "kwquad.obj") { GL.Enable(EnableCap.Blend); } if (g.ColorEmissive.W > 0) { GL.Uniform4(mUniform_EmissiveColor, g.ColorEmissive); } else { GL.Uniform4(mUniform_EmissiveColor, meshMaterial.ColorEmissive.X, meshMaterial.ColorEmissive.Y, meshMaterial.ColorEmissive.Z, meshMaterial.ColorEmissive.W); } GL.Uniform1(mUniform_Opacity, meshMaterial.Opacity * g.Opacity); if (mesh.BoneNames.Count > 0 && g.AnimationID >= 0 && g.Model.Animations != null && g.Model.Animations.Count > 0) { GL.Uniform1(mUniform_UseAnimations, 1); for (int j = 0; j < g.BoneTranslationMatrices[meshName].Length; j++) { Matrix4 tmp = g.BoneTranslationMatrices[meshName][j]; GL.UniformMatrix4(mUniform_BoneTransforms + j, false, ref tmp); } } else { GL.Uniform1(mUniform_UseAnimations, 0); } GL.Uniform1(mUniform_Roughness, meshMaterial.Roughness); GL.Uniform1(mUniform_Metalness, meshMaterial.Metalness); Vector4 texTransform = new Vector4(meshMaterial.TextureAlbedo.UVTransform.X == 0 ? 1 : meshMaterial.TextureAlbedo.UVTransform.X, meshMaterial.TextureAlbedo.UVTransform.Y == 0 ? 1 : meshMaterial.TextureAlbedo.UVTransform.Y, g.mTextureOffset.X, g.mTextureOffset.Y); GL.Uniform4(mUniform_TextureTransform, texTransform); // albedo map: int texId = meshMaterial.TextureAlbedo.OpenGLID; GL.ActiveTexture(TextureUnit.Texture0 + textureIndex); if (texId > 0) { GL.BindTexture(TextureTarget.Texture2D, texId); GL.Uniform1(mUniform_Texture, textureIndex); GL.Uniform1(mUniform_TextureUse, 1); GL.Uniform3(mUniform_BaseColor, 1f, 1f, 1f); } else { GL.BindTexture(TextureTarget.Texture2D, KWEngine.TextureWhite); GL.Uniform1(mUniform_Texture, textureIndex); GL.Uniform1(mUniform_TextureUse, 0); GL.Uniform3(mUniform_BaseColor, meshMaterial.ColorAlbedo.X, meshMaterial.ColorAlbedo.Y, meshMaterial.ColorAlbedo.Z); } // normal map: texId = meshMaterial.TextureNormal.OpenGLID; GL.ActiveTexture(TextureUnit.Texture0 + textureIndex + 1); if (texId > 0) { GL.BindTexture(TextureTarget.Texture2D, texId); GL.Uniform1(mUniform_TextureNormalMap, textureIndex + 1); GL.Uniform1(mUniform_TextureUseNormalMap, 1); } else { GL.BindTexture(TextureTarget.Texture2D, KWEngine.TextureWhite); GL.Uniform1(mUniform_TextureNormalMap, textureIndex + 1); GL.Uniform1(mUniform_TextureUseNormalMap, 0); } // roughness map: GL.ActiveTexture(TextureUnit.Texture0 + textureIndex + 2); if (meshMaterial.TextureRoughness.OpenGLID > 0) { GL.BindTexture(TextureTarget.Texture2D, meshMaterial.TextureRoughness.OpenGLID); GL.Uniform1(mUniform_TextureRoughnessMap, textureIndex + 2); 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 + 2); GL.Uniform1(mUniform_TextureUseRoughnessMap, 0); GL.Uniform1(mUniform_TextureRoughnessIsSpecular, 1); } else { GL.BindTexture(TextureTarget.Texture2D, KWEngine.TextureWhite); GL.Uniform1(mUniform_TextureRoughnessMap, textureIndex + 2); GL.Uniform1(mUniform_TextureUseRoughnessMap, 0); GL.Uniform1(mUniform_TextureRoughnessIsSpecular, 0); } } // metalness map: GL.ActiveTexture(TextureUnit.Texture0 + textureIndex + 3); if (meshMaterial.TextureMetalness.OpenGLID > 0) { GL.BindTexture(TextureTarget.Texture2D, meshMaterial.TextureMetalness.OpenGLID); GL.Uniform1(mUniform_TextureMetalnessMap, textureIndex + 3); GL.Uniform1(mUniform_TextureUseMetalnessMap, 1); } else { GL.BindTexture(TextureTarget.Texture2D, KWEngine.TextureBlack); GL.Uniform1(mUniform_TextureMetalnessMap, textureIndex + 3); GL.Uniform1(mUniform_TextureUseMetalnessMap, 0); } // emissive map: GL.ActiveTexture(TextureUnit.Texture0 + textureIndex + 4); if (meshMaterial.TextureEmissive.OpenGLID > 0) { GL.BindTexture(TextureTarget.Texture2D, meshMaterial.TextureEmissive.OpenGLID); GL.Uniform1(mUniform_TextureEmissiveMap, textureIndex + 4); GL.Uniform1(mUniform_TextureUseEmissiveMap, 1); } else { GL.BindTexture(TextureTarget.Texture2D, KWEngine.TextureBlack); GL.Uniform1(mUniform_TextureEmissiveMap, textureIndex + 4); GL.Uniform1(mUniform_TextureUseEmissiveMap, 0); } GL.ActiveTexture(TextureUnit.Texture0 + textureIndex + 5); if (meshMaterial.TextureLight.OpenGLID > 0) { GL.BindTexture(TextureTarget.Texture2D, meshMaterial.TextureLight.OpenGLID); GL.Uniform1(mUniform_TextureLightMap, textureIndex + 5); GL.Uniform1(mUniform_TextureUseLightMap, 1); } else { GL.BindTexture(TextureTarget.Texture2D, KWEngine.TextureWhite); GL.Uniform1(mUniform_TextureLightMap, textureIndex + 5); GL.Uniform1(mUniform_TextureUseLightMap, 0); } GL.Uniform1(mUniform_TextureFullAlpha, g.Model.Name == "kwquad.obj" ? 1 : 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); GL.BindTexture(TextureTarget.Texture2D, 0); } } }
/// <summary> /// Baut ein Terrain-Modell /// </summary> /// <param name="name">Name des Modells</param> /// <param name="heightmap">Height Map Textur</param> /// <param name="texture">Textur der Oberfläche</param> /// <param name="width">Breite</param> /// <param name="height">Höhe</param> /// <param name="depth">Tiefe</param> /// <param name="texRepeatX">Texturwiederholung Breite</param> /// <param name="texRepeatZ">Texturwiederholung Tiefe</param> /// <param name="isFile">false, wenn die Texturen Teil der EXE sind (Eingebettete Ressource)</param> public static void BuildTerrainModel(string name, string heightmap, string texture, float width, float height, float depth, float texRepeatX = 1, float texRepeatZ = 1, bool isFile = true) { if (Models.ContainsKey(name)) { throw new Exception("There already is a model with that name. Please choose a different name."); } GeoModel terrainModel = new GeoModel(); terrainModel.Name = name; terrainModel.Meshes = new Dictionary <string, GeoMesh>(); terrainModel.IsValid = true; GeoMeshHitbox meshHitBox = new GeoMeshHitbox(0 + width / 2, 0 + height / 2, 0 + depth / 2, 0 - width / 2, 0 - height / 2, 0 - depth / 2); meshHitBox.Model = terrainModel; meshHitBox.Name = name; terrainModel.MeshHitboxes = new List <GeoMeshHitbox>(); terrainModel.MeshHitboxes.Add(meshHitBox); GeoTerrain t = new GeoTerrain(); GeoMesh terrainMesh = t.BuildTerrain(new Vector3(0, 0, 0), heightmap, width, height, depth, texRepeatX, texRepeatZ, isFile); terrainMesh.Terrain = t; GeoMaterial mat = new GeoMaterial(); mat.BlendMode = OpenTK.Graphics.OpenGL4.BlendingFactor.OneMinusSrcAlpha; mat.ColorDiffuse = new Vector4(1, 1, 1, 1); mat.ColorEmissive = new Vector4(0, 0, 0, 0); mat.Name = name + "-Material"; mat.SpecularArea = 512; mat.SpecularPower = 0; GeoTexture texDiffuse = new GeoTexture(name + "-TextureDiffuse"); texDiffuse.Filename = texture; texDiffuse.Type = GeoTexture.TexType.Diffuse; texDiffuse.UVMapIndex = 0; texDiffuse.UVTransform = new Vector2(texRepeatX, texRepeatZ); bool dictFound = CustomTextures.TryGetValue(CurrentWorld, out Dictionary <string, int> texDict); if (dictFound && texDict.ContainsKey(texture)) { texDiffuse.OpenGLID = texDict[texture]; } else { texDiffuse.OpenGLID = isFile ? HelperTexture.LoadTextureForModelExternal(texture) : HelperTexture.LoadTextureForModelInternal(texture); if (dictFound) { texDict.Add(texture, texDiffuse.OpenGLID); } } mat.TextureDiffuse = texDiffuse; terrainMesh.Material = mat; terrainModel.Meshes.Add("Terrain", terrainMesh); KWEngine.Models.Add(name, terrainModel); }
/// <summary> /// Baut ein Terrain-Modell /// </summary> /// <param name="name">Name des Modells</param> /// <param name="heightmap">Height Map Textur</param> /// <param name="texture">Textur der Oberfläche</param> /// <param name="width">Breite</param> /// <param name="height">Höhe</param> /// <param name="depth">Tiefe</param> /// <param name="texRepeatX">Texturwiederholung Breite</param> /// <param name="texRepeatZ">Texturwiederholung Tiefe</param> /// <param name="isFile">false, wenn die Texturen Teil der EXE sind (Eingebettete Ressource)</param> public static void BuildTerrainModel(string name, string heightmap, string texture, float width, float height, float depth, float texRepeatX = 1, float texRepeatZ = 1, bool isFile = true) { if (Models.ContainsKey(name)) { HelperGeneral.ShowErrorAndQuit("KWEngine::BuildTerrainModel()", "There already is a model with that name. Please choose a different name."); return; } GeoModel terrainModel = new GeoModel(); terrainModel.Name = name; terrainModel.Meshes = new Dictionary <string, GeoMesh>(); terrainModel.IsValid = true; GeoMeshHitbox meshHitBox = new GeoMeshHitbox(0 + width / 2, 0 + height / 2, 0 + depth / 2, 0 - width / 2, 0 - height / 2, 0 - depth / 2, null); meshHitBox.Model = terrainModel; meshHitBox.Name = name; terrainModel.MeshHitboxes = new List <GeoMeshHitbox>(); terrainModel.MeshHitboxes.Add(meshHitBox); GeoTerrain t = new GeoTerrain(); GeoMesh terrainMesh = t.BuildTerrain2(new Vector3(0, 0, 0), heightmap, width, height, depth, texRepeatX, texRepeatZ, isFile); terrainMesh.Terrain = t; GeoMaterial mat = new GeoMaterial(); mat.BlendMode = BlendingFactor.OneMinusSrcAlpha; mat.ColorAlbedo = new Vector4(1, 1, 1, 1); mat.ColorEmissive = new Vector4(0, 0, 0, 0); mat.Opacity = 1; mat.Metalness = 0; mat.Roughness = 1; GeoTexture texDiffuse = new GeoTexture(); texDiffuse.Filename = texture; texDiffuse.Type = TextureType.Albedo; texDiffuse.UVMapIndex = 0; texDiffuse.UVTransform = new Vector2(texRepeatX, texRepeatZ); bool dictFound = CustomTextures.TryGetValue(CurrentWorld, out Dictionary <string, int> texDict); if (dictFound && texDict.ContainsKey(texture)) { texDiffuse.OpenGLID = texDict[texture]; } else { int texId = isFile ? HelperTexture.LoadTextureForModelExternal(texture) : HelperTexture.LoadTextureForModelInternal(texture); texDiffuse.OpenGLID = texId > 0 ? texId : KWEngine.TextureDefault; if (dictFound && texId > 0) { texDict.Add(texture, texDiffuse.OpenGLID); } } mat.TextureAlbedo = texDiffuse; terrainMesh.Material = mat; terrainModel.Meshes.Add("Terrain", terrainMesh); KWEngine.Models.Add(name, terrainModel); }
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); } }