OpenTK探索二:立体纹理贴图

上一节写了简单的立体绘制,相信大家也可以绘制很多种立体图形了。接下来要讲的是纹理贴图,说到纹理贴图,相信随便百度下就一大把,不过大多都是2D平面贴图。说到这肯定有人要说了,纹理贴图不就只支持平面2D吗?各位息怒,把刀先放下!且听我慢慢道来。

我记得我原来学习纹理的时候,百度一下到处都是,照着弄一下也很顺,可是出来就是个平面图片。我心想,我们要做的是3D啊,怎么一直教我在平面上搞,作为小白的我,那时候也是很郁闷的。郁闷久了反而想通了:我画立体图形的时候不也是一个面一个面的画吗?那我就一个面一个面的贴图不就好了?跟着这个想法,我开始了探索。

按照上一节的代码基础,我在界面加载时先加入一张图片:

            Bitmap _bitmap = new Bitmap("D:\\Red墙.jpg");
            BitmapData bitmapData = _bitmap.LockBits(
                               new Rectangle(0, 0, _bitmap.Width, _bitmap.Height),
                               ImageLockMode.ReadOnly,
                               System.Drawing.Imaging.PixelFormat.Format32bppArgb
                               );

然后绑定到纹理:

            GL.GenTextures(1, out TextureID);
            GL.BindTexture(TextureTarget.Texture2D, TextureID);

            GL.TexImage2D(
                    TextureTarget.Texture2D,
                    0,
                    PixelInternalFormat.Rgba,
                    bitmapData.Width,
                    bitmapData.Height,
                    0,
                    OpenTK.Graphics.OpenGL.PixelFormat.Bgra,
                    PixelType.UnsignedByte,
                    bitmapData.Scan0
                );

            _bitmap.UnlockBits(bitmapData);

            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);

接下来就是绘图部分了:

            GL.Enable(EnableCap.Texture2D);
            int sides = 40;
            float radius = 1;
            Vector3[] Points = new Vector3[sides + 1];

            for (int i = 0; i < sides + 1; i++)
            {
                Points[i].X = radius * (float)Math.Cos(- Math.PI + i * 2 * Math.PI / sides);
                Points[i].Y = radius * (float)Math.Sin(-Math.PI + i * 2 * Math.PI / sides);
                Points[i].Z = 0;
            }

            GL.Begin(BeginMode.Quads);

            for (int i = 0; i < sides; i++)
            {
                GL.TexCoord2((float)i / sides, 1);
                GL.Vertex3(Points[i]);
                GL.Normal3(Vector3d.Normalize(new Vector3d(Points[i].X, Points[i].Y, 0)));

                GL.TexCoord2((float)i / sides, 0);
                GL.Vertex3(Points[i] + new Vector3(0, 0, 3));
                GL.Normal3(Vector3d.Normalize(new Vector3d(Points[i].X, Points[i].Y, 0)));

                GL.TexCoord2((float)(i + 1) / sides, 0);
                GL.Vertex3(Points[i + 1] + new Vector3(0, 0, 3));
                GL.Normal3(Vector3d.Normalize(new Vector3d(Points[i + 1].X, Points[i + 1].Y, 0)));

                GL.TexCoord2((float)(i + 1) / sides, 1);
                GL.Vertex3(Points[i + 1]);
                GL.Normal3(Vector3d.Normalize(new Vector3d(Points[i + 1].X, Points[i + 1].Y, 0)));
            }
            GL.End();

            GL.Disable(EnableCap.Texture2D);

这边是绘制的一个圆柱侧面上的贴图,把侧面分成了无数块小长方形,然后按照比例把每一小块图片贴上。

效果:

 结尾:不明白的童鞋可以举手啊,在下方评论,看到必回。另外,如果有大佬看到的话希望可以不吝赐教。

首先,需要在WinForm中安装OpenTK Nuget包。 然后,可以按照以下步骤绘制一个立体小球: 1. 在WinForm中添加一个控件,例如Panel,用于显示绘制的小球。 2. 创建一个OpenTK.GLControl控件,将它添加到Panel控件中。这个控件将用于OpenGL绘制。 3. 在GLControl的Load事件中,初始化OpenGL的相关设置,例如背景色、深度缓存等: ```csharp private void glControl_Load(object sender, EventArgs e) { GL.ClearColor(Color.Black); GL.Enable(EnableCap.DepthTest); GL.DepthFunc(DepthFunction.Lequal); GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest); } ``` 4. 在GLControl的Paint事件中,绘制小球。可以使用OpenTK提供的GLU库来绘制球体: ```csharp private void glControl_Paint(object sender, PaintEventArgs e) { GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); GL.MatrixMode(MatrixMode.Modelview); GL.LoadIdentity(); GL.Color3(Color.Red); GL.Translate(0, 0, -6); GL.Rotate(rotation, 0, 1, 0); GLU.Sphere(quadric, 1.0, 16, 16); rotation += 1f; glControl.SwapBuffers(); } ``` 5. 在GLControl的Resize事件中,设置OpenGL视口的大小: ```csharp private void glControl_Resize(object sender, EventArgs e) { GL.Viewport(0, 0, glControl.Width, glControl.Height); GL.MatrixMode(MatrixMode.Projection); GL.LoadIdentity(); GLU.Perspective(45.0, (double)glControl.Width / (double)glControl.Height, 0.1, 100.0); } ``` 完整代码如下: ```csharp using System; using System.Drawing; using System.Windows.Forms; using OpenTK.Graphics.OpenGL; using OpenTK.Graphics; using OpenTK; namespace WinForm_OpenTK_Sphere { public partial class Form1 : Form { private GLUquadric quadric; private float rotation = 0f; public Form1() { InitializeComponent(); glControl.Load += glControl_Load; glControl.Paint += glControl_Paint; glControl.Resize += glControl_Resize; } private void glControl_Load(object sender, EventArgs e) { quadric = GLU.NewQuadric(); GL.ClearColor(Color.Black); GL.Enable(EnableCap.DepthTest); GL.DepthFunc(DepthFunction.Lequal); GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest); } private void glControl_Paint(object sender, PaintEventArgs e) { GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); GL.MatrixMode(MatrixMode.Modelview); GL.LoadIdentity(); GL.Color3(Color.Red); GL.Translate(0, 0, -6); GL.Rotate(rotation, 0, 1, 0); GLU.Sphere(quadric, 1.0, 16, 16); rotation += 1f; glControl.SwapBuffers(); } private void glControl_Resize(object sender, EventArgs e) { GL.Viewport(0, 0, glControl.Width, glControl.Height); GL.MatrixMode(MatrixMode.Projection); GL.LoadIdentity(); GLU.Perspective(45.0, (double)glControl.Width / (double)glControl.Height, 0.1, 100.0); } } } ``` 以上是简单的绘制小球的代码,可以根据需要进行修改。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值