/// <summary> /// Crear flechas de debug para normales, tangentes y binormales /// </summary> private void loadDebugArrows(TgcMeshBumpMapping mesh) { //Obtener vertexBuffer var vertexBuffer = (TgcMeshBumpMapping.BumpMappingVertex[])mesh.D3dMesh.LockVertexBuffer( typeof(TgcMeshBumpMapping.BumpMappingVertex), LockFlags.ReadOnly, mesh.D3dMesh.NumberVertices); mesh.D3dMesh.UnlockVertexBuffer(); for (var i = 0; i < vertexBuffer.Length; i++) { var v = vertexBuffer[i]; normals.Add(TgcArrow.fromDirection(v.Position, v.Normal * 50, Color.Blue, Color.Yellow, 0.5f, new Vector2(2f, 4f))); tangents.Add(TgcArrow.fromDirection(v.Position, v.Tangent * 50, Color.Red, Color.Yellow, 0.5f, new Vector2(2f, 4f))); binormals.Add(TgcArrow.fromDirection(v.Position, v.Binormal * 50, Color.Green, Color.Yellow, 0.5f, new Vector2(2f, 4f))); } }
public override void Init() { //DEBUG: para probar codigo que genera un NormalMap automaticamente. Queda bastante peor que el NormalMap que ya viene hecho //createNormalMap(this.ShadersDir+"BumpMapping_DiffuseMap.jpg", this.ShadersDir+"NormalMap_Prueba.jpg"); //TgcTexture normalMap = TgcTexture.createTexture(this.ShadersDir+"NormalMap_Prueba2.jpg"); //Crear 3 paredes y un piso con textura comun y textura de normalMap var diffuseMap = TgcTexture.createTexture(MediaDir + "Texturas//BM_DiffuseMap_pared.jpg"); var normalMap = TgcTexture.createTexture(MediaDir + "Texturas//BM_NormalMap.jpg"); TgcTexture[] normalMapArray = { normalMap }; var paredSur = TgcBox.fromExtremes(new Vector3(-200, 0, -210), new Vector3(200, 100, -200), diffuseMap); var paredOeste = TgcBox.fromExtremes(new Vector3(-210, 0, -200), new Vector3(-200, 100, 200), diffuseMap); var paredEste = TgcBox.fromExtremes(new Vector3(200, 0, -200), new Vector3(210, 100, 200), diffuseMap); var piso = TgcBox.fromExtremes(new Vector3(-200, -1, -200), new Vector3(200, 0, 200), diffuseMap); //Convertir TgcBox a TgcMesh var m1 = paredSur.toMesh("paredSur"); var m2 = paredOeste.toMesh("paredOeste"); var m3 = paredEste.toMesh("paredEste"); var m4 = piso.toMesh("piso"); //Convertir TgcMesh a TgcMeshBumpMapping meshes = new List <TgcMeshBumpMapping>(); meshes.Add(TgcMeshBumpMapping.fromTgcMesh(m1, normalMapArray)); meshes.Add(TgcMeshBumpMapping.fromTgcMesh(m2, normalMapArray)); meshes.Add(TgcMeshBumpMapping.fromTgcMesh(m3, normalMapArray)); meshes.Add(TgcMeshBumpMapping.fromTgcMesh(m4, normalMapArray)); //Borrar TgcMesh y TgcBox, ya no se usan paredSur.dispose(); paredOeste.dispose(); paredEste.dispose(); piso.dispose(); m1.dispose(); m2.dispose(); m3.dispose(); m4.dispose(); //Crear flechas de debug tangents = new List <TgcArrow>(); normals = new List <TgcArrow>(); binormals = new List <TgcArrow>(); foreach (var mesh in meshes) { loadDebugArrows(mesh); } //Camara en 1ra persona Camara = new TgcFpsCamera(new Vector3(0, 50, 100)); //Cargar Shader de personalizado de BumpMapping. Solo soporta meshes de tipo DiffuseMap effect = TgcShaders.loadEffect(ShadersDir + "BumpMapping.fx"); //Cargar shader en meshes foreach (var m in meshes) { m.Effect = effect; m.Technique = "BumpMappingTechnique"; } //Mesh para la luz lightMesh = TgcBox.fromSize(new Vector3(10, 10, 10), Color.Red); Modifiers.addFloat("bumpiness", 0, 1, 1f); Modifiers.addVertex3f("lightPos", new Vector3(-200, 0, -200), new Vector3(200, 100, 200), new Vector3(0, 80, 0)); Modifiers.addColor("lightColor", Color.White); Modifiers.addFloat("lightIntensity", 0, 150, 20); Modifiers.addFloat("lightAttenuation", 0.1f, 2, 0.3f); Modifiers.addFloat("specularEx", 0, 20, 9f); Modifiers.addBoolean("showNormals", "showNormals", false); Modifiers.addBoolean("showTangents", "showTangents", false); Modifiers.addBoolean("showBinormals", "showBinormals", false); Modifiers.addColor("mEmissive", Color.Black); Modifiers.addColor("mAmbient", Color.White); Modifiers.addColor("mDiffuse", Color.White); Modifiers.addColor("mSpecular", Color.White); }
public override void Init() { //Cargar textura de CubeMap para Environment Map cubeMap = TextureLoader.FromCubeFile(D3DDevice.Instance.Device, MediaDir + "CubeMap.dds"); //Crear 3 paredes y un piso con textura comun y textura de normalMap var diffuseMap = TgcTexture.createTexture(MediaDir + "Texturas//BM_DiffuseMap_pared.jpg"); var normalMap = TgcTexture.createTexture(MediaDir + "Texturas//BM_NormalMap.jpg"); TgcTexture[] normalMapArray = { normalMap }; var paredSur = TgcBox.fromExtremes(new Vector3(-200, 0, -210), new Vector3(200, 100, -200), diffuseMap); var paredOeste = TgcBox.fromExtremes(new Vector3(-210, 0, -200), new Vector3(-200, 100, 200), diffuseMap); var paredEste = TgcBox.fromExtremes(new Vector3(200, 0, -200), new Vector3(210, 100, 200), diffuseMap); var piso = TgcBox.fromExtremes(new Vector3(-200, -1, -200), new Vector3(200, 0, 200), diffuseMap); //Convertir TgcBox a TgcMesh var m1 = paredSur.toMesh("paredSur"); var m2 = paredOeste.toMesh("paredOeste"); var m3 = paredEste.toMesh("paredEste"); var m4 = piso.toMesh("piso"); //Convertir TgcMesh a TgcMeshBumpMapping (se usa solo por conveniencia, pero el NormalMap de TgcMeshBumpMapping es innecesario para este ejemplo) meshes = new List <TgcMeshBumpMapping>(); meshes.Add(TgcMeshBumpMapping.fromTgcMesh(m1, normalMapArray)); meshes.Add(TgcMeshBumpMapping.fromTgcMesh(m2, normalMapArray)); meshes.Add(TgcMeshBumpMapping.fromTgcMesh(m3, normalMapArray)); meshes.Add(TgcMeshBumpMapping.fromTgcMesh(m4, normalMapArray)); //Borrar TgcMesh y TgcBox, ya no se usan paredSur.dispose(); paredOeste.dispose(); paredEste.dispose(); piso.dispose(); m1.dispose(); m2.dispose(); m3.dispose(); m4.dispose(); //Camara en 1ra persona Camara = new TgcFpsCamera(new Vector3(0, 50, 100)); //Cargar Shader de DynamicLights effect = TgcShaders.loadEffect(ShadersDir + "EnvironmentMap.fx"); effect.Technique = "SimpleEnvironmentMapTechnique"; //Cargar shader en meshes foreach (var m in meshes) { m.Effect = effect; m.Technique = "SimpleEnvironmentMapTechnique"; } //Mesh para la luz lightMesh = TgcBox.fromSize(new Vector3(10, 10, 10), Color.Red); Modifiers.addFloat("reflection", 0, 1, 0.35f); Modifiers.addVertex3f("lightPos", new Vector3(-200, 0, -200), new Vector3(200, 100, 200), new Vector3(0, 80, 0)); Modifiers.addColor("lightColor", Color.White); Modifiers.addFloat("lightIntensity", 0, 150, 20); Modifiers.addFloat("lightAttenuation", 0.1f, 2, 0.3f); Modifiers.addFloat("specularEx", 0, 20, 9f); Modifiers.addColor("mEmissive", Color.Black); Modifiers.addColor("mAmbient", Color.White); Modifiers.addColor("mDiffuse", Color.White); Modifiers.addColor("mSpecular", Color.White); }
public override void Init() { //Cargar textura de CubeMap para Environment Map, fijo para todos los meshes cubeMap = TextureLoader.FromCubeFile(D3DDevice.Instance.Device, MediaDir + "CubeMap.dds"); //Cargar Shader personalizado de EnvironmentMap effect = TgcShaders.loadEffect(ShadersDir + "EnvironmentMap.fx"); //Cargar escenario, pero inicialmente solo hacemos el parser, para separar los objetos que son solo luces y no meshes var scenePath = MediaDir + "NormalMapRoom\\NormalMapRoom-TgcScene.xml"; var mediaPath = MediaDir + "NormalMapRoom\\"; var parser = new TgcSceneParser(); var sceneData = parser.parseSceneFromString(File.ReadAllText(scenePath)); //Separar modelos reales de las luces, segun layer "Lights" lights = new List <LightData>(); var realMeshData = new List <TgcMeshData>(); for (var i = 0; i < sceneData.meshesData.Length; i++) { var meshData = sceneData.meshesData[i]; //Es una luz, no cargar mesh, solo importan sus datos if (meshData.layerName == "Lights") { //Guardar datos de luz var light = new LightData(); light.color = Color.FromArgb((int)meshData.color[0], (int)meshData.color[1], (int)meshData.color[2]); light.aabb = new TgcBoundingAxisAlignBox(TgcParserUtils.float3ArrayToVector3(meshData.pMin), TgcParserUtils.float3ArrayToVector3(meshData.pMax)); light.pos = light.aabb.calculateBoxCenter(); lights.Add(light); } //Es un mesh real, agregar a array definitivo else { realMeshData.Add(meshData); } } //Reemplazar array original de meshData de sceneData por el definitivo sceneData.meshesData = realMeshData.ToArray(); //Ahora si cargar meshes reales var loader = new TgcSceneLoader(); var scene = loader.loadScene(sceneData, mediaPath); //Separar meshes con bumpMapping de los comunes bumpMeshes = new List <TgcMeshBumpMapping>(); commonMeshes = new List <TgcMesh>(); foreach (var mesh in scene.Meshes) { //Mesh con BumpMapping if (mesh.Layer == "BumpMap") { //Por convencion de este ejemplo el NormalMap se llama igual que el DiffuseMap (y cada mesh tiene una sola) var path = mesh.DiffuseMaps[0].FilePath; var split = path.Split('.'); path = split[0] + "." + split[1] + "_NormalMap.png"; //Convertir TgcMesh a TgcMeshBumpMapping var normalMap = TgcTexture.createTexture(path); TgcTexture[] normalMapArray = { normalMap }; var bumpMesh = TgcMeshBumpMapping.fromTgcMesh(mesh, normalMapArray); bumpMesh.Effect = effect; bumpMesh.Technique = "EnvironmentMapTechnique"; bumpMeshes.Add(bumpMesh); //Liberar original mesh.dispose(); } //Mesh normal else { commonMeshes.Add(mesh); } } //Camara en 1ra persona Camara = new TgcFpsCamera(new Vector3(0, 50, 100), Input); //Modifiers Modifiers.addFloat("reflection", 0, 1, 0.2f); Modifiers.addFloat("bumpiness", 0, 2, 1f); Modifiers.addFloat("lightIntensity", 0, 150, 20); Modifiers.addFloat("lightAttenuation", 0.1f, 2, 0.3f); Modifiers.addFloat("specularEx", 0, 20, 9f); Modifiers.addColor("mEmissive", Color.Black); Modifiers.addColor("mAmbient", Color.White); Modifiers.addColor("mDiffuse", Color.White); Modifiers.addColor("mSpecular", Color.White); }
public override void Init() { //Cargar textura de CubeMap para Environment Map cubeMap = TextureLoader.FromCubeFile(D3DDevice.Instance.Device, MediaDir + "CubeMap.dds"); //Crear 3 paredes y un piso con textura comun y textura de normalMap var diffuseMap = TgcTexture.createTexture(MediaDir + "Texturas//BM_DiffuseMap_pared.jpg"); var normalMap = TgcTexture.createTexture(MediaDir + "Texturas//BM_NormalMap.jpg"); TgcTexture[] normalMapArray = { normalMap }; var paredSur = TGCBox.fromExtremes(new TGCVector3(-200, 0, -210), new TGCVector3(200, 100, -200), diffuseMap); paredSur.Transform = TGCMatrix.Translation(paredSur.Position); var paredOeste = TGCBox.fromExtremes(new TGCVector3(-210, 0, -200), new TGCVector3(-200, 100, 200), diffuseMap); paredOeste.Transform = TGCMatrix.Translation(paredOeste.Position); var paredEste = TGCBox.fromExtremes(new TGCVector3(200, 0, -200), new TGCVector3(210, 100, 200), diffuseMap); paredEste.Transform = TGCMatrix.Translation(paredEste.Position); var piso = TGCBox.fromExtremes(new TGCVector3(-200, -1, -200), new TGCVector3(200, 0, 200), diffuseMap); piso.Transform = TGCMatrix.Translation(piso.Position); //Convertir TgcBox a TgcMesh var m1 = paredSur.ToMesh("paredSur"); var m2 = paredOeste.ToMesh("paredOeste"); var m3 = paredEste.ToMesh("paredEste"); var m4 = piso.ToMesh("piso"); //Convertir TgcMesh a TgcMeshBumpMapping meshes = new List <TgcMeshBumpMapping>(); meshes.Add(TgcMeshBumpMapping.fromTgcMesh(m1, normalMapArray)); meshes.Add(TgcMeshBumpMapping.fromTgcMesh(m2, normalMapArray)); meshes.Add(TgcMeshBumpMapping.fromTgcMesh(m3, normalMapArray)); meshes.Add(TgcMeshBumpMapping.fromTgcMesh(m4, normalMapArray)); //Borrar TgcMesh y TgcBox, ya no se usan paredSur.Dispose(); paredOeste.Dispose(); paredEste.Dispose(); piso.Dispose(); m1.Dispose(); m2.Dispose(); m3.Dispose(); m4.Dispose(); //Camara en 1ra persona Camera = new TgcFpsCamera(new TGCVector3(200, 60, 50), Input); //Cargar Shader personalizado para EnviromentMap effect = TGCShaders.Instance.LoadEffect(ShadersDir + "EnvironmentMap.fx"); //Cargar shader en meshes foreach (var m in meshes) { m.Effect = effect; m.Technique = "EnvironmentMapTechnique"; } //Mesh para la luz lightMesh = TGCBox.fromSize(new TGCVector3(10, 10, 10), Color.Red); reflectionModifier = AddFloat("reflection", 0, 1, 0.35f); bumpinessModifier = AddFloat("bumpiness", 0, 1, 1f); lightPosModifier = AddVertex3f("lightPos", new TGCVector3(-200, 0, -200), new TGCVector3(200, 100, 200), new TGCVector3(0, 80, 0)); lightColorModifier = AddColor("lightColor", Color.White); lightIntensityModifier = AddFloat("lightIntensity", 0, 150, 20); lightAttenuationModifier = AddFloat("lightAttenuation", 0.1f, 2, 0.3f); specularExModifier = AddFloat("specularEx", 0, 20, 9f); mEmissiveModifier = AddColor("mEmissive", Color.Black); mAmbientModifier = AddColor("mAmbient", Color.White); mDiffuseModifier = AddColor("mDiffuse", Color.White); mSpecularModifier = AddColor("mSpecular", Color.White); }
/// <summary> /// Crear un TgcMeshBumpMapping en base a un TgcMesh y su normalMap. /// Solo esta soportado un TgcMehs MeshRenderType = DiffuseMap /// </summary> public static TgcMeshBumpMapping fromTgcMesh(TgcMesh mesh, TgcTexture[] normalMaps) { if (mesh.RenderType != MeshRenderType.DIFFUSE_MAP) { throw new Exception("Solo esta soportado MeshRenderType = DiffuseMap"); } //Obtener vertexBuffer original var origVertexBuffer = (TgcSceneLoader.DiffuseMapVertex[])mesh.D3dMesh.LockVertexBuffer( typeof(TgcSceneLoader.DiffuseMapVertex), LockFlags.ReadOnly, mesh.D3dMesh.NumberVertices); mesh.D3dMesh.UnlockVertexBuffer(); //Crear nuevo Mesh de DirectX var triCount = origVertexBuffer.Length / 3; var d3dMesh = new Mesh(triCount, origVertexBuffer.Length, MeshFlags.Managed, BumpMappingVertexElements, D3DDevice.Instance.Device); //Calcular normales recorriendo los triangulos var normals = new TGCVector3[origVertexBuffer.Length]; for (var i = 0; i < normals.Length; i++) { normals[i] = TGCVector3.Empty; } for (var i = 0; i < triCount; i++) { //Los 3 vertices del triangulo var v1 = origVertexBuffer[i * 3]; var v2 = origVertexBuffer[i * 3 + 1]; var v3 = origVertexBuffer[i * 3 + 2]; //Face-normal (left-handend) var a = v2.Position - v1.Position; var b = v3.Position - v1.Position; var n = TGCVector3.Cross(a, b); //Acumular normal del vertice segun todas sus Face-normal normals[i * 3] += n; normals[i * 3 + 1] += n; normals[i * 3 + 2] += n; } //Normalizar normales for (var i = 0; i < normals.Length; i++) { normals[i] = TGCVector3.Normalize(normals[i]); } //Crear nuevo VertexBuffer using (var vb = d3dMesh.VertexBuffer) { //Iterar sobre triangulos var data = vb.Lock(0, 0, LockFlags.None); for (var i = 0; i < triCount; i++) { //Vertices originales var vOrig1 = origVertexBuffer[i * 3]; var vOrig2 = origVertexBuffer[i * 3 + 1]; var vOrig3 = origVertexBuffer[i * 3 + 2]; //Nuevo vertice 1 var v1 = new BumpMappingVertex(); v1.Position = vOrig1.Position; v1.Color = vOrig1.Color; v1.Tu = vOrig1.Tu; v1.Tv = vOrig1.Tv; v1.Normal = normals[i * 3]; //Nuevo vertice 2 var v2 = new BumpMappingVertex(); v2.Position = vOrig2.Position; v2.Color = vOrig2.Color; v2.Tu = vOrig2.Tu; v2.Tv = vOrig2.Tv; v2.Normal = normals[i * 3 + 1]; //Nuevo vertice 3 var v3 = new BumpMappingVertex(); v3.Position = vOrig3.Position; v3.Color = vOrig3.Color; v3.Tu = vOrig3.Tu; v3.Tv = vOrig3.Tv; v3.Normal = normals[i * 3 + 2]; //Calcular tangente y binormal para todo el triangulo y cargarlas en cada vertice TGCVector3 tangent; TGCVector3 binormal; computeTangentBinormal(v1, v2, v3, out tangent, out binormal); v1.Tangent = tangent; v1.Binormal = binormal; v2.Tangent = tangent; v2.Binormal = binormal; v3.Tangent = tangent; v3.Binormal = binormal; //Cargar VertexBuffer data.Write(v1); data.Write(v2); data.Write(v3); } vb.Unlock(); } //Cargar IndexBuffer en forma plana using (var ib = d3dMesh.IndexBuffer) { var indices = new short[origVertexBuffer.Length]; for (var i = 0; i < indices.Length; i++) { indices[i] = (short)i; } ib.SetData(indices, 0, LockFlags.None); } //Clonar texturas y materials var diffuseMaps = new TgcTexture[mesh.DiffuseMaps.Length]; var materials = new Material[mesh.Materials.Length]; for (var i = 0; i < mesh.DiffuseMaps.Length; i++) { diffuseMaps[i] = mesh.DiffuseMaps[i].Clone(); materials[i] = D3DDevice.DEFAULT_MATERIAL; } //Cargar attributeBuffer if (diffuseMaps.Length > 1) { var origAttributeBuffer = mesh.D3dMesh.LockAttributeBufferArray(LockFlags.None); var newAttributeBuffer = d3dMesh.LockAttributeBufferArray(LockFlags.None); Array.Copy(origAttributeBuffer, newAttributeBuffer, origAttributeBuffer.Length); mesh.D3dMesh.UnlockAttributeBuffer(); d3dMesh.UnlockAttributeBuffer(newAttributeBuffer); } //Crear mesh de BumpMapping Mesh var bumpMesh = new TgcMeshBumpMapping(d3dMesh, mesh.Name, mesh.RenderType); bumpMesh.diffuseMaps = diffuseMaps; bumpMesh.materials = materials; bumpMesh.NormalMaps = normalMaps; bumpMesh.layer = mesh.Layer; bumpMesh.AlphaBlendEnable = mesh.AlphaBlendEnable; bumpMesh.UserProperties = mesh.UserProperties; bumpMesh.boundingBox = mesh.BoundingBox.clone(); bumpMesh.enabled = true; return(bumpMesh); }