Exemplo n.º 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));
        }
Exemplo n.º 2
0
        private float rota = 0;//旋转
        private void Tick(object sender, ElapsedEventArgs e)
        {
            lock (_frameBuff) {
                clearBuff();
                rota += 0.05f;
                //获取旋转矩阵
                Matrix4x4 rotaX     = MathUntil.GetRotateX(rota);
                Matrix4x4 rotaY     = MathUntil.GetRotateY(rota);
                Matrix4x4 translate = MathUntil.GetTranslate(0, 0, 10);
                Matrix4x4 m         = rotaX * rotaY * translate;
                //计算相机视矩阵
                Matrix4x4 v = MathUntil.GetView(_camera.pos, _camera.lookAt, _camera.up);
                //投影矩阵
                Matrix4x4 p = MathUntil.GetProjection(_camera.fov, _camera.aspect, _camera.zn, _camera.zf);

                Draw(m, v, p);

                if (_frameG2 == null)
                {
                    _frameG2 = CreateGraphics();
                }

                _frameG2.Clear(System.Drawing.Color.Black);
                _frameG2.DrawImage(_frameBuff, 0, 0);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// 平底,p1为上顶点,p2,p3
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="p3"></param>

        private void DrawTriangleBottom(Vertex p1, Vertex p2, Vertex p3)
        {
            for (float y = p1.point.y; y <= p2.point.y; y += 0.5f)
            {
                int yIndex = (int)(System.Math.Round(y, MidpointRounding.AwayFromZero));
                if (yIndex >= 0 && yIndex < this.MaximumSize.Height)
                {
                    float xl = (y - p1.point.y) * (p2.point.x - p1.point.x) / (p2.point.y - p1.point.y) + p1.point.x;
                    float xr = (y - p1.point.y) * (p3.point.x - p1.point.x) / (p3.point.y - p1.point.y) + p1.point.x;

                    float dy = y - p1.point.y;
                    float t  = dy / (p2.point.y - p1.point.y);
                    //插值生成左右顶点
                    Vertex new1 = new Vertex();
                    new1.point.x = xl;
                    new1.point.y = y;
                    MathUntil.ScreenSpaceLerpVertex(ref new1, p1, p2, t);
                    //
                    Vertex new2 = new Vertex();
                    new2.point.x = xr;
                    new2.point.y = y;
                    MathUntil.ScreenSpaceLerpVertex(ref new2, p1, p3, t);
                    //扫描线填充
                    if (new1.point.x < new2.point.x)
                    {
                        ScanlineFill(new1, new2, yIndex);
                    }
                    else
                    {
                        ScanlineFill(new2, new1, yIndex);
                    }
                }
            }
        }
Exemplo n.º 4
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;
        }
Exemplo n.º 5
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));
                        }
                    }
                }
            }
        }
Exemplo n.º 6
0
        private void Tick(object sender, EventArgs e)
        {
            lock (_frameBuff)
            {
                ClearBuff();
                rot += 0.05f;
                Matrix4x4 m = MathUntil.GetRotateX(rot) * MathUntil.GetRotateY(rot) * MathUntil.GetTranslate(0, 0, 10);

                Matrix4x4 v = MathUntil.GetView(_camera.pos, _camera.lookAt, _camera.up);
                Matrix4x4 p = MathUntil.GetProjection(_camera.fov, _camera.aspect, _camera.zn, _camera.zf);
                //
                Draw(m, v, p);

                if (g == null)
                {
                    g = this.CreateGraphics();
                }
                g.Clear(System.Drawing.Color.Black);
                g.DrawImage(_frameBuff, 0, 0);
            }
        }
Exemplo n.º 7
0
 private void timer1_Tick(object sender, EventArgs e)
 {
     lock (_frameBuff)
     {
         ClearBuff();
         CMatrix4x4 m = new CMatrix4x4();
         m.Identity();
         m[3, 2] = 5;
         rot    += 0.1f;
         m       = MathUntil.GetRotateY(rot) * m;
         CMatrix4x4 v = MathUntil.GetView(new CVector3D(0, 0, 0, 1), new CVector3D(0, 0, 1, 1), new CVector3D(0, 1, 0, 1));
         CMatrix4x4 p = MathUntil.GetProjection((float)System.Math.PI / 4, this.MaximumSize.Width / (float)this.MaximumSize.Height, 1f, 500f);
         //
         Draw(m, v, p);
         //
         if (g1 == null)
         {
             g1 = this.CreateGraphics();
         }
         g1.Clear(System.Drawing.Color.Black);
         g1.DrawImage(_frameBuff, 0, 0);
     }
     this.Invalidate();
 }
Exemplo n.º 8
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());
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// 光栅化三角形
        /// </summary>
        private void TriangleRasterization(Vertex p1, Vertex p2, Vertex p3)
        {
            if (p1.point.y == p2.point.y)
            {
                if (p1.point.y < p3.point.y)
                {//平顶
                    DrawTriangleTop(p1, p2, p3);
                }
                else
                {//平底
                    DrawTriangleBottom(p3, p1, p2);
                }
            }
            else if (p1.point.y == p3.point.y)
            {
                if (p1.point.y < p2.point.y)
                {//平顶
                    DrawTriangleTop(p1, p3, p2);
                }
                else
                {//平底
                    DrawTriangleBottom(p2, p1, p3);
                }
            }
            else if (p2.point.y == p3.point.y)
            {
                if (p2.point.y < p1.point.y)
                {//平顶
                    DrawTriangleTop(p2, p3, p1);
                }
                else
                {//平底
                    DrawTriangleBottom(p1, p2, p3);
                }
            }
            else
            {//分割三角形
                Vertex top;

                Vertex bottom;
                Vertex middle;
                if (p1.point.y > p2.point.y && p2.point.y > p3.point.y)
                {
                    top    = p3;
                    middle = p2;
                    bottom = p1;
                }
                else if (p3.point.y > p2.point.y && p2.point.y > p1.point.y)
                {
                    top    = p1;
                    middle = p2;
                    bottom = p3;
                }
                else if (p2.point.y > p1.point.y && p1.point.y > p3.point.y)
                {
                    top    = p3;
                    middle = p1;
                    bottom = p2;
                }
                else if (p3.point.y > p1.point.y && p1.point.y > p2.point.y)
                {
                    top    = p2;
                    middle = p1;
                    bottom = p3;
                }
                else if (p1.point.y > p3.point.y && p3.point.y > p2.point.y)
                {
                    top    = p2;
                    middle = p3;
                    bottom = p1;
                }
                else if (p2.point.y > p3.point.y && p3.point.y > p1.point.y)
                {
                    top    = p1;
                    middle = p3;
                    bottom = p2;
                }
                else
                {
                    //三点共线
                    return;
                }
                //插值求中间点x
                float middlex = (middle.point.y - top.point.y) * (bottom.point.x - top.point.x) / (bottom.point.y - top.point.y) + top.point.x;
                float dy      = middle.point.y - top.point.y;
                float t       = dy / (bottom.point.y - top.point.y);
                //插值生成左右顶点
                Vertex newMiddle = new Vertex();
                newMiddle.point.x = middlex;
                newMiddle.point.y = middle.point.y;
                MathUntil.ScreenSpaceLerpVertex(ref newMiddle, top, bottom, t);

                //平底
                DrawTriangleBottom(top, newMiddle, middle);
                //平顶
                DrawTriangleTop(newMiddle, middle, bottom);
            }
        }
Exemplo n.º 10
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);
 }
Exemplo n.º 11
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);
 }