簡體   English   中英

OpenTK-GLSL-用於紋理坐標的BufferData單獨存儲

[英]OpenTK - GLSL - BufferData for texture coordinates stored separately

我試圖在VB.NET的OpenGL 3.3(OpenTK)中進行紋理處理。 但是我在嘗試將紋理映射到Quad時遇到了一個奇怪的問題,導致以下輸出: 輸出

實際圖像是:

原始圖片

該代碼是:

Imports OpenTK
Imports OpenTK.Graphics.OpenGL
Imports System.IO
Imports System.Drawing.Imaging

Public Class Form1



    Private vertices() As Vector3 = {New Vector3(0.5F, 0.5F, 0.0F),
                                     New Vector3(0.5F, -0.5F, 0.0F),
                                     New Vector3(-0.5F, -0.5F, 0.0F),
                                     New Vector3(-0.5F, 0.5F, 0.0F)}

    Private texcoords() As Vector2 = {New Vector2(1.0F, 1.0F),
                                     New Vector2(1.0F, 0.0F),
                                     New Vector2(0.0F, 0.0F),
                                     New Vector2(0.0F, 1.0F)}

    Private indices() As UInteger = {0, 1, 3,
                                    1, 2, 3}

    Private VBO, VAO, EBO As Integer

    Private vert_shader_source, frag_shader_source As String
    Private vertex_shader, fragment_shader, shader_program As Integer

    '--------------
    Private texture As Integer
    Private texture_bmp As New Bitmap("Textures/tex4.jpg")
    Private TBO As Integer


    Private Sub load_texture(ByRef tex_bmp As Bitmap, ByRef texture_index As Integer)

        GL.Enable(EnableCap.Texture2D)

        GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest)

        GL.GenTextures(1, texture_index)
        GL.BindTexture(TextureTarget.Texture2D, texture_index)
        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, CInt(TextureMinFilter.Linear))
        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, CInt(TextureMagFilter.Linear))

        Dim data As BitmapData = tex_bmp.LockBits(New System.Drawing.Rectangle(0, 0, tex_bmp.Width, tex_bmp.Height), ImageLockMode.[ReadOnly], System.Drawing.Imaging.PixelFormat.Format32bppArgb)

        GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0,
    OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0)

        tex_bmp.UnlockBits(data)

    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        vert_shader_source = openShader("Shaders/vertex.glsl")
        frag_shader_source = openShader("Shaders/fragment.glsl")

        createShaders()
        create_handles()

        createVAO()

        '---------------
        load_texture(texture_bmp, texture)

    End Sub

    Sub create_handles()

        VAO = GL.GenVertexArray()
        VBO = GL.GenBuffer()
        EBO = GL.GenBuffer()

        '-------------
        TBO = GL.GenBuffer()

    End Sub

    Private Sub GlControl1_Load(sender As Object, e As EventArgs) Handles GlControl1.Load

    End Sub

    Sub copy_to_gpu()

        GL.BindBuffer(BufferTarget.ArrayBuffer, VBO)
        GL.BufferData(Of Vector3)(BufferTarget.ArrayBuffer, New IntPtr(vertices.Length * Vector3.SizeInBytes),
                                  vertices, BufferUsageHint.StaticDraw)

        GL.BindBuffer(BufferTarget.ElementArrayBuffer, EBO)
        GL.BufferData(BufferTarget.ElementArrayBuffer, New IntPtr(indices.Length * Len(New UInteger)),
                                  indices, BufferUsageHint.StaticDraw)


        '-----------
        GL.BindBuffer(BufferTarget.TextureBuffer, TBO)
        GL.BufferData(Of Vector2)(BufferTarget.TextureBuffer, New IntPtr(texcoords.Length * Vector2.SizeInBytes),
                                  texcoords, BufferUsageHint.StaticDraw)

    End Sub

    Sub link_vertex_attribs()

        GL.EnableVertexAttribArray(0)
        GL.BindBuffer(BufferTarget.ArrayBuffer, VBO)
        GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, False, Vector3.SizeInBytes, 0)

        '-------------
        GL.EnableVertexAttribArray(1)
        GL.BindBuffer(BufferTarget.TextureBuffer, TBO)
        GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, False, Vector3.SizeInBytes, 0)

    End Sub


    Sub createVAO()

        GL.BindVertexArray(VAO)

        copy_to_gpu()
        link_vertex_attribs()

        GL.BindBuffer(BufferTarget.ArrayBuffer, 0)
        GL.BindVertexArray(0)

    End Sub

    Sub createShaders()

        'vertex shader
        vertex_shader = GL.CreateShader(ShaderType.VertexShader)
        GL.ShaderSource(vertex_shader, vert_shader_source)
        GL.CompileShader(vertex_shader)

        'fragment shader
        fragment_shader = GL.CreateShader(ShaderType.FragmentShader)
        GL.ShaderSource(fragment_shader, frag_shader_source)
        GL.CompileShader(fragment_shader)

        'create shader program
        shader_program = GL.CreateProgram()


        'attach shader program
        GL.AttachShader(shader_program, vertex_shader)
        GL.AttachShader(shader_program, fragment_shader)


        'link shader program
        GL.LinkProgram(shader_program)


        GL.DeleteShader(vertex_shader)
        GL.DeleteShader(fragment_shader)

    End Sub

    Function openShader(location As String) As String

        Dim ret As String = ""

        Try
            ' Open the file using a stream reader.
            Using sr As New StreamReader(location)
                Dim line As String
                ' Read the stream to a string and write the string to the console.
                line = sr.ReadToEnd()

                ret &= line
            End Using
        Catch e As Exception
            MsgBox("Error Opening shader", MsgBoxStyle.Critical, "Error")
            Me.Close()
        End Try

        Return ret

    End Function

    Private Sub GlControl1_Paint(sender As Object, e As PaintEventArgs) Handles GlControl1.Paint

        GL.ClearColor(0.2F, 0.3F, 0.3F, 1.0F)
        GL.Clear(ClearBufferMask.ColorBufferBit)

        GL.UseProgram(shader_program)

        ''''''''

        GL.ActiveTexture(TextureUnit.Texture0)
        GL.BindTexture(TextureTarget.Texture2D, texture)
        GL.Uniform1(GL.GetUniformLocation(shader_program, "ourTexture"), 0)

        ''''''''

        GL.BindVertexArray(VAO)

        GL.DrawElements(BeginMode.Triangles, 6, DrawElementsType.UnsignedInt, 0)
        GL.BindVertexArray(0)

        GlControl1.SwapBuffers()


    End Sub

    Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing

        GL.DeleteVertexArray(VAO)
        GL.DeleteBuffer(VBO)
        GL.DeleteBuffer(EBO)

        GL.DeleteTexture(texture)

    End Sub
End Class

我分別存儲頂點數據和紋理坐標,並嘗試使用BufferData將其分別緩沖到GPU。

問題似乎是BufferData無法正常工作。 因為無論我為紋理坐標指定什么值,輸出都不會受到影響!

這是頂點着色器:

#version 330 core

layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoord;

out vec2 TexCoord;

void main()
{
    gl_Position = vec4(position.x, position.y, position.z, 1.0);

    TexCoord = texCoord;
}

片段着色器:

#version 330 core

out vec4 color;

in vec2 TexCoord;
uniform sampler2D ourTexture;

void main()
{
    color = texture(ourTexture, TexCoord);
}

但是,如果我將片段着色器調整為:

color = texture(ourTexture, vec2(TexCoord.x-1.0f,1.0f-TexCoord.y));

可以。但是紋理坐標似乎不會影響輸出。

這里有幾處錯誤

1)存儲紋理坐標的緩沖區不是紋理緩沖區。 紋理緩沖區用於處理紋理數據,而不用於存儲紋理坐標。 紋理坐標是屬性,類似於位置,顏色等,必須存儲在GL_ARRAY_BUFFER

2)由於紋理緩沖區不能用作屬性的輸入,因此對VertexAttribPointer的第二次調用仍使用位置vbo,這將為您提供准確的結果(紋理坐標范圍-0.5至0.5)。 此處還將紋理坐標vbo綁定到GL_ARRAY_BUFFER

3)上傳數據時,您使用2維矢量,但是在VertexAttribPointer調用中,您告訴OpenGL您的數據由3d矢量組成。 正確的代碼是:

GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, False, Vector2.SizeInBytes, 0)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM