【问题标题】:OpenGL C# Bad texture alignment / stretchingOpenGL C#错误的纹理对齐/拉伸
【发布时间】:2016-05-20 19:59:27
【问题描述】:

我是 OpenGL 新手,我一直在与纹理未对齐/拉伸问题作斗争。纹理大小为 256x256,类型为 png。

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

正如您从图片中看到的那样,即使我应该正确分配所有的 UV,纹理也不能正确地贴合面部。

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

以下是我如何启动和使用 OpenGL 视图的代码 sn-p:

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 的范围内。

【问题讨论】:

    标签: c# opengl


    【解决方案1】:

    问题在于我将 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();
    
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-28
      • 1970-01-01
      • 2014-07-21
      • 2015-02-03
      • 1970-01-01
      • 1970-01-01
      • 2020-01-27
      • 1970-01-01
      相关资源
      最近更新 更多