sharpGL(openGl的.net版)之纹理使用

前言:做视频渲染,在windows平台有很多种方式(如d3d9,WriteableBitmap等)。然而著名的openGl是大家的首选。在.net中,微软提供好了已经封装过的openGl库,即sharpGl。接下来以wpf为例进行纹理部分的讲解。

经过本文的阅读,您不仅可以了解如何在wpf中使用sharpGl纹理,还可以触类旁通,学习OpenGl的在其他平台的使用方式,比如openGL ES等等。

一、纹理基本介绍

1、纹理介绍:纹理一般是指将图片贴到预先渲染的多边形上的某个指定区域上,以达到精美的效果。也可以不贴图片,直接贴RGB颜色空间也可以。

2、纹理的坐标:纹理和顶点坐标(这个会在基础章节讲解)不一样,他的坐标是st坐标,对应顶点坐标的x轴和y轴,且他的标准取值范围是(0,1)没有负数。(标准范围是0-1,当取非标准时范围时,如取3,可以用参数做伸缩和重复渲染处理)

3、纹理使用效果图:

 (使用纹理的3种效果图示)


二、wpf代码实现

1、新建一个wpf项目;

2、通过NuGet管理器下载shrpGL.WPF版本的dll到本地(也可从别的地方拷贝到项目):

 3、在 MainWindow.xaml 界面中使用OpenGLControl控件:

<Grid>
        <wpf:OpenGLControl x:Name="openGLControl1"
             OpenGLDraw="OpenGLControl1_OpenGLDraw"
             OpenGLInitialized="OpenGLControl1_OpenGLInitialized"
             RenderContextType="FBO" 
             FrameRate="20">
        </wpf:OpenGLControl>
</Grid>

4、后台代码(MainWindow.xaml.cs)

using SharpGL;
using System;
using System.Runtime.InteropServices;
using System.Windows;

namespace sharpGlGetPara
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        OpenGL gl;
        double rateDouTexture = 0; //旋转角度
        SharpGL.SceneGraph.Assets.Texture _texture; //申明一个纹理
        public MainWindow()
        {
            InitializeComponent();
        }

        //初始化openGl
        private void OpenGLControl1_OpenGLInitialized(object sender, SharpGL.WPF.OpenGLRoutedEventArgs args)
        {
            gl = openGLControl1.OpenGL;
            gl.ClearColor(0, 0, 0F, 1.0f);
            gl.Color(1.0, 0.0, 0.0, 0.0); //设置背景色
            gl.Enable(OpenGL.GL_TEXTURE_2D);

            _texture = new SharpGL.SceneGraph.Assets.Texture();
            _texture.Create(gl, "jingdong.png");//作为方便演示,我直接放到Debug输出文件夹了
            _texture.Bind(gl);
        }

        //渲染视频,这个方法根据FrameRate="20"的帧率决定执行频率
        private void OpenGLControl1_OpenGLDraw(object sender, SharpGL.WPF.OpenGLRoutedEventArgs args)
        {
            Dispatcher.Invoke(new Action(() =>
            {
                float[] verts = //正方形的顶点数组
               {
                     -0.5f, 0.5f,-0f,
                      0.5f, 0.5f, -0f,
                      0.5f,  -0.5f,-0f,
                     -0.5f,  -0.5f,-0f,
                 };


                float[] colors = //颜色数组(rgba参数-渐变)
                {
                   1f, 1f, 1f, 1f,//白色
                   1f, 1f, 1f, 1f,//白色
                   0.94f,  0.69f, 0.45f,1f,//橙色
                   0.94f,  0.69f, 0.45f,1f//橙色
                };

                float[] textures = //纹理坐标数组,注意:图片的纹理t轴是反的,这里通过1-处理
                {
                        0f, 1-1f,
                        1f, 1-1f,
                        1f, 1-0f,
                        0f, 1-0f
                };


                gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
                gl.LoadIdentity();
                gl.Translate(0f, 0f, -6f);//将坐标系后移动,让用户可见视图
                gl.EnableClientState(OpenGL.GL_VERTEX_ARRAY); //允许设置顶点
                gl.EnableClientState(OpenGL.GL_COLOR_ARRAY); //允许设置顶点颜色数组
                gl.EnableClientState(OpenGL.GL_TEXTURE_COORD_ARRAY); //允许设置顶点纹理坐标数组

                IntPtr pArray = Marshal.AllocHGlobal(verts.Length * sizeof(float)); //申请数组的指针
                IntPtr pColorArray = Marshal.AllocHGlobal(colors.Length * sizeof(float)); 
                IntPtr pTextureArray = Marshal.AllocHGlobal(textures.Length * sizeof(float));
                try
                {
                    Marshal.Copy(verts, 0, pArray, verts.Length);
                    gl.VertexPointer(3, OpenGL.GL_FLOAT, 0, pArray);//设置正方形的顶点数据

                    Marshal.Copy(colors, 0, pColorArray, colors.Length);
                    gl.ColorPointer(4, OpenGL.GL_FLOAT, 0, pColorArray);//设置正方形的顶点颜色数据

                    Marshal.Copy(textures, 0, pTextureArray, textures.Length);
                    //绑定纹理
                    gl.ActiveTexture(_texture.TextureName);
                    gl.BindTexture(OpenGL.GL_TEXTURE_2D, _texture.TextureName);

                    //当纹理坐标范围超出(0,1)时,下面4行用来配置拉伸效果
                    //gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MIN_FILTER, OpenGL.GL_LINEAR);
                    //gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MAG_FILTER, OpenGL.GL_LINEAR);

                    //gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_S, OpenGL.GL_CLAMP_TO_EDGE);
                    //gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_T, OpenGL.GL_CLAMP_TO_EDGE);

                    //设置顶点纹理坐标。但设置了顶点纹理坐标,那么顶点颜色自动失效
                    gl.TexCoordPointer(2, OpenGL.GL_FLOAT, 0, pTextureArray);

                    gl.Rotate(rateDouTexture, 0, 1f, 0); //变换,模拟播放效果(这里是绕着y轴旋转)
                }
                finally
                {
                    Marshal.FreeHGlobal(pArray); //释放数组内存
                    Marshal.FreeHGlobal(pColorArray);
                    Marshal.FreeHGlobal(pTextureArray);
                }

                gl.DrawArrays(OpenGL.GL_QUADS, 0, 4); //绘制正方形
                gl.DisableClientState(OpenGL.GL_VERTEX_ARRAY); //关闭顶点数组
                gl.DisableClientState(OpenGL.GL_COLOR_ARRAY); //关闭顶点颜色数组
                gl.DisableClientState(OpenGL.GL_TEXTURE_COORD_ARRAY); //关闭顶点纹理坐标数组

                rateDouTexture += 0.5d;
            }));
        }

      
    }
}

5、效果图(这里用了gl.Rotate旋转和OpenGLDraw渲染方法,达到实时视频渲染效果)


好了,本次关于sharpGL的纹理篇就讲到这里了,更多内容,请期待下次的讲述

欢迎有问题的伙伴及时留意讨论,有不足之处还望指正

祝大家生活工作愉快~

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值