Пример #1
0
        private System.Drawing.Color ReadTexture(int uIndex, int vIndex)
        {
            int u = MathUntil.Range(uIndex, 0, _texture.Width - 1);
            int v = MathUntil.Range(vIndex, 0, _texture.Height - 1);

            return(_texture.GetPixel(u, v));
        }
Пример #2
0
        /// <summary>
        /// 实现了“基础光照模型”,在世界空间进行顶点光照处理
        /// </summary>
        /// <param name="v"></param>
        private void Lighting(Matrix4x4 m, Vector3D worldEyePositon, ref Vertex v)
        {
            Vector3D worldPoint = v.point * m;                        //世界空间顶点位置
            Vector3D normal     = v.normal * m.Inverse().Transpose(); //模型空间法线乘以世界矩阵的逆转置得到世界空间法线

            normal = normal.Normalize();
            RenderData.Color emissiveColor = _mesh.material.emissive;           //自发光
            RenderData.Color ambientColor  = _ambientColor * _mesh.material.ka; //环境光

            Vector3D inLightDir = (_light.worldPosition - worldPoint).Normalize();
            float    diffuse    = Vector3D.Dot(normal, inLightDir);

            if (diffuse < 0)
            {
                diffuse = 0;
            }
            RenderData.Color diffuseColor = _mesh.material.diffuse * diffuse * _light.lightColor;//漫反射
            //
            Vector3D inViewDir = (worldEyePositon - worldPoint).Normalize();
            Vector3D h         = (inViewDir + inLightDir).Normalize();
            float    specular  = 0;

            if (diffuse != 0)
            {//防止出现光源在物体背面产生高光的情况
                specular = (float)System.Math.Pow(MathUntil.Range(Vector3D.Dot(h, normal), 0, 1), _mesh.material.shininess);
            }
            RenderData.Color specularColor = _mesh.material.specular * specular * _light.lightColor;//镜面高光
            //
            v.lightingColor = emissiveColor + ambientColor + diffuseColor + specularColor;
        }
Пример #3
0
        /// <summary>
        /// 扫描线填充
        /// </summary>
        /// <param name="left">左端点,值已经经过插值</param>
        /// <param name="right">右端点,值已经经过插值</param>
        private void ScanlineFill(CVertex left, CVertex right, int yIndex)
        {
            float dx = right.point.x - left.point.x;

            for (float x = left.point.x; x <= right.point.x; x++)
            {
                int xIndex = (int)(System.Math.Round(x, MidpointRounding.AwayFromZero));
                if (xIndex >= 0 && xIndex < this.MaximumSize.Width)
                {
                    float lerpFactor = 0;
                    if (dx != 0)
                    {
                        lerpFactor = (x - left.point.x) / dx;
                    }
                    //1/z’与x’和y'是线性关系的
                    float onePreZ = MathUntil.Lerp(left.onePerZ, right.onePerZ, lerpFactor);
                    if (onePreZ >= _zBuff[yIndex, xIndex]) //使用1/z进行深度测试
                    {                                      //通过测试
                        float w = 1 / onePreZ;
                        _zBuff[yIndex, xIndex] = onePreZ;
                        //uv 插值,求纹理颜色
                        float u      = MathUntil.Lerp(left.u, right.u, lerpFactor) * w * (_texture.Width - 1);
                        float v      = MathUntil.Lerp(left.v, right.v, lerpFactor) * w * (_texture.Height - 1);
                        int   uIndex = (int)(u + 0.5f);
                        int   vIndex = (int)(v + 0.5f);
                        uIndex = MathUntil.Range(uIndex, 0, _texture.Width - 1);
                        vIndex = MathUntil.Range(vIndex, 0, _texture.Height - 1);
                        //uv坐标系采用dx风格
                        System.Drawing.Color textrueColor = _texture.GetPixel(vIndex, uIndex);


                        //插值顶点颜色
                        float r = MathUntil.Lerp(left.color.r, right.color.r, lerpFactor) * w * 255;
                        float g = MathUntil.Lerp(left.color.g, right.color.g, lerpFactor) * w * 255;
                        float b = MathUntil.Lerp(left.color.b, right.color.b, lerpFactor) * w * 255;


                        //更新渲染模式渲染
                        if (RenderMode.Textured == _currentMode)
                        {
                            _frameBuff.SetPixel(xIndex, yIndex, textrueColor);
                        }
                        else if (RenderMode.VertexColor == _currentMode)
                        {
                            _frameBuff.SetPixel(xIndex, yIndex, System.Drawing.Color.FromArgb((int)r, (int)g, (int)b));
                        }
                    }
                }
            }
        }
Пример #4
0
        /// <summary>
        /// 扫描线填充
        /// </summary>
        /// <param name="left">左端点,值已经经过插值</param>
        /// <param name="right">右端点,值已经经过插值</param>
        private void ScanlineFill(Vertex left, Vertex right, int yIndex)
        {
            float dx   = right.point.x - left.point.x;
            float step = 1;

            if (dx != 0)
            {
                step = 1 / dx;
            }
            for (float x = left.point.x; x <= right.point.x; x += 0.5f)
            {
                int xIndex = (int)(x + 0.5f);
                if (xIndex >= 0 && xIndex < this.MaximumSize.Width)
                {
                    float lerpFactor = 0;
                    if (dx != 0)
                    {
                        lerpFactor = (x - left.point.x) / dx;
                    }
                    //1/z’与x’和y'是线性关系的
                    float onePreZ = MathUntil.Lerp(left.onePerZ, right.onePerZ, lerpFactor);
                    if (onePreZ >= _zBuff[yIndex, xIndex]) //使用1/z进行深度测试
                    {                                      //通过测试
                        float w = 1 / onePreZ;
                        _zBuff[yIndex, xIndex] = onePreZ;
                        //uv 插值,求纹理颜色
                        float u = MathUntil.Lerp(left.u, right.u, lerpFactor) * w * (_texture.Width - 1);
                        float v = MathUntil.Lerp(left.v, right.v, lerpFactor) * w * (_texture.Height - 1);
                        //纹理采样
                        RenderData.Color texColor = new RenderData.Color(1, 1, 1);
                        if (_textureFilterMode == TextureFilterMode.Point)
                        {//点采样
                            int uIndex = (int)System.Math.Round(u, MidpointRounding.AwayFromZero);
                            int vIndex = (int)System.Math.Round(v, MidpointRounding.AwayFromZero);
                            uIndex = MathUntil.Range(uIndex, 0, _texture.Width - 1);
                            vIndex = MathUntil.Range(vIndex, 0, _texture.Height - 1);
                            //uv坐标系采用dx风格
                            texColor = new RenderData.Color(ReadTexture(uIndex, vIndex));//转到我们自定义的color进行计算
                        }
                        else if (_textureFilterMode == TextureFilterMode.Bilinear)
                        {//双线性采样
                            float uIndex = (float)System.Math.Floor(u);
                            float vIndex = (float)System.Math.Floor(v);
                            float du     = u - uIndex;
                            float dv     = v - vIndex;

                            RenderData.Color texcolor1 = new RenderData.Color(ReadTexture((int)uIndex, (int)vIndex)) * (1 - du) * (1 - dv);
                            RenderData.Color texcolor2 = new RenderData.Color(ReadTexture((int)uIndex + 1, (int)vIndex)) * du * (1 - dv);
                            RenderData.Color texcolor3 = new RenderData.Color(ReadTexture((int)uIndex, (int)vIndex + 1)) * (1 - du) * dv;
                            RenderData.Color texcolor4 = new RenderData.Color(ReadTexture((int)uIndex + 1, (int)vIndex + 1)) * du * dv;
                            texColor = texcolor1 + texcolor2 + texcolor3 + texcolor4;
                        }

                        //插值顶点颜色
                        RenderData.Color vertColor = MathUntil.Lerp(left.vcolor, right.vcolor, lerpFactor) * w;
                        //插值光照颜色
                        RenderData.Color lightColor = MathUntil.Lerp(left.lightingColor, right.lightingColor, lerpFactor) * w;;


                        if (_lightMode == LightMode.ON)
                        {//光照模式,需要混合光照的颜色
                            if (RenderMode.Textured == _currentMode)
                            {
                                RenderData.Color finalColor = texColor * lightColor;
                                _frameBuff.SetPixel(xIndex, yIndex, finalColor.TransFormToSystemColor());
                            }
                            else if (RenderMode.VertexColor == _currentMode)
                            {
                                RenderData.Color finalColor = vertColor * lightColor;
                                _frameBuff.SetPixel(xIndex, yIndex, finalColor.TransFormToSystemColor());
                            }
                        }
                        else
                        {
                            if (RenderMode.Textured == _currentMode)
                            {
                                _frameBuff.SetPixel(xIndex, yIndex, texColor.TransFormToSystemColor());
                            }
                            else if (RenderMode.VertexColor == _currentMode)
                            {
                                _frameBuff.SetPixel(xIndex, yIndex, vertColor.TransFormToSystemColor());
                            }
                        }
                    }
                }
            }
        }
Пример #5
0
 public Color(System.Drawing.Color c)
 {
     this._r = MathUntil.Range((float)c.R / 255, 0, 1);
     this._g = MathUntil.Range((float)c.G / 255, 0, 1);
     this._b = MathUntil.Range((float)c.B / 255, 0, 1);
 }
Пример #6
0
 public Color(float r, float g, float b)
 {
     this._r = MathUntil.Range(r, 0, 1);
     this._g = MathUntil.Range(g, 0, 1);
     this._b = MathUntil.Range(b, 0, 1);
 }