OpenGL C#纹理对齐/拉伸不良

时间:2016-05-19 09:03:07

标签: c# opengl

我是OpenGL的新手,我一直在解决纹理错位/拉伸的问题。纹理大小为256x256,类型为png。

左边是一个四边形,有2个三角形,纹理正确, 在右边是一个自定义平面,有16个四边形全部三角形。

从图片中可以看出,即使我应该正确分配了所有的UV,纹理也不能正确贴合在脸部。

这是所有顶点,UV以及面如何形成的图片。 (在新标签中打开以获得更大的图片):

以下是我如何开始使用我的OpenGL视图的代码片段:

public void Start(){
        Glut.glutInit();
        Glut.glutInitDisplayMode(Glut.GLUT_DOUBLE | Glut.GLUT_DEPTH);
        Glut.glutInitWindowSize(_width, _height);
        Glut.glutCreateWindow("OpenGL View");

        //Gl.ReloadFunctions();

        texture = new Texture("water.png");

        //Define functions
        Glut.glutIdleFunc(OnRenderFrame);
        Glut.glutDisplayFunc(OnDisplay);
        Glut.glutMouseFunc(OnMouse);
        Glut.glutMotionFunc(OnMove);
        Glut.glutCloseFunc(OnClose);


        program = new ShaderProgram(VertexShader, FragmentShader);
        program["projection_matrix"].SetValue(Matrix4.CreatePerspectiveFieldOfView(0.45f,
            (float)_width / _height, 0.1f, 1000f));

        program.Use();

        Glut.glutSetOption(Glut.GLUT_ACTION_ON_WINDOW_CLOSE, Glut.GLUT_ACTION_CONTINUE_EXECUTION);
        Glut.glutMainLoop();
}

private static void OnRenderFrame()
    {
        Gl.Viewport(0, 0, _width, _height);
        Gl.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

        Gl.UseProgram(program);

        Gl.Enable(EnableCap.Texture2D);
        Gl.BindTexture(texture);

        Matrix4 transform = Matrix4.CreateRotationY(yangle) * Matrix4.CreateRotationX(xangle)
                            * Matrix4.CreateTranslation(translationVector);

        program["model_matrix"].SetValue(transform);
        program["view_matrix"].SetValue(Matrix4.LookAt(
            new Vector3(0, 0, viewZoom), Vector3.Zero,Vector3.Up));

        //Bind Vertices and Vertex indices
        Gl.BindBufferToShaderAttribute(_model, program, "vertexPosition");
        Gl.BindBufferToShaderAttribute(_modelUV, program, "vertexUV");
        Gl.BindBuffer(_model);
        Gl.BindBuffer(_modelFaces);

        Gl.DrawElements(BeginMode.Triangles, _modelFaces.Count, DrawElementsType.UnsignedInt,
                        IntPtr.Zero);

        Glut.glutSwapBuffers();
    }

    public static string VertexShader = @"
in vec3 vertexPosition;
in vec2 vertexUV;

out vec2 uv;

uniform mat4 projection_matrix;
uniform mat4 view_matrix;
uniform mat4 model_matrix;

void main(void)
{
    gl_Position = projection_matrix * view_matrix * model_matrix * vec4(vertexPosition,1);
    uv = vertexUV;
}
";
    public static string FragmentShader = @"

uniform sampler2D texture;

in vec2 uv;

out vec4 fragment;

void main(void)
{
    fragment = texture2D(texture, uv);
}
";

我似乎无法确定问题,UV看起来都很好,即使它们不正确,它们也不应该拉伸并重复纹理,因为它们在0和1的范围内。 / p>

1 个答案:

答案 0 :(得分:0)

问题在于我将UV分配给视频卡的内存。

这就是我加载模型的方式:

public void SetModel(Vector3[] modelVertices, int[] modelFaces, Vector2[] modelUV)
    {
        _model = new VBO<Vector3>(modelVertices);
        _modelFaces = new VBO<int>(modelFaces, BufferTarget.ElementArrayBuffer);
        _modelUV = new VBO<Vector2>(modelUV, BufferTarget.TextureBuffer);
    }

这就是它应该如何:

public void SetModel(Vector3[] modelVertices, int[] modelFaces, Vector2[] modelUV)
    {
        _model = new VBO<Vector3>(modelVertices);
        _modelFaces = new VBO<int>(modelFaces, BufferTarget.ElementArrayBuffer);
        _modelUV = new VBO<Vector2>(modelUV);
    }

当我在TextureBuffer中使用BufferTarget将向量分配给VBO时,它会翻转出来。解决方法是删除参数,以便BufferTarget默认为ArrayBuffer。

我还通过删除无顶点的顶点来编辑我的渲染功能:

private static void OnRenderFrame()
    {
        Gl.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

        Gl.UseProgram(program);


        Matrix4 transform = Matrix4.CreateRotationY(yangle) * Matrix4.CreateRotationX(xangle)
                            * Matrix4.CreateTranslation(translationVector);

        Gl.BindTexture(texture);

        program["model_matrix"].SetValue(transform);
        program["view_matrix"].SetValue(Matrix4.LookAt(
            new Vector3(0, 0, viewZoom), Vector3.Zero,Vector3.Up));


        Gl.BindBufferToShaderAttribute(_model, program, "vertexPosition");
        Gl.BindBufferToShaderAttribute(_modelUV, program, "vertexUV");

        Gl.BindBuffer(_modelFaces);


        Gl.DrawElements(BeginMode.Triangles, _modelFaces.Count, DrawElementsType.UnsignedInt,
                        IntPtr.Zero);

        Glut.glutSwapBuffers();

    }