Ejemplo n.º 1
0
        public override Bounds Bounds(RenderEntity ent)
        {
            Bounds b = new();

            b.Zero();
            b.ExpandSelf(ent == null ? 8f : Math.Max(ent.shaderParms[IRenderWorld.SHADERPARM_SPRITE_WIDTH], ent.shaderParms[IRenderWorld.SHADERPARM_SPRITE_HEIGHT]) * 0.5f);
            return(b);
        }
Ejemplo n.º 2
0
        public RenderBuffer <float> Draw(RenderEntity[] entities, ICamera camera)
        {
            _renderTarget.Clear();
            _matrixWorldToView = camera.WorldToView;

            TApp appdata = new TApp();

            TV2F[][]       vertexV2FData = new TV2F[entities.Length][];
            IPrimitive[][] primitives    = new IPrimitive[entities.Length][];
            Vector2[][]    screenCoords  = new Vector2[entities.Length][];
            for (int i = 0; i < entities.Length; i++)
            {
                RenderEntity instanceCopy = entities[i].GetInstanceToApply();

                _matrixObjectToWorld = instanceCopy.Transform.LocalToWorld;
                _matrixObjectToView  = _matrixWorldToView * _matrixObjectToWorld;

                Vector3[] vertices = instanceCopy.Model.Vertices;
                vertexV2FData[i] = new TV2F[vertices.Length];
                screenCoords[i]  = new Vector2[vertices.Length];
                primitives[i]    = instanceCopy.Model.Primitives;
                for (int j = 0; j < vertices.Length; j++)
                {
                    appdata.AssignAppdata(ref instanceCopy.Model, j);
                    TV2F v2f = Vertex(ref appdata);

                    vertexV2FData[i][j] = v2f;
                    screenCoords[i][j]  = ViewToScreen(v2f.Vertex_VOut);
                }
            }

            //Octree is so annoying
            //Clipping();

            Vector2Int[][][] rasterization = Rasterize(screenCoords, vertexV2FData, primitives);

            GenericVector <float> whiteColor = new GenericVector <float>(3)
            {
                1, 1, 1
            };

            //Model
            for (int i = 0; i < rasterization.Length; i++)
            {
                //Primitive
                for (int j = 0; j < rasterization[i].Length; j++)
                {
                    //PixelPos
                    for (int k = 0; k < rasterization[i][j].Length; k++)
                    {
                        _renderTarget.WritePixel(rasterization[i][j][k].X, rasterization[i][j][k].Y, whiteColor);
                    }
                }
            }

            return(_renderTarget);
        }
Ejemplo n.º 3
0
        private unsafe void SetPerObjectValues(RenderEntity currentEntity)
        {
            *ShaderValue.ObjectToWorld = *currentEntity.Transform.LocalToWorld;
            Mul(ShaderValue.WorldToView, ShaderValue.ObjectToWorld, ShaderValue.ObjectToView);
            Mul(ViewToScreen, ShaderValue.ObjectToView, ShaderValue.ObjectToScreen);

            //TODO Normalize
            //if (!JMath.Approx(ShaderValue.ObjectToView->M44, 1f))
            //    Divide(ShaderValue.ObjectToView, ShaderValue.ObjectToView->M44, ShaderValue.ObjectToView);
        }
Ejemplo n.º 4
0
    public static uint CreatePlayer()
    {
        int playerCount = ComponentManager.PlayerComponent.Count();

        if (playerCount >= MAX_PLAYERS)
            return uint.MaxValue;

        uint playerID = IDManager.GetNewID();

        Player player = new Player()
        {
            EntityID = playerID,
            PlayerID = (ushort)playerCount
        };
        ComponentManager.PlayerComponent.Add(playerID, player);

        Position playerPosition = new Position()
        {
            EntityID = playerID,
            Center = new Vector3()
        };
        ComponentManager.PositionComponent.Add(playerID, playerPosition);

        ComponentManager.PlaneComponent.Add(playerID);

        Movement playerMovement = new Movement()
        {
            EntityID = playerID,
            MoveDirection = Vector2.zero,
            Speed = BASE_SPEED
        };
        ComponentManager.MovementComponent.Add(playerID, playerMovement);

        SpriteAnim playerAnim = new SpriteAnim()
        {
            EntityID = playerID,
            AnimArray = new List<Sprite>(),
            AnimIndex = 0,
            AnimType = SpriteType.Loop,
            FPS = 1.0f,
            FrameIncrement = 0,
            TimeLeft = 1.0f
        };
        playerAnim = SpriteHelper.SetMageAnim(playerAnim.EntityID, SpriteHelper.AnimList.IdleDown);
        ComponentManager.SpriteAnimComponent.Add(playerID, playerAnim);

        RenderEntity playerRender = new RenderEntity()
        {
            EntityID = playerID
        };
        ComponentManager.RenderComponent.Add(playerID, playerRender);

        return playerID;
    }
Ejemplo n.º 5
0
        public static void TestRenderCube()
        {
            EstablishTestScene <Camera_Orthographic>(out var pipeline, out var charBuffer, out var camera);

            RenderEntity entity = new RenderEntity(
                transform: new Transform(Vector3.Zero),
                model: Model.Cube(),
                material: null);

            RenderEntity[] entitiesApply = new RenderEntity[] { entity };

            DrawRotatingObject(pipeline, entitiesApply, camera, charBuffer);
        }
Ejemplo n.º 6
0
        public static void TestRenderTriangle()
        {
            EstablishTestScene(out var pipeline, out var charBuffer, out var camera);

            RenderEntity entity = new RenderEntity(new Transform(),
                                                   new Model(
                                                       vertices: new Vector4[] { new Vector4(1, 0, 0, 1), new Vector4(0, 1, 0, 1), new Vector4(0, -1, 0, 1) },
                                                       primitives: new IPrimitive[] { new TrianglePrimitive(0, 1, 2) },
                                                       uvs: null,
                                                       normals: null),
                                                   material: null);

            RenderEntity[] entitiesApply = new RenderEntity[] { entity };

            DrawRotatingObject(pipeline, entitiesApply, camera, charBuffer);
        }
Ejemplo n.º 7
0
        public static void TestRenderTriangle()
        {
            EstablishTestScene <Camera_Orthographic>(out var pipeline, out var charBuffer, out var camera);

            RenderEntity entity = new RenderEntity(
                transform: new Transform(Vector3.Zero),
                new Model(
                    vertices: new Vector3[] { new Vector3(-.5f, -.25f, 0), new Vector3(.5f, -.25f, 0), new Vector3(0, .5f, 0) },
                    indices: new int[] { 0, 1, 2 },
                    uvs: null,
                    normals: null),
                material: null);

            RenderEntity[] entitiesApply = new RenderEntity[] { entity };

            DrawRotatingObject(pipeline, entitiesApply, camera, charBuffer);
        }
Ejemplo n.º 8
0
        public static void TestDrawLine()
        {
            EstablishTestScene(out var pipeline, out var charBuffer, out var camera);

            RenderEntity entity = new RenderEntity(
                transform: new Transform(Vector3.Zero),
                model: new Model(
                    vertices: new Vector4[] { new Vector4(-.5f, .5f, -.5f, 1f), new Vector4(-.5f, -.5f, -.5f, 1f), new Vector4(.5f, -.5f, -.5f, 1f), new Vector4(.5f, .5f, -.5f, 1f),
                                              new Vector4(-.5f, .5f, .5f, 1f), new Vector4(-.5f, -.5f, .5f, 1f), new Vector4(.5f, -.5f, .5f, 1f), new Vector4(.5f, .5f, .5f, 1f) },
                    primitives: new IPrimitive[] { new LinePrimitive(0, 1), new LinePrimitive(1, 2), new LinePrimitive(2, 3), new LinePrimitive(3, 0),
                                                   new LinePrimitive(4, 5), new LinePrimitive(5, 6), new LinePrimitive(6, 7), new LinePrimitive(7, 4),
                                                   new LinePrimitive(0, 4), new LinePrimitive(1, 5), new LinePrimitive(2, 6), new LinePrimitive(3, 7) },
                    uvs: null,
                    normals: null),
                material: new Material <Shader_Scale>(Shader_Scale.Instance));

            RenderEntity[] entitiesApply = new RenderEntity[] { entity };

            DrawRotatingObject(pipeline, entitiesApply, camera, charBuffer);
        }
Ejemplo n.º 9
0
        //void GetFrameBounds(RenderEntity ent, out Bounds bounds);

        void DrawJoints(RenderEntity ent, ViewDef view)
        {
            int i; Vector3 pos;

            var num = ent.numJoints;

            for (i = 0; i < num; i++)
            {
                var joint    = ent.joints[i];
                var md5Joint = joints[i];
                pos = ent.origin + joint.ToVec3() * ent.axis;
                if (md5Joint.parent != null)
                {
                    var parentNum = md5Joint.parent - joints;
                    session.rw.DebugLine(colorWhite, ent.origin + ent.joints[parentNum].ToVec3() * ent.axis, pos);
                }

                session.rw.DebugLine(colorRed, pos, pos + joint.ToMat3()[0] * 2f * ent.axis);
                session.rw.DebugLine(colorGreen, pos, pos + joint.ToMat3()[1] * 2f * ent.axis);
                session.rw.DebugLine(colorBlue, pos, pos + joint.ToMat3()[2] * 2f * ent.axis);
            }

            Bounds bounds = new();

            bounds.FromTransformedBounds(ent.bounds, Vector3.origin, ent.axis);
            session.rw.DebugBounds(colorMagenta, bounds, ent.origin);

            if (r_jointNameScale.Float != 0f && bounds.Expand(128f).ContainsPoint(view.renderView.vieworg - ent.origin))
            {
                Vector3 offset = new(0f, 0f, r_jointNameOffset.Float);
                var     scale  = r_jointNameScale.Float;
                num = ent.numJoints;
                for (i = 0; i < num; i++)
                {
                    var joint = ent.joints[i];
                    pos = ent.origin + joint.ToVec3() * ent.axis;
                    session.rw.DrawText(joints[i].name, pos + offset, scale, colorWhite, view.renderView.viewaxis, 1);
                }
            }
        }
Ejemplo n.º 10
0
        public static void TestDrawLine()
        {
            PipelineBase <AppdataBasic, V2FBasic> pipeline = new PipelineBase <AppdataBasic, V2FBasic>();
            CharRenderBuffer <float> charBuffer            = new CharRenderBuffer <float>(pipeline.RenderTarget);

            RenderEntity entity = new RenderEntity(new Transform(Vector3.Zero),
                                                   new Model(
                                                       vertices: new Vector3[] { new Vector3(-.5f, .5f, -.5f), new Vector3(-.5f, -.5f, -.5f), new Vector3(.5f, -.5f, -.5f), new Vector3(.5f, .5f, -.5f),
                                                                                 new Vector3(-.5f, .5f, .5f), new Vector3(-.5f, -.5f, .5f), new Vector3(.5f, -.5f, .5f), new Vector3(.5f, .5f, .5f) },
                                                       primitives: new IPrimitive[] { new LinePrimitive(0, 1), new LinePrimitive(1, 2), new LinePrimitive(2, 3), new LinePrimitive(3, 0),
                                                                                      new LinePrimitive(4, 5), new LinePrimitive(5, 6), new LinePrimitive(6, 7), new LinePrimitive(7, 4),
                                                                                      new LinePrimitive(0, 4), new LinePrimitive(1, 5), new LinePrimitive(2, 6), new LinePrimitive(3, 7) },
                                                       uvs: null,
                                                       normals: null
                                                       ), null);
            ICamera camera = new Camera_Orthographic(width: 3.5f, height: 3.5f, near: -2.5f, far: 2.5f,
                                                     new Transform(
                                                         pos: Vector3.Zero,
                                                         rotation: new Vector3(0, JMath.PI_HALF * .35f, -JMath.PI_HALF * 1.5f)));

            RenderEntity[] entitiesApply = new RenderEntity[] { entity };

            float framerate     = 25f;
            float time          = 10f;
            int   totalFrame    = (int)(framerate * time);
            float angleStep     = JMath.PI_TWO / totalFrame;
            int   frameInterval = (int)(1000f / framerate);

            for (int i = 0; i < totalFrame; i++)
            {
                pipeline.Draw(entitiesApply, camera);
                CRenderer.Render(charBuffer);
                entity.Transform.Rotation.X += angleStep;
                entity.Transform.Rotation.Z += angleStep;
                Thread.Sleep(frameInterval);
            }
        }
Ejemplo n.º 11
0
        public override Bounds Bounds(RenderEntity ent)
        {
            Bounds b = new();

            b.Zero();
            if (ent == null)
            {
                b.ExpandSelf(8f);
            }
            else
            {
                Vector3 target      = reinterpret.cast_vec3(ent.shaderParms, IRenderWorld.SHADERPARM_BEAM_END_X);
                var     modelMatrix = stackalloc float[16];
                R_AxisToModelMatrix(ent.axis, ent.origin, modelMatrix);
                R_GlobalPointToLocal(modelMatrix, target, out var localTarget);

                b.AddPoint(localTarget);
                if (ent.shaderParms[IRenderWorld.SHADERPARM_BEAM_WIDTH] != 0f)
                {
                    b.ExpandSelf(ent.shaderParms[IRenderWorld.SHADERPARM_BEAM_WIDTH] * 0.5f);
                }
            }
            return(b);
        }
Ejemplo n.º 12
0
 public void AddEntity(RenderEntity Entity)
 {
     current.Add(Entity);
 }
Ejemplo n.º 13
0
        public override IRenderModel InstantiateDynamicModel(RenderEntity ent, ViewDef view, IRenderModel cachedModel)
        {
            int i, surfaceNum; MD5Mesh mesh; RenderModelStatic staticModel;

            if (cachedModel != null && !r_useCachedDynamicModels.Bool)
            {
                cachedModel.Dispose();
                cachedModel = null;
            }

            if (purged)
            {
                common.DWarning($"model {Name} instantiated while purged"); LoadModel();
            }

            if (ent.joints == null)
            {
                common.Printf($"RenderModelMD5::InstantiateDynamicModel: null joints on renderEntity for '{Name}'\n");
                cachedModel.Dispose();
                return(null);
            }
            else if (ent.numJoints != joints.Length)
            {
                common.Printf($"RenderModelMD5::InstantiateDynamicModel: renderEntity has different number of joints than model for '{Name}'\n");
                cachedModel.Dispose();
                return(null);
            }

            tr.pc.c_generateMd5++;

            if (cachedModel != null)
            {
                Debug.Assert(cachedModel is RenderModelStatic);
                Debug.Assert(string.Equals(cachedModel.Name, MD5_SnapshotName, StringComparison.OrdinalIgnoreCase));
                staticModel = (RenderModelStatic)cachedModel;
            }
            else
            {
                staticModel = new RenderModelStatic();
                staticModel.InitEmpty(MD5_SnapshotName);
            }

            staticModel.bounds.Clear();

            if (r_showSkel.Integer != 0)
            {
                if (view != null && (!r_skipSuppress.Bool || ent.suppressSurfaceInViewID == 0 || ent.suppressSurfaceInViewID != view.renderView.viewID))
                {
                    DrawJoints(ent, view);                                                                                                                                      // only draw the skeleton
                }
                if (r_showSkel.Integer > 1)
                {
                    staticModel.InitEmpty(MD5_SnapshotName); return(staticModel);
                }                                                                                            // turn off the model when showing the skeleton
            }

            // create all the surfaces
            for (i = 0; i < meshes.Length; i++)
            {
                mesh = meshes[i];

                // avoid deforming the surface if it will be a nodraw due to a skin remapping. FIXME: may have to still deform clipping hulls
                var shader = mesh.shader;

                shader = R_RemapShaderBySkin(shader, ent.customSkin, ent.customShader);

                if (shader == null || (!shader.IsDrawn && !shader.SurfaceCastsShadow))
                {
                    staticModel.DeleteSurfaceWithId(i); mesh.surfaceNum = -1; continue;
                }

                ModelSurface surf;
                if (staticModel.FindSurfaceWithId(i, out surfaceNum))
                {
                    mesh.surfaceNum = surfaceNum;
                    surf            = staticModel.surfaces[surfaceNum];
                }
                else
                {
                    // Remove Overlays before adding new surfaces
                    RenderModelOverlay.RemoveOverlaySurfacesFromModel(staticModel);

                    mesh.surfaceNum = staticModel.NumSurfaces;
                    surf            = staticModel.surfaces.Alloc();
                    surf.geometry   = null;
                    surf.shader     = null;
                    surf.id         = i;
                }

                mesh.UpdateSurface(ent, ent.joints, surf);

                staticModel.bounds.AddPoint(surf.geometry.bounds[0]);
                staticModel.bounds.AddPoint(surf.geometry.bounds[1]);
            }

            return(staticModel);
        }
Ejemplo n.º 14
0
 // This calculates a rough bounds by using the joint radii without transforming all the points
 public override Bounds Bounds(RenderEntity ent)
 => ent == null
     ? bounds // this is the bounds for the reference pose
     : ent.bounds;
Ejemplo n.º 15
0
        public void UpdateSurface(RenderEntity ent, JointMat[] joints, ModelSurface surf)
        {
            int i;

            tr.pc.c_deformedSurfaces++;
            tr.pc.c_deformedVerts   += deformInfo.numOutputVerts;
            tr.pc.c_deformedIndexes += deformInfo.numIndexes;

            surf.shader = shader;

            if (surf.geometry != null)
            {
                // if the number of verts and indexes are the same we can re-use the triangle surface the number of indexes must be the same to assure the correct amount of memory is allocated for the facePlanes
                if (surf.geometry.numVerts == deformInfo.numOutputVerts && surf.geometry.numIndexes == deformInfo.numIndexes)
                {
                    R_FreeStaticTriSurfVertexCaches(surf.geometry);
                }
                else
                {
                    R_FreeStaticTriSurf(surf.geometry); surf.geometry = R_AllocStaticTriSurf();
                }
            }
            else
            {
                surf.geometry = R_AllocStaticTriSurf();
            }

            var tri = surf.geometry;

            // note that some of the data is references, and should not be freed
            tri.deformedSurface      = true;
            tri.tangentsCalculated   = false;
            tri.facePlanesCalculated = false;

            tri.numIndexes       = deformInfo.numIndexes;
            tri.indexes          = deformInfo.indexes;
            tri.silIndexes       = deformInfo.silIndexes;
            tri.numMirroredVerts = deformInfo.numMirroredVerts;
            tri.mirroredVerts    = deformInfo.mirroredVerts;
            tri.numDupVerts      = deformInfo.numDupVerts;
            tri.dupVerts         = deformInfo.dupVerts;
            tri.numSilEdges      = deformInfo.numSilEdges;
            tri.silEdges         = deformInfo.silEdges;
            tri.dominantTris     = deformInfo.dominantTris;
            tri.numVerts         = deformInfo.numOutputVerts;

            if (tri.verts == null)
            {
                R_AllocStaticTriSurfVerts(tri, tri.numVerts);
                for (i = 0; i < deformInfo.numSourceVerts; i++)
                {
                    tri.verts[i].Clear(); tri.verts[i].st = texCoords[i];
                }
            }

            fixed(JointMat *jointsJ = joints)
            if (ent.shaderParms[IRenderWorld.SHADERPARM_MD5_SKINSCALE] != 0f)
            {
                TransformScaledVerts(tri.verts, jointsJ, ent.shaderParms[IRenderWorld.SHADERPARM_MD5_SKINSCALE]);
            }
            else
            {
                TransformVerts(tri.verts, jointsJ);
            }

            // replicate the mirror seam vertexes
            var base_ = deformInfo.numOutputVerts - deformInfo.numMirroredVerts;

            for (i = 0; i < deformInfo.numMirroredVerts; i++)
            {
                tri.verts[base_ + i] = tri.verts[deformInfo.mirroredVerts[i]];
            }

            R_BoundTriSurf(tri);

            // If a surface is going to be have a lighting interaction generated, it will also have to call R_DeriveTangents() to get normals, tangents, and face planes.  If it only
            // needs shadows generated, it will only have to generate face planes.  If it only has ambient drawing, or is culled, no additional work will be necessary
            if (!r_useDeferredTangents.Bool)
            {
                R_DeriveTangents(tri);                              // set face planes, vertex normals, tangents
            }
        }
Ejemplo n.º 16
0
        public static void CreateOutput(object sender, object selectedItem)
        {
            if (selectedItem is OutputCollectionViewModel outputCollectionViewModel)
            {
                CreateOutput(sender, outputCollectionViewModel.Parent);
                return;
            }

            if (!(selectedItem is GroupViewModel entityGroupViewModel))
            {
                return;
            }

            var button = (Button)sender;

            var type = (string)button.CommandParameter;

            OutputBase entity;

            switch (type)
            {
            case nameof(RenderArrayHint):
                entity = RenderArrayHint.New();
                break;

            case nameof(RenderNextDate):
                entity = RenderNextDate.New("Name", "0001-01-01", "Weekly");
                break;

            case nameof(RenderIndex):
                entity = RenderIndex.New();
                break;

            case nameof(RenderEntity):
                entity = RenderEntity.New();
                break;

            case nameof(RenderLink):
                entity = RenderLink.New();
                break;

            case nameof(RenderProperty):
                entity = RenderProperty.New("Display Name", "Property Name");
                break;

            case nameof(RenderValue):
                entity = RenderValue.New("Name", "Value");
                break;

            case nameof(RenderTypeName):
                entity = RenderTypeName.New("Name");
                break;

            case nameof(RenderTaxPeriodDate):
                entity = RenderTaxPeriodDate.New("Name", "2020", "1");
                break;

            case nameof(RenderConstant):
                entity = RenderConstant.New("Name", "Constant Name", typeof(DateTime));
                break;

            case nameof(RenderTaxPeriod):
                entity = RenderTaxPeriod.New("Name", "Monthly", "0001-01-01");
                break;

            case nameof(RenderDateAdd):
                entity = RenderDateAdd.New("Name", "0001-01-01", "Day", "1");
                break;

            case nameof(RenderUniqueKeyFromLink):
                entity = RenderUniqueKeyFromLink.New("Name", "[Link]");
                break;

            case nameof(Avg):
                entity = Avg.New("Name", "Property");
                break;

            case nameof(Max):
                entity = Max.New("Name", "Property");
                break;

            case nameof(Min):
                entity = Min.New("Name", "Property");
                break;

            case nameof(Sum):
                entity = Sum.New("Name", "Property");
                break;

            case nameof(Count):
                entity = Count.New("Name");
                break;

            case nameof(ExpressionCalculator):
                entity = ExpressionCalculator.New("Name", "1 + 2 - 3 * 4 / 5", rounding: RoundingOption.NotSet);
                break;

            case nameof(Distinct):
                entity = Distinct.New("Name", "Property");
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            entityGroupViewModel.Element.Outputs.Add(entity);
            var viewModelCollection = entityGroupViewModel.Children.OfType <OutputCollectionViewModel>().First();

            var viewModel = new OutputViewModel(entity, viewModelCollection);

            viewModelCollection.Children.Add(viewModel);

            entityGroupViewModel.IsExpanded = true;
            viewModelCollection.IsExpanded  = true;
            viewModel.IsSelected            = true;
            viewModel.IsExpanded            = true;
        }
Ejemplo n.º 17
0
        public unsafe RenderBuffer <float> Draw(RenderEntity[] entities, ICamera camera)
        {
            RenderTarget.Clear();

            int        entityCount         = entities.Length;
            Fragment **rasterizedFragments = stackalloc Fragment *[entityCount];
            int *      primitiveCounts     = stackalloc int[entityCount];

            BeginRasterize();
            ShaderValue.WorldToView = camera.WorldToView;
            ShaderValue.Time        = CRenderer.CurrentSecond;
            ShaderValue.SinTime     = MathF.Sin(ShaderValue.Time);
            for (int i = 0; i < entityCount; i++)
            {
                RenderEntity instanceCopy = entities[i].GetInstanceToApply();
                IMaterial    material     = instanceCopy.Material ?? DEFAULT_MATERIAL;
                Vector4[]    vertices     = instanceCopy.Model.Vertices;
                IPrimitive[] primitives   = instanceCopy.Model.Primitives;

                ShaderValue.ObjectToWorld = instanceCopy.Transform.LocalToWorld;
                ShaderValue.ObjectToView  = ShaderValue.WorldToView * ShaderValue.ObjectToWorld;

                ShaderInvoker <IVertexShader> .ChangeActiveShader(material.ShaderType, material.Shader);

                int      vertexCount  = vertices.Length;
                Vector2 *coordsOutput = stackalloc Vector2[vertexCount];
                Vector4 *vertexOutput = stackalloc Vector4[vertexCount];

                for (int j = 0; j < vertexCount; j++)
                {
                    ShaderInOutMap outputMap = ShaderInvoker <IVertexShader> .Invoke(j, vertices);

                    vertexOutput[j] = *outputMap.VertexPtr;
                    coordsOutput[j] = ViewToScreen(*outputMap.VertexPtr);
                }

                Fragment *fragments = stackalloc Fragment[primitives.Length];
                primitiveCounts[i] = primitives.Length;
                for (int j = 0; j < primitives.Length; j++)
                {
                    Rasterize(coordsOutput, primitives[j], fragments + j);
                }
                rasterizedFragments[i] = fragments;
            }
            EndRasterize();

            //Octree is so annoying
            //TODO: View frustum clip, triangle clip, pixel clip
            //Clipping();

            //This is not the proper way to output, just to check result as soon as possible
            GenericVector <float> white = new GenericVector <float>(3)
            {
                1, 1, 1
            };

            for (int i = 0; i < entityCount; i++)
            {
                for (int j = 0; j < primitiveCounts[i]; j++)
                {
                    RenderTarget.WritePixel(rasterizedFragments[i][j].Rasterization, rasterizedFragments[i][j].PixelCount, white);
                }
            }

            return(RenderTarget);
        }
Ejemplo n.º 18
0
        public override IRenderModel InstantiateDynamicModel(RenderEntity ent, ViewDef view, IRenderModel cachedModel)
        {
            idRenderModelStatic *staticModel;

            if (cachedModel && !r_useCachedDynamicModels.GetBool())
            {
                delete cachedModel;
                cachedModel = NULL;
            }

            // this may be triggered by a model trace or other non-view related source, to which we should look like an empty model
            if (renderEntity == NULL || viewDef == NULL)
            {
                delete cachedModel;
                return(NULL);
            }

            if (r_skipParticles.GetBool())
            {
                delete cachedModel;
                return(NULL);
            }

            /*
             * // if the entire system has faded out
             * if ( renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME] && viewDef->renderView.time * 0.001f >= renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME] ) {
             *      delete cachedModel;
             *      return NULL;
             * }
             */

            if (cachedModel != NULL)
            {
                assert(dynamic_cast <idRenderModelStatic *>(cachedModel) != NULL);
                assert(idStr::Icmp(cachedModel->Name(), parametricParticle_SnapshotName) == 0);

                staticModel = static_cast <idRenderModelStatic *>(cachedModel);
            }
            else
            {
                staticModel = new idRenderModelStatic;
                staticModel->InitEmpty(parametricParticle_SnapshotName);
            }

            particleGen_t g;

            g.renderEnt  = renderEntity;
            g.renderView = &viewDef->renderView;
            g.origin.Zero();
            g.axis.Identity();

            for (int stageNum = 0; stageNum < particleSystem->stages.Num(); stageNum++)
            {
                idParticleStage *stage = particleSystem->stages[stageNum];

                if (!stage->material)
                {
                    continue;
                }
                if (!stage->cycleMsec)
                {
                    continue;
                }
                if (stage->hidden)
                {                       // just for gui particle editor use
                    staticModel->DeleteSurfaceWithId(stageNum);
                    continue;
                }

                idRandom steppingRandom, steppingRandom2;

                int stageAge   = g.renderView->time + renderEntity->shaderParms[SHADERPARM_TIMEOFFSET] * 1000 - stage->timeOffset * 1000;
                int stageCycle = stageAge / stage->cycleMsec;

                // some particles will be in this cycle, some will be in the previous cycle
                steppingRandom.SetSeed(((stageCycle << 10) & idRandom::MAX_RAND) ^ (int)(renderEntity->shaderParms[SHADERPARM_DIVERSITY] * idRandom::MAX_RAND));
                steppingRandom2.SetSeed((((stageCycle - 1) << 10) & idRandom::MAX_RAND) ^ (int)(renderEntity->shaderParms[SHADERPARM_DIVERSITY] * idRandom::MAX_RAND));

                int count = stage->totalParticles * stage->NumQuadsPerParticle();

                int             surfaceNum;
                modelSurface_t *surf;

                if (staticModel->FindSurfaceWithId(stageNum, surfaceNum))
                {
                    surf = &staticModel->surfaces[surfaceNum];
                    R_FreeStaticTriSurfVertexCaches(surf->geometry);
                }
                else
                {
                    surf           = &staticModel->surfaces.Alloc();
                    surf->id       = stageNum;
                    surf->shader   = stage->material;
                    surf->geometry = R_AllocStaticTriSurf();
                    R_AllocStaticTriSurfVerts(surf->geometry, 4 * count);
                    R_AllocStaticTriSurfIndexes(surf->geometry, 6 * count);
                    R_AllocStaticTriSurfPlanes(surf->geometry, 6 * count);
                }

                int         numVerts = 0;
                idDrawVert *verts    = surf->geometry->verts;

                for (int index = 0; index < stage->totalParticles; index++)
                {
                    g.index = index;

                    // bump the random
                    steppingRandom.RandomInt();
                    steppingRandom2.RandomInt();

                    // calculate local age for this index
                    int bunchOffset = stage->particleLife * 1000 * stage->spawnBunching * index / stage->totalParticles;

                    int particleAge   = stageAge - bunchOffset;
                    int particleCycle = particleAge / stage->cycleMsec;
                    if (particleCycle < 0)
                    {
                        // before the particleSystem spawned
                        continue;
                    }
                    if (stage->cycles && particleCycle >= stage->cycles)
                    {
                        // cycled systems will only run cycle times
                        continue;
                    }

                    if (particleCycle == stageCycle)
                    {
                        g.random = steppingRandom;
                    }
                    else
                    {
                        g.random = steppingRandom2;
                    }

                    int inCycleTime = particleAge - particleCycle * stage->cycleMsec;

                    if (renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME] &&
                        g.renderView->time - inCycleTime >= renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME] * 1000)
                    {
                        // don't fire any more particles
                        continue;
                    }

                    // supress particles before or after the age clamp
                    g.frac = (float)inCycleTime / (stage->particleLife * 1000);
                    if (g.frac < 0.0f)
                    {
                        // yet to be spawned
                        continue;
                    }
                    if (g.frac > 1.0f)
                    {
                        // this particle is in the deadTime band
                        continue;
                    }

                    // this is needed so aimed particles can calculate origins at different times
                    g.originalRandom = g.random;

                    g.age = g.frac * stage->particleLife;

                    // if the particle doesn't get drawn because it is faded out or beyond a kill region, don't increment the verts
                    numVerts += stage->CreateParticle(&g, verts + numVerts);
                }

                // numVerts must be a multiple of 4
                assert((numVerts & 3) == 0 && numVerts <= 4 * count);

                // build the indexes
                int        numIndexes = 0;
                glIndex_t *indexes    = surf->geometry->indexes;
                for (int i = 0; i < numVerts; i += 4)
                {
                    indexes[numIndexes + 0] = i;
                    indexes[numIndexes + 1] = i + 2;
                    indexes[numIndexes + 2] = i + 3;
                    indexes[numIndexes + 3] = i;
                    indexes[numIndexes + 4] = i + 3;
                    indexes[numIndexes + 5] = i + 1;
                    numIndexes += 6;
                }

                surf->geometry->tangentsCalculated   = false;
                surf->geometry->facePlanesCalculated = false;
                surf->geometry->numVerts             = numVerts;
                surf->geometry->numIndexes           = numIndexes;
                surf->geometry->bounds = stage->bounds;                     // just always draw the particles
            }

            return(staticModel);
        }
Ejemplo n.º 19
0
 public override Bounds Bounds(RenderEntity ent)
 => particleSystem.bounds;
Ejemplo n.º 20
0
        => true;        // don't ever need to load

        public override IRenderModel InstantiateDynamicModel(RenderEntity ent, ViewDef view, IRenderModel cachedModel)
        {
            RenderModelStatic staticModel; SrfTriangles tri; ModelSurface surf;

            if (cachedModel != null)
            {
                cachedModel = null;
            }

            if (ent == null || view == null)
            {
                return(null);
            }

            if (cachedModel != null)
            {
                Debug.Assert(cachedModel is RenderModelStatic);
                Debug.Assert(string.Equals(cachedModel.Name, beam_SnapshotName, StringComparison.OrdinalIgnoreCase));

                staticModel = (RenderModelStatic)cachedModel;
                surf        = staticModel.Surface(0);
                tri         = surf.geometry;
            }
            else
            {
                staticModel = new RenderModelStatic();
                staticModel.InitEmpty(beam_SnapshotName);

                tri = R_AllocStaticTriSurf();
                R_AllocStaticTriSurfVerts(tri, 4);
                R_AllocStaticTriSurfIndexes(tri, 6);

                tri.verts[0].Clear(); tri.verts[0].st.x = 0; tri.verts[0].st.y = 0;
                tri.verts[1].Clear(); tri.verts[1].st.x = 0; tri.verts[1].st.y = 1;
                tri.verts[2].Clear(); tri.verts[2].st.x = 1; tri.verts[2].st.y = 0;
                tri.verts[3].Clear(); tri.verts[3].st.x = 1; tri.verts[3].st.y = 1;

                tri.indexes[0] = 0; tri.indexes[1] = 2; tri.indexes[2] = 1; tri.indexes[3] = 2; tri.indexes[4] = 3; tri.indexes[5] = 1;

                tri.numVerts   = 4;
                tri.numIndexes = 6;

                surf          = new();
                surf.geometry = tri;
                surf.id       = 0;
                surf.shader   = tr.defaultMaterial;
                staticModel.AddSurface(surf);
            }

            Vector3 target = reinterpret.cast_vec3(ent.shaderParms, IRenderWorld.SHADERPARM_BEAM_END_X);

            // we need the view direction to project the minor axis of the tube as the view changes
            var modelMatrix = stackalloc float[16];

            R_AxisToModelMatrix(ent.axis, ent.origin, modelMatrix);
            R_GlobalPointToLocal(modelMatrix, view.renderView.vieworg, out var localView);
            R_GlobalPointToLocal(modelMatrix, target, out var localTarget);

            Vector3 major = localTarget;
            Vector3 minor = default;

            Vector3 mid = 0.5f * localTarget;
            Vector3 dir = mid - localView;

            minor.Cross(major, dir);
            minor.Normalize();
            if (ent.shaderParms[IRenderWorld.SHADERPARM_BEAM_WIDTH] != 0f)
            {
                minor *= ent.shaderParms[IRenderWorld.SHADERPARM_BEAM_WIDTH] * 0.5f;
            }

            var red   = (byte)MathX.FtoiFast(ent.shaderParms[IRenderWorld.SHADERPARM_RED] * 255f);
            var green = (byte)MathX.FtoiFast(ent.shaderParms[IRenderWorld.SHADERPARM_GREEN] * 255f);
            var blue  = (byte)MathX.FtoiFast(ent.shaderParms[IRenderWorld.SHADERPARM_BLUE] * 255f);
            var alpha = (byte)MathX.FtoiFast(ent.shaderParms[IRenderWorld.SHADERPARM_ALPHA] * 255f);

            tri.verts[0].xyz = minor; tri.verts[0].color0 = red; tri.verts[0].color1 = green; tri.verts[0].color2 = blue; tri.verts[0].color3 = alpha;
            tri.verts[1].xyz = -minor; tri.verts[1].color0 = red; tri.verts[1].color1 = green; tri.verts[1].color2 = blue; tri.verts[1].color3 = alpha;
            tri.verts[2].xyz = localTarget + minor; tri.verts[2].color0 = red; tri.verts[2].color1 = green; tri.verts[2].color2 = blue; tri.verts[2].color3 = alpha;
            tri.verts[3].xyz = localTarget - minor; tri.verts[3].color0 = red; tri.verts[3].color1 = green; tri.verts[3].color2 = blue; tri.verts[3].color3 = alpha;

            R_BoundTriSurf(tri);

            staticModel.bounds = tri.bounds;

            return(staticModel);
        }
Ejemplo n.º 21
0
        public override IRenderModel InstantiateDynamicModel(RenderEntity ent, ViewDef view, IRenderModel cachedModel)
        {
            RenderModelStatic staticModel;
            SrfTriangles      tri;
            ModelSurface      surf;

            if (cachedModel != null && !r_useCachedDynamicModels.Bool)
            {
                cachedModel.Dispose(); cachedModel = null;
            }

            if (ent == null || view == null)
            {
                cachedModel.Dispose(); cachedModel = null;
            }

            if (cachedModel != null)
            {
                Debug.Assert(cachedModel is RenderModelStatic);
                Debug.Assert(string.Equals(cachedModel.Name, sprite_SnapshotName, StringComparison.OrdinalIgnoreCase));

                staticModel = (RenderModelStatic)cachedModel;
                surf        = staticModel.Surface(0);
                tri         = surf.geometry;
            }
            else
            {
                staticModel = new RenderModelStatic();
                staticModel.InitEmpty(sprite_SnapshotName);

                tri = R_AllocStaticTriSurf();
                R_AllocStaticTriSurfVerts(tri, 4);
                R_AllocStaticTriSurfIndexes(tri, 6);

                tri.verts[0].Clear();
                tri.verts[0].normal.Set(1f, 0f, 0f);
                tri.verts[0].tangents0.Set(0f, 1f, 0f);
                tri.verts[0].tangents1.Set(0f, 0f, 1f);
                tri.verts[0].st.x = 0f;
                tri.verts[0].st.y = 0f;

                tri.verts[1].Clear();
                tri.verts[1].normal.Set(1f, 0f, 0f);
                tri.verts[1].tangents0.Set(0f, 1f, 0f);
                tri.verts[1].tangents1.Set(0f, 0f, 1f);
                tri.verts[1].st.x = 1f;
                tri.verts[1].st.y = 0f;

                tri.verts[2].Clear();
                tri.verts[2].normal.Set(1f, 0f, 0f);
                tri.verts[2].tangents0.Set(0f, 1f, 0f);
                tri.verts[2].tangents1.Set(0f, 0f, 1f);
                tri.verts[2].st.x = 1f;
                tri.verts[2].st.y = 1f;

                tri.verts[3].Clear();
                tri.verts[3].normal.Set(1f, 0f, 0f);
                tri.verts[3].tangents0.Set(0f, 1f, 0f);
                tri.verts[3].tangents1.Set(0f, 0f, 1f);
                tri.verts[3].st.x = 0f;
                tri.verts[3].st.y = 1f;

                tri.indexes[0] = 0;
                tri.indexes[1] = 1;
                tri.indexes[2] = 3;
                tri.indexes[3] = 1;
                tri.indexes[4] = 2;
                tri.indexes[5] = 3;

                tri.numVerts   = 4;
                tri.numIndexes = 6;

                surf          = new();
                surf.geometry = tri;
                surf.id       = 0;
                surf.shader   = tr.defaultMaterial;
                staticModel.AddSurface(surf);
            }

            var red   = (byte)MathX.FtoiFast(ent.shaderParms[IRenderWorld.SHADERPARM_RED] * 255f);
            var green = (byte)MathX.FtoiFast(ent.shaderParms[IRenderWorld.SHADERPARM_GREEN] * 255f);
            var blue  = (byte)MathX.FtoiFast(ent.shaderParms[IRenderWorld.SHADERPARM_BLUE] * 255f);
            var alpha = (byte)MathX.FtoiFast(ent.shaderParms[IRenderWorld.SHADERPARM_ALPHA] * 255f);

            var right = new Vector3(0f, ent.shaderParms[IRenderWorld.SHADERPARM_SPRITE_WIDTH] * 0.5f, 0f);
            var up    = new Vector3(0f, 0f, ent.shaderParms[IRenderWorld.SHADERPARM_SPRITE_HEIGHT] * 0.5f);

            tri.verts[0].xyz    = up + right;
            tri.verts[0].color0 = red;
            tri.verts[0].color1 = green;
            tri.verts[0].color2 = blue;
            tri.verts[0].color3 = alpha;

            tri.verts[1].xyz    = up - right;
            tri.verts[1].color0 = red;
            tri.verts[1].color1 = green;
            tri.verts[1].color2 = blue;
            tri.verts[1].color3 = alpha;

            tri.verts[2].xyz    = -right - up;
            tri.verts[2].color0 = red;
            tri.verts[2].color1 = green;
            tri.verts[2].color2 = blue;
            tri.verts[2].color3 = alpha;

            tri.verts[3].xyz    = right - up;
            tri.verts[3].color0 = red;
            tri.verts[3].color1 = green;
            tri.verts[3].color2 = blue;
            tri.verts[3].color3 = alpha;

            R_BoundTriSurf(tri);

            staticModel.bounds = tri.bounds;

            return(staticModel);
        }
Ejemplo n.º 22
0
        public unsafe RenderBuffer <float> Draw <T>(RenderEntity[] entities, T camera) where T : ICamera
        {
            Clear();

            int entityCount = entities.Length;

            BeginRasterize();
            SetPerRenderValues(camera);
            for (int i = 0; i < entityCount; i++)
            {
                RenderEntity currentEntity = entities[i];
                SetPerObjectValues(currentEntity);

                Material material = currentEntity.Material ?? DEFAULT_MATERIAL;
                Model    model    = currentEntity.Model;

                #region Vertex Stage

                //Prepare vertex shader
                VertexInvoker.ChangeActiveShader(material.ShaderType, material.Shader);

                //Invoke vertex shader
                int      vertexCount  = model.Vertices.Length;
                Vector2 *coordsOutput = stackalloc Vector2[vertexCount];
                ShaderInOutPatternDefault *inoutPtr = stackalloc ShaderInOutPatternDefault[1];
                for (int j = 0; j < vertexCount; j++)
                {
                    VertexInvoker.Invoke(model.ReadVerticesDataAsPattern(j));
                    VertexInvoker.ActiveOutputMap.Write(inoutPtr);
                    coordsOutput[j] = *(Vector2 *)&inoutPtr->Vertex;
                }

                #endregion

                #region Fragment Stage

                FragmentInvoker.ChangeActiveShader(material.ShaderType, material.Shader);

                //Primitive assemble
                int newPrimitiveCount = AssemblePrimitive(model, coordsOutput);
                _rasterizedFragments.AddEmpty(newPrimitiveCount);
                switch (_assembleMode)
                {
                case PrimitiveAssembleMode.Line:
                case PrimitiveAssembleMode.LineTriangle:
                    Rasterize <LinePrimitive, Line>(_linePrimitives.GetPointer(_linePrimitives.Count - newPrimitiveCount), newPrimitiveCount, _rasterizedFragments.GetPointer(_rasterizedFragments.Count - newPrimitiveCount));
                    break;

                case PrimitiveAssembleMode.Triangle:
                    Rasterize <TrianglePrimitive, Triangle>(_trianglePrimitives.GetPointer(_trianglePrimitives.Count - newPrimitiveCount), newPrimitiveCount, _rasterizedFragments.GetPointer(_rasterizedFragments.Count - newPrimitiveCount));
                    break;
                }

                for (int j = _rasterizedFragments.Count - newPrimitiveCount; j < _rasterizedFragments.Count; j++)
                {
                    Fragment *fragment = _rasterizedFragments.GetPointer(j);
                    for (int k = 0; k < fragment->PixelCount; k++)
                    {
                        //Fragment.FragmentData has been tailored to a proper size
                        FragmentInvoker.Invoke((byte *)fragment->FragmentData[k]);
                        FragmentInvoker.ActiveOutputMap.Write(inoutPtr);
                        _renderedColors.Add(inoutPtr->Color);
                    }
                    fragment->FragmentColor = _renderedColors.ArchivePointer();
                }

                #endregion
            }

            EndRasterize();


            //Octree is so annoying
            //TODO: View frustum clip, triangle clip, pixel clip
            //Clipping();

            //This is not the proper way to output, rather for debugging
            for (int i = 0; i < _rasterizedFragments.Count; i++)
            {
                Fragment *fragmentPtr = _rasterizedFragments.GetPointer(i);
                RenderTarget.WritePixel(fragmentPtr->Rasterization, fragmentPtr->PixelCount, fragmentPtr->FragmentColor);
            }

            return(RenderTarget);
        }