微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在openTK中旋转图像

如何解决在openTK中旋转图像

我想将GLControl中显示的图像旋转10度。为此,我使用c#代码旋转了位图,并将此旋转后的位图传递给opengl着色器代码。但是生成的图像似乎像下面那样隐藏/剪切了旋转的部分。旋转时是否需要对其视口进行任何更改?还是用着色器代码本身旋转图像好?

     public void DrawImage(int image,int glcontrolWidth,int glcontrolHeight,Matrix4 **transformMatrix**)
    {
        GL.Viewport(new Rectangle(0,glcontrolWidth,glcontrolHeight));    
        GL.MatrixMode(MatrixMode.Projection);
        GL.Pushmatrix();
        GL.LoadIdentity();

        GL.MatrixMode(MatrixMode.Modelview);
        GL.Pushmatrix();
        GL.LoadIdentity();

        GL.disable(EnableCap.Lighting);
        GL.Enable(EnableCap.Texture2D);

        GL.ActiveTexture(TextureUnit.Texture0);
        GL.BindTexture(TextureTarget.Texture2D,image);
        GL.Uniform1(positionLocation1,0);

        RunShaders();
       
        GL.disable(EnableCap.Texture2D);
        GL.PopMatrix();

        GL.MatrixMode(MatrixMode.Projection);
        GL.PopMatrix();

        GL.MatrixMode(MatrixMode.Modelview);        

    }
    public void RunShaders()
    {
        GL.UseProgram(program);
        **GL.UniformMatrix4(transformlocation,false,ref transformMatrix);**
        GL.DrawArrays(PrimitiveType.Triangles,vertices.Length / 3);
        ErrorCode ec = GL.GetError();
        if (ec != 0)
            System.Console.WriteLine(ec.ToString());
        Console.Read();
    }
    public void Init()
    {
        CreateShaders();
        CreateProgram();        
        InitBuffers();
    }
    public void CreateProgram()
    {
        program = GL.CreateProgram();
        GL.AttachShader(program,vertShader);
        GL.AttachShader(program,fragShader);
        GL.LinkProgram(program);       
    }
    public void InitBuffers()
    {
        buffer = GL.GenBuffer();
        positionLocation = GL.GetAttribLocation(program,"a_position");
        positionLocation1 = GL.GetUniformlocation(program,"sTexture");
        **transformlocation = GL.GetUniformlocation(program,"u_transform");**      
        GL.EnabLevertexAttribArray(positionLocation);
        GL.BindBuffer(BufferTarget.ArrayBuffer,buffer);
        GL.BufferData(BufferTarget.ArrayBuffer,(IntPtr)(vertices.Length * sizeof(float)),vertices,BufferUsageHint.StaticDraw);
        GL.VertexAttribPointer(positionLocation,3,VertexAttribPointerType.Float,0);

    }
    public void CreateShaders()
    {
        /***********Vert Shader********************/
        vertShader = GL.CreateShader(ShaderType.VertexShader);
        GL.ShaderSource(vertShader,@"attribute vec3 a_position;
                                varying vec2 vTexCoord;
                           **uniform mat4 u_transform;**
                                void main() {
                                vTexCoord = (a_position.xy+1)/2 ;  
                                **gl_Position = u_transform * vec4(a_position,1);**
                                }");
        GL.CompileShader(vertShader);

        /***********Frag Shader ****************/
        fragShader = GL.CreateShader(ShaderType.FragmentShader);
        GL.ShaderSource(fragShader,@"precision highp float;
  uniform sampler2D sTexture_2;varying vec2 vTexCoord; 
          void main ()
         {
     vec4 color = texture2D (sTexture_2,vec2(vTexCoord.x,vTexCoord.y));
     gl_FragColor =color;

   }"); GL.CompileShader(fragShader);

    }
  

Degree Ten

解决方法

不要旋转图像,而是旋转和缩放顶点坐标。

将转换矩阵添加到顶点着色器:

attribute vec3 a_position;
varying vec2 vTexCoord;
uniform mat4 u_transform;

void main()
{
    vTexCoord = (a_position.xy+1)/2;
    gl_Position = u_transform * vec4(a_position,1);
}

获取变换矩阵统一形式(``u_transform'')的位置(在程序链接之后)。

int transformLocation = GL.GetUniformLocation(program,"u_transform");

根据角度计算比例尺:

double diagonal = Math.Sqrt(bmp.Width * bmp.Width + bmp.Height * bmp.Height);
double dia_angle1 = Math.Atan2(bmp.Height,bmp.Width) + angle * Math.PI / 180;
double dia_angle2 = Math.Atan2(bmp.Height,-bmp.Width) + angle * Math.PI / 180;
double rot_w = Math.Max(Math.Abs(diagonal * Math.Cos(dia_angle1)),Math.Abs(diagonal * Math.Cos(dia_angle2)));
double rot_h = Math.Max(Math.Abs(diagonal * Math.Sin(dia_angle1)),Math.Abs(diagonal * Math.Sin(dia_angle2)));
double scale = Math.Min(bmp.Width / rot_w,bmp.Height / rot_h);

定义一个缩放矩阵并考虑纵横比来旋转图像:

Matrix4 transformMatrix =
    Matrix4.CreateScale((float)scale) *
    Matrix4.CreateScale(this.Width,this.Height,1.0f) *
    Matrix4.CreateRotationZ((float)(angle * Math.PI / 180)) *
    Matrix4.CreateScale(1.0f / this.Width,1.0f / this.Height,1.0f);

在程序安装后(GL.UseProgram之后)设置矩阵统一:

GL.UniformMatrix4(transformLocation,false,ref transformMatrix);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。