Beispiel #1
0
        public unsafe bool UpdateSimpleMaterialBGFX(RendererBGFXInstance *sys, ref SimpleMaterial mat, ref SimpleMaterialBGFX matBGFX, bool srgbColors)
        {
            // if constants changed, need to update packed value
            matBGFX.constAlbedo_Opacity = srgbColors ?
                                          new float4(Color.LinearToSRGB(mat.constAlbedo), mat.constOpacity) :
                                          new float4(mat.constAlbedo, mat.constOpacity);
            // if texture entity OR load state changed need to update texture handles
            // content of texture change should transparently update texture referenced by handle
            bool stillLoading = false;

            if (InitTexture(ref matBGFX.texAlbedoOpacity, mat.texAlbedoOpacity, sys->m_whiteTexture))
            {
                stillLoading = true;
            }

            // if twoSided or hasalpha changed, need to update state
            matBGFX.state = (ulong)(bgfx.StateFlags.WriteRgb | bgfx.StateFlags.WriteA | bgfx.StateFlags.DepthTestLess);
            if (!mat.twoSided && !mat.billboarded)
            {
                matBGFX.state |= (ulong)bgfx.StateFlags.CullCw;
            }
            if (mat.transparent)
            {
                matBGFX.state |= RendererBGFXStatic.MakeBGFXBlend(bgfx.StateFlags.BlendOne, bgfx.StateFlags.BlendInvSrcAlpha);
            }
            else
            {
                matBGFX.state |= (ulong)bgfx.StateFlags.WriteZ;
            }
            matBGFX.mainTextureScaleTranslate = new float4(mat.scale, mat.offset);

            matBGFX.billboarded = new float4(mat.billboarded ? 1 : 0, 0, 0, 0);
            return(!stillLoading);
        }
Beispiel #2
0
        public static unsafe MeshBGFX CreateStaticMesh(RendererBGFXInstance *inst, ushort *indices, int nindices, SimpleVertex *vertices, int nvertices, SkinnedMeshVertex *skinningdata = null)
        {
            bool hasSkinningData = skinningdata != null;

#if ENABLE_DOTSRUNTIME_PROFILER
            ProfilerStats.AccumStats.memMeshCount.Accumulate(1);
            long bytes = nvertices * sizeof(SimpleVertex) + nindices * sizeof(ushort);
            if (hasSkinningData)
            {
                bytes += nvertices * sizeof(SkinnedMeshVertex);
            }
            ProfilerStats.AccumStats.memMesh.Accumulate(bytes);
            ProfilerStats.AccumStats.memReservedGFX.Accumulate(bytes);
            ProfilerStats.AccumStats.memUsedGFX.Accumulate(bytes);
#endif
            if (hasSkinningData)
            {
                int   simpleVertexSize   = sizeof(SimpleVertex);
                int   skinningVertexSize = sizeof(SkinnedMeshVertex);
                int   totalVertexSize    = simpleVertexSize + skinningVertexSize;
                byte *tmpBlock           = (byte *)UnsafeUtility.Malloc(totalVertexSize * nvertices, 4, Allocator.Temp);
                UnsafeUtility.MemCpyStride(tmpBlock, totalVertexSize, vertices, simpleVertexSize, simpleVertexSize, nvertices);
                UnsafeUtility.MemCpyStride(tmpBlock + simpleVertexSize, totalVertexSize, skinningdata, skinningVertexSize, skinningVertexSize, nvertices);
                bgfx.Memory *bgfxMemory = RendererBGFXStatic.CreateMemoryBlock((byte *)tmpBlock, nvertices * totalVertexSize);
                UnsafeUtility.Free(tmpBlock, Allocator.Temp);

                return(new MeshBGFX
                {
                    indexBufferHandle = bgfx.create_index_buffer(RendererBGFXStatic.CreateMemoryBlock((byte *)indices, nindices * 2), (ushort)bgfx.BufferFlags.None).idx,
                    vertexBufferHandle = bgfx.create_vertex_buffer(bgfxMemory, &inst->m_simpleSkinnedVertexBufferDecl, (ushort)bgfx.BufferFlags.None).idx,
                    indexCount = nindices,
                    vertexCount = nvertices,
                    maxIndexCount = nindices,
                    maxVertexCount = nvertices,
                    vertexLayoutHandle = inst->m_simpleSkinnedVertexBufferDeclHandle,
                    isDynamic = false,
                    vertexSize = totalVertexSize,
                });
            }
            else
            {
                return(new MeshBGFX
                {
                    indexBufferHandle = bgfx.create_index_buffer(RendererBGFXStatic.CreateMemoryBlock((byte *)indices, nindices * 2), (ushort)bgfx.BufferFlags.None).idx,
                    vertexBufferHandle = bgfx.create_vertex_buffer(RendererBGFXStatic.CreateMemoryBlock((byte *)vertices, nvertices * sizeof(SimpleVertex)), &inst->m_simpleVertexBufferDecl, (ushort)bgfx.BufferFlags.None).idx,
                    indexCount = nindices,
                    vertexCount = nvertices,
                    maxIndexCount = nindices,
                    maxVertexCount = nvertices,
                    vertexLayoutHandle = inst->m_simpleVertexBufferDeclHandle,
                    isDynamic = false,
                    vertexSize = sizeof(SimpleVertex),
                });
            }
        }
Beispiel #3
0
        public unsafe bool UpdateLitMaterialBGFX(RendererBGFXInstance *sys, ref LitMaterial mat, ref LitMaterialBGFX matBGFX, bool srgbColors)
        {
            bool stillLoading = false;

            if (InitTexture(ref matBGFX.texAlbedoOpacity, mat.texAlbedoOpacity, sys->m_whiteTexture))
            {
                stillLoading = true;
            }
            if (InitTexture(ref matBGFX.texNormal, mat.texNormal, sys->m_upTexture))
            {
                stillLoading = true;
            }
            if (InitTexture(ref matBGFX.texMetal, mat.texMetal, sys->m_whiteTexture))
            {
                stillLoading = true;
            }
            if (InitTexture(ref matBGFX.texEmissive, mat.texEmissive, sys->m_whiteTexture))
            {
                stillLoading = true;
            }

            InitShader(ref matBGFX.shaderProgram, mat.shader, sys->m_litShader.m_prog);

            matBGFX.constAlbedo_Opacity = srgbColors ?
                                          new float4(Color.LinearToSRGB(mat.constAlbedo), mat.constOpacity) :
                                          new float4(mat.constAlbedo, mat.constOpacity);
            matBGFX.constMetal_Smoothness_Billboarded = new float4(mat.constMetal, mat.constSmoothness, mat.billboarded ? 1 : 0, 0);
            matBGFX.constEmissive_normalMapZScale     = srgbColors ?
                                                        new float4(Color.LinearToSRGB(mat.constEmissive), mat.normalMapZScale) :
                                                        new float4(mat.constEmissive, mat.normalMapZScale);
            matBGFX.mainTextureScaleTranslate = new float4(mat.scale, mat.offset);
            matBGFX.smoothness   = new float4(0.0f);
            matBGFX.smoothness.x = (!mat.transparent && mat.smoothnessAlbedoAlpha) ? 1 : 0;
            matBGFX.smoothness.y = (!mat.transparent && !mat.smoothnessAlbedoAlpha) ? 1 : 0;
            matBGFX.smoothness.z = !mat.transparent ? 1 : 0;

            // if twoSided, need to update state
            matBGFX.state = (ulong)(bgfx.StateFlags.WriteRgb | bgfx.StateFlags.WriteA | bgfx.StateFlags.DepthTestLess);
            if (!mat.twoSided && !mat.billboarded)
            {
                matBGFX.state |= (ulong)bgfx.StateFlags.CullCcw;
            }
            if (mat.transparent)
            {
                matBGFX.state |= RendererBGFXStatic.MakeBGFXBlend(bgfx.StateFlags.BlendOne, bgfx.StateFlags.BlendInvSrcAlpha);
            }
            else
            {
                matBGFX.state |= (ulong)bgfx.StateFlags.WriteZ;
            }
            return(!stillLoading);
        }
        protected override void OnUpdate()
        {
            var shader = World.GetExistingSystem <SpriteRendererSubmitSystem>().DefaultShader;

            if (!shader.IsInitialized)
            {
                return;
            }

            var cmd = m_Barrier.CreateCommandBuffer();

            Dependency = Entities
                         .WithName("CreateMesh2D")
                         .WithoutBurst()
                         .WithNone <SpriteMeshBuffers>()
                         .ForEach((Entity entity, in Sprite sprite) =>
            {
                var blob        = sprite.Mesh;
                var indexCount  = blob.Value.Indices.Length;
                var vertexCount = blob.Value.Vertices.Length;

                unsafe
                {
                    cmd.AddComponent(entity, new SpriteMeshBuffers
                    {
                        IndexCount         = indexCount,
                        VertexCount        = vertexCount,
                        VertexLayoutHandle = shader.LayoutHandle,
                        IndexBufferHandle  = bgfx.create_index_buffer(RendererBGFXStatic.CreateMemoryBlock((byte *)blob.Value.Indices.GetUnsafePtr(), indexCount * 2), (ushort)bgfx.BufferFlags.None).idx,
                        VertexBufferHandle = bgfx.create_vertex_buffer(RendererBGFXStatic.CreateMemoryBlock((byte *)blob.Value.Vertices.GetUnsafePtr(), vertexCount * sizeof(SpriteVertex)), (bgfx.VertexLayout *)shader.VertexLayout.GetUnsafeReadOnlyPtr(), (ushort)bgfx.BufferFlags.None).idx
                    });
                }
            }).Schedule(Dependency);

            Dependency = Entities
                         .WithName("RemoveMesh2D")
                         .WithoutBurst()
                         .WithNone <Sprite>()
                         .ForEach((Entity entity, in SpriteMeshBuffers mesh) =>
            {
                bgfx.destroy_index_buffer(new bgfx.IndexBufferHandle {
                    idx = mesh.IndexBufferHandle
                });
                bgfx.destroy_vertex_buffer(new bgfx.VertexBufferHandle {
                    idx = mesh.VertexBufferHandle
                });
                cmd.RemoveComponent(entity, typeof(SpriteMeshBuffers));
            }).Schedule(Dependency);

            m_Barrier.AddJobHandleForProducer(Dependency);
        }
Beispiel #5
0
        public ulong              state; // includes blending and culling!

        internal unsafe bool Update(EntityManager em, RendererBGFXInstance *sys, ref BitmapFontMaterial mat)
        {
            constClipRect     = mat.ConstClipRect;
            constMaskSoftness = mat.ConstMaskSoftness;

            // if texture entity OR load state changed need to update texture handles
            // content of texture change should transparently update texture referenced by handle
            bool stillLoading = UpdateTextMaterialsSystem.InitTexture(em, ref texAtlas, mat.AtlasTexture, sys->m_whiteTexture);

            // text is always two-sided and transparent
            state  = (ulong)(bgfx.StateFlags.WriteRgb | bgfx.StateFlags.WriteA | bgfx.StateFlags.DepthTestLess);
            state |= RendererBGFXStatic.MakeBGFXBlend(bgfx.StateFlags.BlendSrcAlpha, bgfx.StateFlags.BlendInvSrcAlpha);

            return(!stillLoading);
        }
Beispiel #6
0
        public unsafe void UpdateDynamic(ushort *indexSrc, int numIndices, byte *vertexSrc, int numVertices, int sizeofVertex)
        {
            Assert.IsTrue(isDynamic);
            Assert.IsTrue(numVertices <= maxVertexCount);
            Assert.IsTrue(numIndices <= maxIndexCount);
#if ENABLE_DOTSRUNTIME_PROFILER
            Assert.IsTrue(vertexSize == sizeofVertex);
            ProfilerStats.AccumStats.memUsedGFX.Accumulate(-(vertexCount * vertexSize + indexCount * sizeof(ushort)));
            ProfilerStats.AccumStats.memUsedGFX.Accumulate(numVertices * vertexSize + numIndices * sizeof(ushort));
#endif
            bgfx.update_dynamic_index_buffer(GetDynamicIndexBufferHandle(), 0, RendererBGFXStatic.CreateMemoryBlock((byte *)indexSrc, numIndices * 2));
            indexCount = numIndices;
            bgfx.update_dynamic_vertex_buffer(GetDynamicVertexBufferHandle(), 0, RendererBGFXStatic.CreateMemoryBlock(vertexSrc, numVertices * sizeofVertex));
            vertexCount = numVertices;
        }
        public static unsafe MeshBGFX CreateStaticMesh(RendererBGFXInstance *inst, ushort *indices, int nindices, SimpleVertex *vertices, int nvertices)
        {
#if ENABLE_DOTSRUNTIME_PROFILER
            ProfilerStats.AccumStats.memMeshCount.Accumulate(1);
            long bytes = nvertices * sizeof(SimpleVertex) + nindices * sizeof(ushort);
            ProfilerStats.AccumStats.memMesh.Accumulate(bytes);
            ProfilerStats.AccumStats.memReservedGFX.Accumulate(bytes);
            ProfilerStats.AccumStats.memUsedGFX.Accumulate(bytes);
#endif
            return(new MeshBGFX
            {
                indexBufferHandle = bgfx.create_index_buffer(RendererBGFXStatic.CreateMemoryBlock((byte *)indices, nindices * 2), (ushort)bgfx.BufferFlags.None).idx,
                vertexBufferHandle = bgfx.create_vertex_buffer(RendererBGFXStatic.CreateMemoryBlock((byte *)vertices, nvertices * sizeof(SimpleVertex)), &inst->m_simpleVertexBufferDecl, (ushort)bgfx.BufferFlags.None).idx,
                indexCount = nindices,
                vertexCount = nvertices,
                maxIndexCount = nindices,
                maxVertexCount = nvertices,
                vertexLayoutHandle = inst->m_simpleVertexBufferDeclHandle,
                isDynamic = false,
                vertexSize = sizeof(SimpleVertex),
            });
        }
        public static unsafe void EncodeLinePreTransformed(RendererBGFXInstance *sys, bgfx.Encoder *encoder, ushort viewId, SimpleVertex *vertices, int n)
        {
            bgfx.TransientIndexBuffer  tib;
            bgfx.TransientVertexBuffer tvb;
            int ni = (n / 4) * 6;

            if (!bgfx.alloc_transient_buffers(&tvb, &sys->m_simpleVertexBufferDecl, (uint)n, &tib, (uint)ni))
            {
                throw new InvalidOperationException("Out of transient bgfx memory!");
            }
            UnsafeUtility.MemCpy((SimpleVertex *)tvb.data, vertices, sizeof(SimpleVertex) * n);
            ushort *indices = (ushort *)tib.data;

            for (int i = 0; i < n; i += 4)
            {
                indices[0] = (ushort)i; indices[1] = (ushort)(i + 1); indices[2] = (ushort)(i + 2);
                indices[3] = (ushort)(i + 2); indices[4] = (ushort)(i + 3); indices[5] = (ushort)i;
                indices   += 6;
            }
            bgfx.encoder_set_transient_index_buffer(encoder, &tib, 0, (uint)ni);
            bgfx.encoder_set_transient_vertex_buffer(encoder, 0, &tvb, 0, (uint)n, sys->m_simpleVertexBufferDeclHandle);

            // material uniforms setup
            ulong state = (ulong)(bgfx.StateFlags.DepthTestLess | bgfx.StateFlags.WriteRgb) | RendererBGFXStatic.MakeBGFXBlend(bgfx.StateFlags.BlendOne, bgfx.StateFlags.BlendInvSrcAlpha);

            bgfx.encoder_set_state(encoder, state, 0);
            bgfx.encoder_submit(encoder, viewId, sys->m_lineShader.m_prog, 0, (byte)bgfx.DiscardFlags.All);
        }
        protected override void OnUpdate()
        {
            var bgfxinst = World.GetExistingSystem <RendererBGFXSystem>().InstancePointer();

            if (!bgfxinst->m_initialized)
            {
                return;
            }

            // setup bgfx side
            Entities.WithoutBurst().ForEach((Entity e, ref RenderPass pass) =>
            {
                if (pass.viewId == 0xffff)
                {
                    RenderDebug.LogFormat("Render pass entity {0} on render node entity {1} is not referenced by the render graph. It should be deleted.", e, pass.inNode);
                    Assert.IsTrue(false);
                    return;
                }
                bool rtt = EntityManager.HasComponent <FramebufferBGFX>(pass.inNode);
                if (rtt)
                {
                    pass.passFlags = RenderPassFlags.RenderToTexture;
                }
                else
                {
                    pass.passFlags = 0;
                }
                // those could be more shared ... (that is, do all passes really need a copy of view & projection?)
                unsafe { fixed(float4x4 * viewp = &pass.viewTransform, projp = &pass.projectionTransform)
                         {
                             if (bgfxinst->m_homogeneousDepth && bgfxinst->m_originBottomLeft) // gl style
                             {
                                 bgfx.set_view_transform(pass.viewId, viewp, projp);
                                 pass.passFlags &= ~RenderPassFlags.FlipCulling;
                             }
                             else // dx style
                             {
                                 bool yflip = !bgfxinst->m_originBottomLeft && rtt;
                                 float4x4 adjustedProjection = RendererBGFXStatic.AdjustProjection(ref pass.projectionTransform, !bgfxinst->m_homogeneousDepth, yflip);
                                 bgfx.set_view_transform(pass.viewId, viewp, &adjustedProjection);
                                 if (yflip)
                                 {
                                     pass.passFlags |= RenderPassFlags.FlipCulling;
                                 }
                                 else
                                 {
                                     pass.passFlags &= ~RenderPassFlags.FlipCulling;
                                 }
                             }
                             // make a viewProjection
                             pass.viewProjectionTransform = math.mul(pass.projectionTransform, pass.viewTransform);
                         } }
                bgfx.set_view_mode(pass.viewId, (bgfx.ViewMode)pass.sorting);
                bgfx.set_view_rect(pass.viewId, pass.viewport.x, pass.viewport.y, pass.viewport.w, pass.viewport.h);
                bgfx.set_view_scissor(pass.viewId, pass.scissor.x, pass.scissor.y, pass.scissor.w, pass.scissor.h);
                bgfx.set_view_clear(pass.viewId, (ushort)pass.clearFlags, pass.clearRGBA, pass.clearDepth, pass.clearStencil);
                if (rtt)
                {
                    var rttbgfx = EntityManager.GetComponentData <FramebufferBGFX>(pass.inNode);
                    bgfx.set_view_frame_buffer(pass.viewId, rttbgfx.handle);
                }
                else
                {
                    bgfx.set_view_frame_buffer(pass.viewId, new bgfx.FrameBufferHandle {
                        idx = 0xffff
                    });
                }
                // touch it? needed?
                bgfx.touch(pass.viewId);
            }).Run();
        }