C# SharpGL初探 长方体贴图 背景色 刷新率 旋转(带贴纸的可旋转长方体)

SharpGL是对OpenGl的C#的封装,支持Net4.0及以上,由于SharpGL仅仅是对C++写的OpenGL做了接口的封装,所以SharpGL的运行效率不用多说,是非常高效的,不会说因为C#是即时性语言而导致性能下降很多,在测试中使用我的笔记本i57300HQ的CPU占用率仅仅0.1%,说明这东西确实运行很高效,虽然没有Unity那样的GPU渲染优化(Unity3D的美化与渲染真的很好),但是这样低的CPU占用率依然很诱人(使用Unity3D时CPU占用率在1.3%~1.6%左右,GPU占用率高,占用线程多),对于轻量级(即便是很简单的一个三维场景,Unity3D一般拖家带口几十Mb甚至上百Mb,而SharpGL则为几Mb)的三维显示,SharpGL无疑是一个很好的选择。因此我在做三维姿态上位机过程中,又学习了一下SharpGL,当然很感谢官方的源码例程,基本所有的操作都是跟着官方例程来的。在这里分享一下:
本文ShaprGL WPF工程链接

安装SharpGL-1.vsix

这个会自动安装到当前的VS中,安装包链接

创建一个SharpGL的WPF窗体:

C# SharpGL初探 长方体贴图 背景色 刷新率 旋转(带贴纸的可旋转长方体)_第1张图片

xaml文件:

<Window x:Class="SharpGLWPFApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="SharpGL WPF Application" Height="554" Width="800" 
        xmlns:sharpGL="clr-namespace:SharpGL.WPF;assembly=SharpGL.WPF">
    <Grid>

        <!-- The OpenGL control provides a OpenGL drawing surface. -->
        <sharpGL:OpenGLControl 
            Name="openGLControl" OpenGLDraw="openGLControl_OpenGLDraw" 
            OpenGLInitialized="openGLControl_OpenGLInitialized" Resized="openGLControl_Resized"
            DrawFPS="false" RenderContextType="FBO" FrameRate="20" Margin="0,0,0.4,-0.2"/>
        <Button Content="暂停/继续" FontSize="28" HorizontalAlignment="Left" Width="135" Margin="0,435,0,0" Click="Button_Click"/>

    </Grid>
</Window>

设计完大概这样:
C# SharpGL初探 长方体贴图 背景色 刷新率 旋转(带贴纸的可旋转长方体)_第2张图片

设置背景色:

当然你觉得黑色不好看的话可换个纯色背景,只需要改改这句话就可以了(其中的透明度好像不能用,设置了好像也没什么变化,前三个RGB值是可以使用的,像我这样设置的话是藏蓝色的):

gl.ClearColor(0.1f, 0.2f,0.3f, 0.01f);//RGB值和透明度

贴图代码:

当然,贴图有两种方式,当然,我推荐简单的一种(虽然我在工程中没有这样做,┗( ▔, ▔ )┛)
简单的版本:

using SharpGL.SceneGraph.Assets;
OpenGL gl = openGLControl.OpenGL;
Texture[] mytexture = new Texture[6];//创建6个面的贴图
mytexture[0].Create(gl, "Pictures/Right.png");//依次生成贴图
...
...
...

一定需要注意的是,贴图前一定要保证已经使能了贴图功能,不然是贴不上去的,必须要有这一句话:

gl.Enable(OpenGL.GL_TEXTURE_2D);

然后就是贴图了,需要注意的是,贴图是
以 gl.Begin(OpenGL.GL_QUADS);开始
以 gl.End();结束
所以贴不同的面都要添上这两句
贴图中用到的三个函数的参数说明为:
/* gl.Normal3i(1, 0, 0); 四边形面的法向量*/
/gl.TexCoord(0, 0); 第一个参数是X坐标,0.0是纹理的左侧,0.5是纹理的中点,1.0是纹理的右侧。第二个参数是Y坐标,0.0是纹理的底部,0.5是纹理的中点,1.0是纹理的顶部/
/gl.Vertex(halfXdimension, -halfYdimension, -halfZdimension); 绘制的四边形的顶点的坐标/

 OpenGL gl = openGLControl.OpenGL;;
 gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);    // Clear screen and DepthBuffer
 gl.LoadIdentity();
 gl.PolygonMode(OpenGL.GL_FRONT, OpenGL.GL_FILL);

 //设置照相机的位置
 gl.Translate(0, 0, -1.0f * CameraDistance);
 switch (CameraView)
 {
     
     case (CameraViews.Right):
         gl.Rotate(-90, 0, 1, 0);
         gl.Rotate(-90, 1, 0, 0);
         break;
     case (CameraViews.Left):
         gl.Rotate(90, 0, 1, 0);
         gl.Rotate(-90, 1, 0, 0);
         break;
     case (CameraViews.Back):
         gl.Rotate(90, 1, 0, 0);
         gl.Rotate(180, 0, 1, 0);
         break;
     case (CameraViews.Front):
         gl.Rotate(-90, 1, 0, 0);
         break;
     case (CameraViews.Top):
         break;
     case (CameraViews.Bottom):
         gl.Rotate(180, 1, 0, 0);
         break;
 }

 gl.PushMatrix();

 //使用旋转矩阵旋转
 //gl.glMultMatrixf(transformationMatrix); //根据旋转矩阵旋转方块

 //根据欧拉角旋转
 /*绕 X 轴旋转  Y->Z  为正*/           /*绕 Y 轴旋转  Z->X  为正*/           /*绕 Z 轴旋转  X->Y  为正*/
 gl.Rotate((float)angle, 1, 0, 0);     gl.Rotate((float)angle, 0, 1, 0);     gl.Rotate((float)angle, 0, 0, 1);

 // +'ve x face
 gl.BindTexture(OpenGL.GL_TEXTURE_2D, textures[0]);//绑定贴图
 gl.Begin(OpenGL.GL_QUADS);//开始四边形
 /* gl.Normal3i(1, 0, 0); 法向量*/
 /*gl.TexCoord(0, 0); 第一个参数是X坐标,0.0是纹理的左侧,0.5是纹理的中点,1.0是纹理的右侧。第二个参数是Y坐标,0.0是纹理的底部,0.5是纹理的中点,1.0是纹理的顶部*/
 /*gl.Vertex(halfXdimension, -halfYdimension, -halfZdimension); 坐标取决于摄像机位置 */
 gl.Normal3i(1, 0, 0); gl.TexCoord(0, 0); gl.Vertex(halfXdimension, -halfYdimension, -halfZdimension);
 gl.Normal3i(1, 0, 0); gl.TexCoord(0, 1); gl.Vertex(halfXdimension, -halfYdimension, halfZdimension);
 gl.Normal3i(1, 0, 0); gl.TexCoord(1, 1); gl.Vertex(halfXdimension, halfYdimension, halfZdimension);
 gl.Normal3i(1, 0, 0); gl.TexCoord(1, 0); gl.Vertex(halfXdimension, halfYdimension, -halfZdimension);
 gl.End();

 // -'ve x face
 gl.BindTexture(OpenGL.GL_TEXTURE_2D, textures[1]);
 gl.Begin(OpenGL.GL_QUADS);
 gl.Normal3i(-1, 0, 0); gl.TexCoord(1, 0); gl.Vertex(-halfXdimension, -halfYdimension, -halfZdimension);
 gl.Normal3i(-1, 0, 0); gl.TexCoord(1, 1); gl.Vertex(-halfXdimension, -halfYdimension, halfZdimension);
 gl.Normal3i(-1, 0, 0); gl.TexCoord(0, 1); gl.Vertex(-halfXdimension, halfYdimension, halfZdimension);
 gl.Normal3i(-1, 0, 0); gl.TexCoord(0, 0); gl.Vertex(-halfXdimension, halfYdimension, -halfZdimension);
 gl.End();

 // +'ve y face
 gl.BindTexture(OpenGL.GL_TEXTURE_2D, textures[2]);
 gl.Begin(OpenGL.GL_QUADS);
 gl.Normal3i(0, 1, 0); gl.TexCoord(1, 0); gl.Vertex(-halfXdimension, halfYdimension, -halfZdimension);
 gl.Normal3i(0, 1, 0); gl.TexCoord(1, 1); gl.Vertex(-halfXdimension, halfYdimension, halfZdimension);
 gl.Normal3i(0, 1, 0); gl.TexCoord(0, 1); gl.Vertex(halfXdimension, halfYdimension, halfZdimension);
 gl.Normal3i(0, 1, 0); gl.TexCoord(0, 0); gl.Vertex(halfXdimension, halfYdimension, -halfZdimension);
 gl.End();

 // -'ve y face
 gl.BindTexture(OpenGL.GL_TEXTURE_2D, textures[3]);
 gl.Begin(OpenGL.GL_QUADS);
 gl.Normal3i(0, -1, 0); gl.TexCoord(0, 0); gl.Vertex(-halfXdimension, -halfYdimension, -halfZdimension);
 gl.Normal3i(0, -1, 0); gl.TexCoord(0, 1); gl.Vertex(-halfXdimension, -halfYdimension, halfZdimension);
 gl.Normal3i(0, -1, 0); gl.TexCoord(1, 1); gl.Vertex(halfXdimension, -halfYdimension, halfZdimension);
 gl.Normal3i(0, -1, 0); gl.TexCoord(1, 0); gl.Vertex(halfXdimension, -halfYdimension, -halfZdimension);
 gl.End();

 // +'ve z face
 gl.BindTexture(OpenGL.GL_TEXTURE_2D, textures[4]);
 gl.Begin(OpenGL.GL_QUADS);
 gl.Normal3i(0, 0, 1); gl.TexCoord(0, 0); gl.Vertex(-halfXdimension, -halfYdimension, halfZdimension);
 gl.Normal3i(0, 0, 1); gl.TexCoord(1, 0); gl.Vertex(halfXdimension, -halfYdimension, halfZdimension);
 gl.Normal3i(0, 0, 1); gl.TexCoord(1, 1); gl.Vertex(halfXdimension, halfYdimension, halfZdimension);
 gl.Normal3i(0, 0, 1); gl.TexCoord(0, 1); gl.Vertex(-halfXdimension, halfYdimension, halfZdimension);
 gl.End();

 // -'ve z face
 gl.BindTexture(OpenGL.GL_TEXTURE_2D, textures[5]);
 gl.Begin(OpenGL.GL_QUADS);
 gl.Normal3i(0, 0, -1); gl.TexCoord(0, 1); gl.Vertex(-halfXdimension, -halfYdimension, -halfZdimension);
 gl.Normal3i(0, 0, -1); gl.TexCoord(1, 1); gl.Vertex(halfXdimension, -halfYdimension, -halfZdimension);
 gl.Normal3i(0, 0, -1); gl.TexCoord(1, 0); gl.Vertex(halfXdimension, halfYdimension, -halfZdimension);
 gl.Normal3i(0, 0, -1); gl.TexCoord(0, 0); gl.Vertex(-halfXdimension, halfYdimension, -halfZdimension);
 gl.End();

 gl.PopMatrix();
 gl.Flush();

最终的实现效果:

C# SharpGL初探 长方体贴图 背景色 刷新率 旋转(带贴纸的可旋转长方体)_第3张图片

设置刷新率:

SharpGL是一个非常的人性化的设置,可以直接调节刷新率,也就省去了开启一个定时器,使用定时器来进行软刷新了,基本省去了定时器的麻烦,反正就是相当于他帮你开启了一个定时器,如果想调节定时器刷新频率的话,很简单,只需要在xaml里修改一下参数就可以了。将FrameRate="20"中的20改成你想要的刷新频率,单位是Hz,不过这个速率我试了下超过100Hz好像就没什么变化了,有可能是人家觉得不需要那么高的刷新率,反正实际FPS的需要也不需要太高吧。
或者这样做也行,添加一句:

openGLControl.FrameRate = 20;//这个20就是FPS可以随便改

你可能感兴趣的:(上位机软件,AHRS,C#,opengl)