/// <summary> /// Adds a renderable mesh using this technique. /// </summary> /// <param name="addMesh">Add mesh</param> public void Add(RenderableMesh addMesh) { // Make sure this mesh uses the correct material if (addMesh.usedTechnique != technique) { throw new ArgumentException("Invalid technique, to add a mesh to " + "MeshesPerMaterialPerTechniques it must use the specified " + "technique=" + technique.Name); } // Search for the used material, maybe we have it already in list. for (int listNum = 0; listNum < meshesPerMaterials.Count; listNum++) { MeshesPerMaterial existingList = meshesPerMaterials[listNum]; if (existingList.material == addMesh.material) { // Just add existingList.Add(addMesh); return; } } // Not found, create new list and add mesh there. MeshesPerMaterial newList = new MeshesPerMaterial(addMesh.material); newList.Add(addMesh); meshesPerMaterials.Add(newList); }
public Cube() { _simpleMaterial = new SimpleMaterial(); var resourceAllocator = new ResourceAllocator(new OpenGlResourceFactory()); _simpleMaterial.Create(); var mesh = MeshCreator.CreateXZGrid(10, 10); _renderable = resourceAllocator.AllocateResourceFor(mesh); _renderable.CreateVAO(); }
/// <summary> /// Adds a renderable mesh using this material. /// </summary> /// <param name="addMesh">Add mesh</param> public void Add(RenderableMesh addMesh) { // Make sure this mesh uses the correct material if (addMesh.material != material) { throw new ArgumentException("Invalid material, to add a mesh to " + "MeshesPerMaterial it must use the specified material=" + material); } meshes.Add(addMesh); }
public void ComputeCoverage(RenderableMesh mesh, AABBf meshBounds, out long sideCoverage, out long topCoverage) { float longestSide = Math.Max(Math.Max(meshBounds.MaxX - meshBounds.MinX, meshBounds.MaxY - meshBounds.MinY), meshBounds.MaxZ - meshBounds.MinZ); float farPlane = longestSide * 2.0f; float x = (meshBounds.MinX + meshBounds.MaxX) / 2.0f; float y = meshBounds.MinY; float z = (meshBounds.MinZ + meshBounds.MaxZ) / 2.0f; Vector3 origin = new Vector3(x, y, z); Vector3 up = Vector3.UnitY; Vector3 look = -Vector3.UnitX; for (int i = 0; i < m_occlusionQueries.Length; i++) { Matrix4 orbit = Matrix4.CreateRotationY(MathHelper.DegreesToRadians((365 / 64.0f) * i)); Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(90), 1.0f, 0.1f, farPlane); Matrix4 view = Matrix4.LookAt(origin + Vector3.Transform(new Vector3(longestSide, 0, 0), orbit), origin, Vector3.TransformNormal(up, orbit)); RenderView(view, projection, mesh, m_occlusionQueries[i]); //Bitmap bmp = GLEx.BitmapColorBuffer(m_pixelWidth, m_pixelHeight); //bmp.Save("C:\\test_" + i + ".bmp"); } // Gather all the occlusion queries we performed long[] m_occlusionQueryResults = new long[64]; for (int i = 0; i < m_occlusionQueries.Length; i++) { int ready = 0; while (ready == 0) { GL.GetQueryObject(m_occlusionQueries[i], GetQueryObjectParam.QueryResultAvailable, out ready); } GL.GetQueryObject(m_occlusionQueries[i], GetQueryObjectParam.QueryResult, out m_occlusionQueryResults[i]); } // Reset the current frame buffer. GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0); long totalSidePixels = 0; long totalTopPixels = 0; for (int i = 0; i < m_occlusionQueries.Length; i++) { totalSidePixels += m_occlusionQueryResults[i]; } sideCoverage = totalSidePixels; topCoverage = totalTopPixels; }
} // Add(vertexBuffer, indexBuffer, part) #endregion #region Render /// <summary> /// Render all meshes we collected this frame sorted by techniques /// and materials. This method is about 3-5 times faster than just /// using Model's Mesh.Draw method (see commented out code there). /// The reason for that is that we require only very few state changes /// and render everthing down as fast as we can. The only optimization /// left would be to put vertices of several meshes together if they /// are static and use the same technique and material. But since /// meshes have WriteOnly vertex and index buffers, we can't do that /// without using a custom model format. /// </summary> public void Render() { // Copy over last frame's object to this frame for (int listNum = 0; listNum < sortedMeshes.Count; listNum++) { MeshesPerMaterialPerTechniques list = sortedMeshes[listNum]; for (int meshNum = 0; meshNum < list.meshesPerMaterials.Count; meshNum++) { MeshesPerMaterial list2 = list.meshesPerMaterials[meshNum]; for (int num = 0; num < list2.meshes.Count; num++) { RenderableMesh mesh = list2.meshes[num]; // Copy over last frame matrices for rendering now! mesh.lastFrameRenderMatricesAndAlpha = mesh.thisFrameRenderMatricesAndAlpha; // Clear list for this frame mesh.thisFrameRenderMatricesAndAlpha = new List <MatrixAndAlpha>(); } // for } // for } // for // Make sure z buffer is on for 3D content BaseGame.Device.RenderState.DepthBufferEnable = true; BaseGame.Device.RenderState.DepthBufferWriteEnable = true; // We always use the normalMapping shader here. Effect effect = BaseGame.ParallaxShader.Effect; // Set general parameters for the shader BaseGame.ParallaxShader.SetParametersOptimizedGeneral(); // Don't set vertex buffer again if it does not change this frame. // Clear these remember settings. lastVertexBufferSet = null; lastIndexBufferSet = null; //obs: foreach (MeshesPerMaterialPerTechniques list in sortedMeshes) for (int listNum = 0; listNum < sortedMeshes.Count; listNum++) { MeshesPerMaterialPerTechniques list = sortedMeshes[listNum]; if (list.NumberOfRenderMatrices > 0) { list.Render(effect); } } // for (listNum) } // Render()
public void Dispose() { GC.SuppressFinalize(this); if (OriginalMesh != null) { OriginalMesh.Dispose(); OriginalMesh = null; } if (OccluderMesh != null) { OccluderMesh.Dispose(); OccluderMesh = null; } }
void AddSphere() { scene.Root.AddChildren(node = new Node(new StringBuilder("Sphere"))); sphereMesh = new RenderableMesh(editorEngine, GeometryFactory.CreateSphere(editorEngine, 3, 5)); node.AddRenderable(sphereMesh); Material material = new Material("earth"); MaterialLayer layer = material.CreateLayer(); layer.DiffuseMap = editorEngine.Textures.CreateTexture2DFromFile(new StringBuilder("earth")); sphereMesh.Material = material; }
} // Render() #endregion #region ClearAll /// <summary> /// Clear all objects in the render list in case our device got lost. /// </summary> public void ClearAll() { // Copy over last frame's object to this frame for (int listNum = 0; listNum < sortedMeshes.Count; listNum++) { MeshesPerMaterialPerTechniques list = sortedMeshes[listNum]; for (int meshNum = 0; meshNum < list.meshesPerMaterials.Count; meshNum++) { MeshesPerMaterial list2 = list.meshesPerMaterials[meshNum]; for (int num = 0; num < list2.meshes.Count; num++) { RenderableMesh mesh = list2.meshes[num]; // Clear all mesh.lastFrameRenderMatricesAndAlpha.Clear(); mesh.thisFrameRenderMatricesAndAlpha.Clear(); } // for } // for } // for } // ClearAll()
} // Add(addMesh) #endregion #region Render /// <summary> /// Render all meshes that use this material. /// This method is only called if we got any meshes to render, /// which is determinated if NumberOfRenderMeshes is greater 0. /// </summary> public void Render() { // Set material settings. We don't have to update the shader here, // it will be done in RenderableMesh.Render anyway because of // updating the world matrix! BaseGame.ParallaxShader.SetParametersOptimized(material); // Set vertex declaration BaseGame.Device.VertexDeclaration = meshes[0].vertexDeclaration; // Render all meshes that use this material. //obs: foreach (RenderableMesh mesh in meshes) for (int meshNum = 0; meshNum < meshes.Count; meshNum++) { RenderableMesh mesh = meshes[meshNum]; if (mesh.lastFrameRenderMatricesAndAlpha.Count > 0) { mesh.Render(); } } // for (meshNum) } // Render()
/// <summary> /// Render all meshes that use this material. /// This method is only called if we got any meshes to render, /// which is determinated if NumberOfRenderMeshes is greater 0. /// </summary> public void Render() { // Set material settings. We don't have to update the shader here, // it will be done in RenderableMesh.Render anyway because of // updating the world matrix! ShaderEffect.normalMapping.SetParametersOptimized(material); // Set vertex declaration //always true: if (meshes.Count > 0) // Enable alpha if this material uses alpha if (material.HasAlpha) { //TODO: AlphaTestEffect //BaseGame.Device.RenderState.AlphaTestEnable = true; //BaseGame.Device.RenderState.ReferenceAlpha = 128; // Make 2sided, we use alpha mainly for our palms. BaseGame.Device.RasterizerState = RasterizerState.CullNone; } // Render all meshes that use this material. for (int meshNum = 0; meshNum < meshes.Count; meshNum++) { RenderableMesh mesh = meshes[meshNum]; if (mesh.renderMatrices.Count > 0) { mesh.Render(); } } // Disable alpha testing again and restore culling if (material.HasAlpha) { //TODO: AlphaTestEffect //BaseGame.Device.RenderState.AlphaTestEnable = false; BaseGame.Device.RasterizerState = RasterizerState.CullCounterClockwise; } }
private void DrawOverlay(RenderableMesh orignalMesh, RenderableMesh occluderMesh) { GL.PushAttrib(AttribMask.AllAttribBits); GL.Color4(1.0f, 1.0f, 1.0f, 1.0f); GL.Enable(EnableCap.Texture2D); GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); GL.DepthFunc(DepthFunction.Lequal); QFont.Begin(); float yOffset = 5; if (orignalMesh != null) PrintCode(String.Format("Orignal Triangles : {0,5}", orignalMesh.Triangles), ref yOffset); if (occluderMesh != null) PrintCode(String.Format("Occluder Triangles : {0,5}", occluderMesh.Triangles), ref yOffset); PrintCode(String.Format("Occluder Levels : {0,5}", m_visualizedMaxLevel), ref yOffset); if (m_operations.Context.VoxelizationOutput != null) { PrintCode(String.Format("Volume Coverage : {0,5:0.##}%", (100 * m_operations.Context.VoxelizationOutput.VolumeCoverage)), ref yOffset); PrintCode(String.Format("Silhouette Coverage : {0,5:0.##}%", (100 * m_operations.Context.VoxelizationOutput.SilhouetteCoverage)), ref yOffset); PrintCode(String.Format("Time Taken : {0,5:0.##} seconds", m_operations.Context.VoxelizationOutput.TimeTaken.TotalSeconds), ref yOffset); } QFont.End(); GL.PopAttrib(); }
/// <summary> /// Add model mesh part with the used effect to our sortedMeshes list. /// Neither the model mesh part nor the effect is directly used, /// we will extract all data from the model and only render the /// index and vertex buffers later. /// The model mesh part must use the TangentVertex format. /// </summary> /// <param name="vertexBuffer">Vertex buffer</param> /// <param name="indexBuffer">Index buffer</param> /// <param name="part">Part</param> /// <param name="effect">Effect</param> /// <returns>Renderable mesh</returns> public RenderableMesh Add(VertexBuffer vertexBuffer, IndexBuffer indexBuffer, ModelMeshPart part, Effect effect) { string techniqueName = effect.CurrentTechnique.Name; // Does this technique already exists? MeshesPerMaterialPerTechniques foundList = null; for (int listNum = 0; listNum < sortedMeshes.Count; listNum++) { MeshesPerMaterialPerTechniques list = sortedMeshes[listNum]; if (list.technique.Name == techniqueName) { foundList = list; break; } } // Did not found list? Create new one if (foundList == null) { foundList = new MeshesPerMaterialPerTechniques( ShaderEffect.normalMapping.GetTechnique(techniqueName)); sortedMeshes.Add(foundList); } // Create new material from the current effect parameters. // This will create duplicate materials if the same material is used // multiple times, we check this later. Material material = new Material(effect); // Search for material inside foundList. for (int innerListNum = 0; innerListNum < foundList.meshesPerMaterials.Count; innerListNum++) { MeshesPerMaterial innerList = foundList.meshesPerMaterials[innerListNum]; // Check if this is the same material and we can use it instead. // For our purposes it is sufficiant if we check textures and colors. if (innerList.material.diffuseTexture == material.diffuseTexture && innerList.material.normalTexture == material.normalTexture && innerList.material.ambientColor == material.ambientColor && innerList.material.diffuseColor == material.diffuseColor && innerList.material.specularColor == material.specularColor && innerList.material.specularPower == material.specularPower) { // Reuse this material and quit this search material = innerList.material; break; } } // Build new RenderableMesh object RenderableMesh mesh = new RenderableMesh( vertexBuffer, indexBuffer, material, foundList.technique, ShaderEffect.normalMapping.WorldParameter, part.VertexDeclaration, part.StreamOffset, part.VertexStride, part.BaseVertex, part.NumVertices, part.StartIndex, part.PrimitiveCount); foundList.Add(mesh); return(mesh); }
/// <summary> /// Add model mesh part with the used effect to our sortedMeshes list. /// Neither the model mesh part nor the effect is directly used, /// we will extract all data from the model and only render the /// index and vertex buffers later. /// The model mesh part must use the TangentVertex format. /// </summary> /// <param name="vertexBuffer">Vertex buffer</param> /// <param name="indexBuffer">Index buffer</param> /// <param name="part">Part</param> /// <param name="effect">Effect</param> /// <returns>Renderable mesh</returns> public RenderableMesh Add(VertexBuffer vertexBuffer, IndexBuffer indexBuffer, ModelMeshPart part, Effect effect) { string techniqueName = effect.CurrentTechnique.Name; // Does this technique already exists? MeshesPerMaterialPerTechniques foundList = null; //obs: foreach (MeshesPerMaterialPerTechniques list in sortedMeshes) for (int listNum = 0; listNum < sortedMeshes.Count; listNum++) { MeshesPerMaterialPerTechniques list = sortedMeshes[listNum]; if (list.technique != null && list.technique.Name == techniqueName) { foundList = list; break; } // if (list.technique.Name) } // for (listNum) // Did not found list? Create new one if (foundList == null) { EffectTechnique technique = BaseGame.ParallaxShader.GetTechnique(techniqueName); // Make sure we always have a valid technique if (technique == null) { if (BaseGame.CanUsePS20) { techniqueName = "Diffuse20"; //"Specular20"; } else { techniqueName = "Diffuse"; //"Specular"; } technique = BaseGame.ParallaxShader.GetTechnique(techniqueName); } // if foundList = new MeshesPerMaterialPerTechniques(technique); sortedMeshes.Add(foundList); } // if (foundList) // Create new material from the current effect parameters. // This will create duplicate materials if the same material is used // multiple times, we check this later. Material material = new Material(effect); // Search for material inside foundList. //obs: foreach (MeshesPerMaterial innerList in foundList.meshesPerMaterials) for (int innerListNum = 0; innerListNum < foundList.meshesPerMaterials.Count; innerListNum++) { MeshesPerMaterial innerList = foundList.meshesPerMaterials[innerListNum]; // Check if this is the same material and we can use it instead. // For our purposes it is sufficiant if we check textures and colors. if (innerList.material.diffuseTexture == material.diffuseTexture && innerList.material.normalTexture == material.normalTexture && innerList.material.ambientColor == material.ambientColor && innerList.material.diffuseColor == material.diffuseColor && innerList.material.specularColor == material.specularColor && innerList.material.specularPower == material.specularPower) { // Reuse this material and quit this search material = innerList.material; break; } // if (innerList.material.diffuseTexture) } // foreach (innerList) // Build new RenderableMesh object RenderableMesh mesh = new RenderableMesh( vertexBuffer, indexBuffer, material, foundList.technique, part.VertexDeclaration, part.StreamOffset, part.VertexStride, part.BaseVertex, part.NumVertices, part.StartIndex, part.PrimitiveCount); foundList.Add(mesh); return(mesh); } // Add(vertexBuffer, indexBuffer, part)
private void BuildRenderableMeshes(Model model) { List<short> indices = new List<short>(); List<InstancedVertexPositionNormalTextureBumpSkin> vertices = new List<InstancedVertexPositionNormalTextureBumpSkin>(); Dictionary<int, int> indexRemap = new Dictionary<int, int>(); // Get the model transforms for baking down vertices into object space (XNA Models are stored in mesh space). Matrix[] boneArray = new Matrix[model.Bones.Count]; model.CopyAbsoluteBoneTransformsTo(boneArray); foreach (ModelMesh modelMesh in model.Meshes) { Debug.WriteLine("Building " + modelMesh.Name); Matrix meshToObject = boneArray[modelMesh.ParentBone.Index]; for(int p=0;p<modelMesh.MeshParts.Count;p++) { ModelMeshPart modelMeshPart = modelMesh.MeshParts[p]; int vertexCount = modelMeshPart.VertexBuffer.VertexCount; int indexCount = modelMeshPart.IndexBuffer.IndexCount; indexRemap.Clear(); vertices.Clear(); indices.Clear(); // Create a material for this meshpart // TODO: Group data by effects DeferredSasEffect partEffect = (DeferredSasEffect)_sourceEffect.Clone(); partEffect.Parameters["AnimationTexture"].SetValue(_animationTexture); partEffect.Parameters["BoneDelta"].SetValue(1f / _animationTexture.Width); partEffect.Parameters["RowDelta"].SetValue(1f / _animationTexture.Height); DeferredObjectEffect effect = (DeferredObjectEffect) modelMeshPart.Effect; partEffect.Parameters["DiffuseTexture"].SetValue(effect.DiffuseMapTexture); short[] sourceIndices = new short[modelMeshPart.PrimitiveCount*3]; modelMeshPart.IndexBuffer.GetData<short>(modelMeshPart.StartIndex*2,sourceIndices,0,modelMeshPart.PrimitiveCount*3); InstancedVertexPositionNormalTextureBumpSkin[] sourceVertices = new InstancedVertexPositionNormalTextureBumpSkin[modelMeshPart.NumVertices]; modelMeshPart.VertexBuffer.GetData<InstancedVertexPositionNormalTextureBumpSkin>(modelMeshPart.VertexOffset * modelMeshPart.VertexBuffer.VertexDeclaration.VertexStride, sourceVertices, 0, modelMeshPart.NumVertices, modelMeshPart.VertexBuffer.VertexDeclaration.VertexStride); for (int instance = 0; instance < _maxInstances; instance++) { for (int i = 0; i < sourceIndices.Length; i++) { indices.Add((short) ((sourceIndices[i]) + (instance * sourceVertices.Length))) ; } for (int i = 0; i < sourceVertices.Length; i++) { sourceVertices[i].TextureCoordinate2 = new Vector2(instance, 0); vertices.Add(sourceVertices[i]); } } VertexBuffer vertexBuffer = new VertexBuffer(_graphicsDevice, typeof(InstancedVertexPositionNormalTextureBumpSkin), vertices.Count, BufferUsage.None); vertexBuffer.SetData<InstancedVertexPositionNormalTextureBumpSkin>(vertices.ToArray()); IndexBuffer indexBuffer = new IndexBuffer(_graphicsDevice, IndexElementSize.SixteenBits, indices.Count, BufferUsage.None); indexBuffer.SetData<short>(indices.ToArray()); RenderableMesh renderableMesh = new RenderableMesh(); renderableMesh.Build(this, partEffect, Matrix.Identity, _boundingSphere, _boundingBox, indexBuffer, vertexBuffer, 0, PrimitiveType.TriangleList, indexBuffer.IndexCount / 3, 0, vertexBuffer.VertexCount, 0, true); base.Add(renderableMesh); } } }
/// <summary> /// Adds a renderable mesh using this technique. /// </summary> /// <param name="addMesh">Add mesh</param> public void Add(RenderableMesh addMesh) { // Make sure this mesh uses the correct material if (addMesh.usedTechnique != technique) throw new Exception("Invalid technique, to add a mesh to "+ "MeshesPerMaterialPerTechniques it must use the specified "+ "technique="+technique.Name); // Search for the used material, maybe we have it already in list. //obs: foreach (MeshesPerMaterial list in meshesPerMaterials) for (int listNum = 0; listNum < meshesPerMaterials.Count; listNum++) { MeshesPerMaterial existingList = meshesPerMaterials[listNum]; if (existingList.material == addMesh.material) { // Just add existingList.Add(addMesh); return; } // if (existingList.material) } // for (listNum) // Not found, create new list and add mesh there. MeshesPerMaterial newList = new MeshesPerMaterial(addMesh.material); newList.Add(addMesh); meshesPerMaterials.Add(newList); }
long MeasureOccluderOcclusion(SilhouetteOcclusionValidator sov, VoxelizationInput input, List<AABBi> occluderBounds) { Mesh mesh = BuildMeshFromBoxes(input, occluderBounds); RenderableMesh renderable = new RenderableMesh(mesh, true); long sideCoverage, topCoverage; sov.ComputeCoverage(renderable, input.Octree.MeshBounds, out sideCoverage, out topCoverage); renderable.Dispose(); return sideCoverage + topCoverage; }
private void BuildRenderableMeshes(Model model) { List <short> indices = new List <short>(); List <InstancedVertexPositionNormalTextureBumpSkin> vertices = new List <InstancedVertexPositionNormalTextureBumpSkin>(); Dictionary <int, int> indexRemap = new Dictionary <int, int>(); // Get the model transforms for baking down vertices into object space (XNA Models are stored in mesh space). Matrix[] boneArray = new Matrix[model.Bones.Count]; model.CopyAbsoluteBoneTransformsTo(boneArray); foreach (ModelMesh modelMesh in model.Meshes) { Debug.WriteLine("Building " + modelMesh.Name); Matrix meshToObject = boneArray[modelMesh.ParentBone.Index]; for (int p = 0; p < modelMesh.MeshParts.Count; p++) { ModelMeshPart modelMeshPart = modelMesh.MeshParts[p]; int vertexCount = modelMeshPart.VertexBuffer.VertexCount; int indexCount = modelMeshPart.IndexBuffer.IndexCount; indexRemap.Clear(); vertices.Clear(); indices.Clear(); // Create a material for this meshpart // TODO: Group data by effects DeferredSasEffect partEffect = (DeferredSasEffect)_sourceEffect.Clone(); partEffect.Parameters["AnimationTexture"].SetValue(_animationTexture); partEffect.Parameters["BoneDelta"].SetValue(1f / _animationTexture.Width); partEffect.Parameters["RowDelta"].SetValue(1f / _animationTexture.Height); DeferredObjectEffect effect = (DeferredObjectEffect)modelMeshPart.Effect; partEffect.Parameters["DiffuseTexture"].SetValue(effect.DiffuseMapTexture); short[] sourceIndices = new short[modelMeshPart.PrimitiveCount * 3]; modelMeshPart.IndexBuffer.GetData <short>(modelMeshPart.StartIndex * 2, sourceIndices, 0, modelMeshPart.PrimitiveCount * 3); InstancedVertexPositionNormalTextureBumpSkin[] sourceVertices = new InstancedVertexPositionNormalTextureBumpSkin[modelMeshPart.NumVertices]; modelMeshPart.VertexBuffer.GetData <InstancedVertexPositionNormalTextureBumpSkin>(modelMeshPart.VertexOffset * modelMeshPart.VertexBuffer.VertexDeclaration.VertexStride, sourceVertices, 0, modelMeshPart.NumVertices, modelMeshPart.VertexBuffer.VertexDeclaration.VertexStride); for (int instance = 0; instance < _maxInstances; instance++) { for (int i = 0; i < sourceIndices.Length; i++) { indices.Add((short)((sourceIndices[i]) + (instance * sourceVertices.Length))); } for (int i = 0; i < sourceVertices.Length; i++) { sourceVertices[i].TextureCoordinate2 = new Vector2(instance, 0); vertices.Add(sourceVertices[i]); } } VertexBuffer vertexBuffer = new VertexBuffer(_graphicsDevice, typeof(InstancedVertexPositionNormalTextureBumpSkin), vertices.Count, BufferUsage.None); vertexBuffer.SetData <InstancedVertexPositionNormalTextureBumpSkin>(vertices.ToArray()); IndexBuffer indexBuffer = new IndexBuffer(_graphicsDevice, IndexElementSize.SixteenBits, indices.Count, BufferUsage.None); indexBuffer.SetData <short>(indices.ToArray()); RenderableMesh renderableMesh = new RenderableMesh(); renderableMesh.Build(this, partEffect, Matrix.Identity, _boundingSphere, _boundingBox, indexBuffer, vertexBuffer, 0, PrimitiveType.TriangleList, indexBuffer.IndexCount / 3, 0, vertexBuffer.VertexCount, 0, true); base.Add(renderableMesh); } } }
/// <summary> /// Adds a renderable mesh using this material. /// </summary> /// <param name="addMesh">Add mesh</param> public void Add(RenderableMesh addMesh) { // Make sure this mesh uses the correct material if (addMesh.material != material) throw new Exception("Invalid material, to add a mesh to "+ "MeshesPerMaterial it must use the specified material="+ material); meshes.Add(addMesh); }
private void RenderView(Matrix4 worldViewMatrix, Matrix4 projMatrix, RenderableMesh mesh, int occlusionQueryHandle) { // Setup VBO state GL.EnableClientState(ArrayCap.VertexArray); GL.EnableClientState(ArrayCap.IndexArray); GL.Enable(EnableCap.StencilTest); GL.StencilFunc(StencilFunction.Always, 1, 1); GL.StencilOp(StencilOp.Keep, StencilOp.Keep, StencilOp.Replace); GL.PushAttrib(AttribMask.ViewportBit); GL.Viewport(0, 0, m_pixelWidth, m_pixelHeight); GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, m_fboHandle); // since there's only 1 Color buffer attached this is not explicitly required GL.DrawBuffer((DrawBufferMode)FramebufferAttachment.ColorAttachment0Ext); GL.Ext.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext, TextureTarget.Texture2D, m_colorTextureHandle, 0); GL.Ext.FramebufferRenderbuffer(FramebufferTarget.FramebufferExt, FramebufferAttachment.DepthAttachmentExt, RenderbufferTarget.RenderbufferExt, m_renderbufferHandle); GL.Ext.FramebufferRenderbuffer(FramebufferTarget.FramebufferExt, FramebufferAttachment.StencilAttachmentExt, RenderbufferTarget.RenderbufferExt, m_renderbufferHandle); GL.ClearColor(0.0f, 0.0f, 0.0f, 0.0f); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit); GL.PushMatrix(); GL.MatrixMode(MatrixMode.Modelview); GL.LoadMatrix(ref worldViewMatrix); GL.MatrixMode(MatrixMode.Projection); GL.LoadMatrix(ref projMatrix); GL.Enable(EnableCap.DepthTest); GL.Disable(EnableCap.CullFace); var effect = new Material(); effect.ShaderHandle = 0; effect.ShowLines = false; GL.Color4(1.0f, 1.0f, 1.0f, 1.0f); mesh.Render(effect); GL.PopMatrix(); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); // Render a quad with stencil test turned on, this will give me an accurate number of pixels rendered for // the object. GL.StencilFunc(StencilFunction.Equal, 1, 1); GL.StencilOp(StencilOp.Keep, StencilOp.Keep, StencilOp.Keep); GL.MatrixMode(MatrixMode.Modelview); GL.LoadIdentity(); GL.MatrixMode(MatrixMode.Projection); GL.LoadIdentity(); GL.Ortho(0, 1, 1, 0, -1, 1); GL.Disable(EnableCap.DepthTest); GL.BeginQuery(QueryTarget.SamplesPassed, occlusionQueryHandle); GL.Color4(1.0f, 1.0f, 1.0f, 1.0f); GL.Begin(BeginMode.Quads); GL.TexCoord2(0f, 1f); GL.Vertex2(0f, 0f); GL.TexCoord2(1f, 1f); GL.Vertex2(1f, 0f); GL.TexCoord2(1f, 0f); GL.Vertex2(1f, 1f); GL.TexCoord2(0f, 0f); GL.Vertex2(0f, 1f); GL.End(); GL.EndQuery(QueryTarget.SamplesPassed); GL.Enable(EnableCap.DepthTest); GL.Disable(EnableCap.StencilTest); GL.PopAttrib(); }
/// <summary> /// Add model mesh part with the used effect to our sortedMeshes list. /// Neither the model mesh part nor the effect is directly used, /// we will extract all data from the model and only render the /// index and vertex buffers later. /// The model mesh part must use the TangentVertex format. /// </summary> /// <param name="vertexBuffer">Vertex buffer</param> /// <param name="indexBuffer">Index buffer</param> /// <param name="part">Part</param> /// <param name="effect">Effect</param> /// <returns>Renderable mesh</returns> public RenderableMesh Add(VertexBuffer vertexBuffer, IndexBuffer indexBuffer, ModelMeshPart part, Effect effect) { string techniqueName = effect.CurrentTechnique.Name; // Does this technique already exists? MeshesPerMaterialPerTechniques foundList = null; //obs: foreach (MeshesPerMaterialPerTechniques list in sortedMeshes) for (int listNum = 0; listNum < sortedMeshes.Count; listNum++) { MeshesPerMaterialPerTechniques list = sortedMeshes[listNum]; if (list.technique != null && list.technique.Name == techniqueName) { foundList = list; break; } // if (list.technique.Name) } // for (listNum) // Did not found list? Create new one if (foundList == null) { EffectTechnique technique = BaseGame.ParallaxShader.GetTechnique(techniqueName); // Make sure we always have a valid technique if (technique == null) { if (BaseGame.CanUsePS20) techniqueName = "Diffuse20";//"Specular20"; else techniqueName = "Diffuse";//"Specular"; technique = BaseGame.ParallaxShader.GetTechnique(techniqueName); } // if foundList = new MeshesPerMaterialPerTechniques(technique); sortedMeshes.Add(foundList); } // if (foundList) // Create new material from the current effect parameters. // This will create duplicate materials if the same material is used // multiple times, we check this later. Material material = new Material(effect); // Search for material inside foundList. //obs: foreach (MeshesPerMaterial innerList in foundList.meshesPerMaterials) for (int innerListNum = 0; innerListNum < foundList.meshesPerMaterials.Count; innerListNum++) { MeshesPerMaterial innerList = foundList.meshesPerMaterials[innerListNum]; // Check if this is the same material and we can use it instead. // For our purposes it is sufficiant if we check textures and colors. if (innerList.material.diffuseTexture == material.diffuseTexture && innerList.material.normalTexture == material.normalTexture && innerList.material.ambientColor == material.ambientColor && innerList.material.diffuseColor == material.diffuseColor && innerList.material.specularColor == material.specularColor && innerList.material.specularPower == material.specularPower) { // Reuse this material and quit this search material = innerList.material; break; } // if (innerList.material.diffuseTexture) } // foreach (innerList) // Build new RenderableMesh object RenderableMesh mesh = new RenderableMesh( vertexBuffer, indexBuffer, material, foundList.technique, part.VertexDeclaration, part.StreamOffset, part.VertexStride, part.BaseVertex, part.NumVertices, part.StartIndex, part.PrimitiveCount); foundList.Add(mesh); return mesh; }
/// <summary> /// Add model mesh part with the used effect to our sortedMeshes list. /// Neither the model mesh part nor the effect is directly used, /// we will extract all data from the model and only render the /// index and vertex buffers later. /// The model mesh part must use the TangentVertex format. /// </summary> /// <param name="vertexBuffer">Vertex buffer</param> /// <param name="indexBuffer">Index buffer</param> /// <param name="part">Part</param> /// <param name="effect">Effect</param> /// <returns>Renderable mesh</returns> public RenderableMesh Add(VertexBuffer vertexBuffer, IndexBuffer indexBuffer, ModelMeshPart part, Effect effect) { string techniqueName = effect.CurrentTechnique.Name; // Does this technique already exists? MeshesPerMaterialPerTechniques foundList = null; for (int listNum = 0; listNum < sortedMeshes.Count; listNum++) { MeshesPerMaterialPerTechniques list = sortedMeshes[listNum]; if (list.technique.Name == techniqueName) { foundList = list; break; } } // Did not found list? Create new one if (foundList == null) { foundList = new MeshesPerMaterialPerTechniques( ShaderEffect.normalMapping.GetTechnique(techniqueName)); sortedMeshes.Add(foundList); } // Create new material from the current effect parameters. // This will create duplicate materials if the same material is used // multiple times, we check this later. Material material = new Material(effect); // Search for material inside foundList. for (int innerListNum = 0; innerListNum < foundList.meshesPerMaterials.Count; innerListNum++) { MeshesPerMaterial innerList = foundList.meshesPerMaterials[innerListNum]; // Check if this is the same material and we can use it instead. // For our purposes it is sufficiant if we check textures and colors. if (innerList.material.diffuseTexture == material.diffuseTexture && innerList.material.normalTexture == material.normalTexture && innerList.material.ambientColor == material.ambientColor && innerList.material.diffuseColor == material.diffuseColor && innerList.material.specularColor == material.specularColor && innerList.material.specularPower == material.specularPower) { // Reuse this material and quit this search material = innerList.material; break; } } // Build new RenderableMesh object RenderableMesh mesh = new RenderableMesh( vertexBuffer, indexBuffer, material, foundList.technique, ShaderEffect.normalMapping.WorldParameter, part.VertexOffset, part.NumVertices, part.StartIndex, part.PrimitiveCount); foundList.Add(mesh); return mesh; }