예제 #1
0
        protected virtual void RenderBlock(Block block, float x, float y, float scale)
        {
            var model = JsonModelLoader.GetModelForBlock(block.UnlocalizedName);

            if (model == null)
            {
                return;
            }

            ModelBlockRaw mbr = (ModelBlockRaw)model.RawModel;
            List <float>  uvs = new List <float>(8);

            mbr.AppendUvsForSide(FaceSides.South, uvs);

            Vector2 UVmin = new Vector2(uvs[0], uvs[1]);
            Vector2 UVmax = new Vector2(uvs[4], uvs[5]);

            Vector2 unit = new Vector2(1f / SharpCraft.Instance.ClientSize.Width, 1f / SharpCraft.Instance.ClientSize.Height);

            float width  = 16;
            float height = 16;

            float scaledWidth  = 16 * scale;
            float scaledHeight = 16 * scale;

            float posX = x + scaledWidth / 2;
            float posY = -y - scaledHeight / 2;

            Vector2 pos = new Vector2(posX, posY).Ceiling() * unit;

            Matrix4 mat = MatrixHelper.CreateTransformationMatrix(pos * 2 - Vector2.UnitX + Vector2.UnitY, scale * new Vector2(width, height) * unit);

            _item.Bind();

            Shader.Bind();
            Shader.UpdateGlobalUniforms();
            Shader.UpdateModelUniforms();
            Shader.UpdateInstanceUniforms(mat, UVmin, UVmax);

            GL.BindTexture(TextureTarget.Texture2D, JsonModelLoader.TEXTURE_BLOCKS);
            _item.RawModel.Render(PrimitiveType.Quads);

            _item.Unbind();
        }
예제 #2
0
        public void BuildChunkModelNow()
        {
            if (ModelBuilding || !QueuedForModelBuild)
            {
                return;
            }

            ModelBuilding = true;

            //ConcurrentDictionary<Shader<ModelBlock>, List<RawQuad>> modelRaw = new ConcurrentDictionary<Shader<ModelBlock>, List<RawQuad>>();

            //List<RawQuad> quads;

            Stopwatch sw = Stopwatch.StartNew(); //this is just a debug thing....

            var air = BlockRegistry.GetBlock <BlockAir>();

            var vertexes = new List <float>();
            var normals  = new List <float>();
            var uvs      = new List <float>();

            object locker = new object();

            //generate the model - fill MODEL_RAW
            Enumerable.Range(0, ChunkHeight).AsParallel().ForAll(y =>
            {
                for (int x = 0; x < ChunkSize; x++)
                {
                    for (int z = 0; z < ChunkSize; z++)
                    {
                        BlockPos worldPos = new BlockPos(x + Pos.WorldSpaceX(), y, z + Pos.WorldSpaceZ());

                        BlockState state = World.GetBlockState(worldPos);
                        if (state.Block == air)
                        {
                            continue;
                        }

                        BlockPos localPos = new BlockPos(x, y, z);

                        ModelBlockRaw mbr = (ModelBlockRaw)state.Model?.RawModel;

                        if (mbr == null)
                        {
                            continue;
                        }

                        if (!state.Block.IsFullCube)
                        {
                            lock (locker)
                                mbr.AppendAllVertexData(vertexes, normals, uvs, localPos);

                            continue;
                        }

                        for (var index = 0; index < FaceSides.AllSides.Count; index++)
                        {
                            FaceSides dir = FaceSides.AllSides[index];

                            BlockPos worldPosO = worldPos.Offset(dir);
                            BlockState stateO  = World.GetBlockState(worldPosO);

                            if (!(stateO.Block == air ||
                                  stateO.Block.HasTransparency && !state.Block.HasTransparency) &&
                                stateO.Block.IsFullCube)
                            {
                                continue;
                            }

                            lock (locker)
                            {
                                mbr.AppendVertexDataForSide(dir, vertexes, normals, uvs, localPos);
                                //mbr.AppendNormalsForSide(dir, normals);
                                //mbr.AppendUvsForSide(dir, uvs);
                            }
                        }
                    }
                }
            });

            sw.Stop();
            Console.WriteLine($"DEBUG: built chunk model [{sw.Elapsed.TotalMilliseconds:F}ms]");

            float[] vtx = vertexes.ToArray(); //this is here because this takes time and I don't want it to slow down the main thread by running it in GlContext
            float[] nrm = normals.ToArray();
            float[] uv  = uvs.ToArray();

            SharpCraft.Instance.RunGlContext(() =>
            {
                if (_model == null)
                {
                    _model = new ModelChunk(vtx, nrm, uv, Block.DefaultShader);
                }
                else
                {
                    _model.OverrideData(vtx, nrm, uv);
                }

                ModelBuilding = false;
            });

            QueuedForModelBuild = false;
        }