Python OpenGL纹理无法正确加载

时间:2018-11-24 18:33:35

标签: python-3.x opengl

这是我的程序:

import glfw
from OpenGL.GL import *
import OpenGL.GL.shaders
import numpy
from PIL import Image


def main():
    # initialize glfw
    if not glfw.init():
        return

    # creating the window
    window = glfw.create_window(800, 600, "My OpenGL window", None, None)

    if not window:
        glfw.terminate()
        return

    glfw.make_context_current(window)
    #           positions        colors          texture coords
    quad = [-0.5, -0.5, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
            0.5, -0.5, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0,
            0.5, 0.5, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0,
            -0.5, 0.5, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0]

    quad = numpy.array(quad, dtype=numpy.float32)

    indices = [0, 1, 2,
               2, 3, 0]

    indices = numpy.array(indices, dtype=numpy.uint32)

    vertex_shader = """
    #version 330
    in layout(location = 0) vec3 position;
    in layout(location = 1) vec3 color;
    in layout(location = 2) vec2 inTexCoords;
    out vec3 newColor;
    out vec2 outTexCoords;
    void main()
    {
        gl_Position = vec4(position, 1.0f);
        newColor = color;
        outTexCoords = inTexCoords;
    }
    """

    fragment_shader = """
    #version 330
    in vec3 newColor;
    in vec2 outTexCoords;
    out vec4 outColor;
    uniform sampler2D samplerTex;
    void main()
    {
        outColor = texture(samplerTex, outTexCoords);
    }
    """
    shader = OpenGL.GL.shaders.compileProgram(OpenGL.GL.shaders.compileShader(vertex_shader, GL_VERTEX_SHADER),
                                              OpenGL.GL.shaders.compileShader(fragment_shader, GL_FRAGMENT_SHADER))

    VBO = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, VBO)
    glBufferData(GL_ARRAY_BUFFER, 128, quad, GL_STATIC_DRAW)

    EBO = glGenBuffers(1)
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 24, indices, GL_STATIC_DRAW)

    # position = glGetAttribLocation(shader, "position")
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(0))
    glEnableVertexAttribArray(0)

    # color = glGetAttribLocation(shader, "color")
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(12))
    glEnableVertexAttribArray(1)

    # texCoords = glGetAttribLocation(shader, "inTexCoords")
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(24))
    glEnableVertexAttribArray(2)

    texture = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, texture)
    # texture wrapping params
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
    # texture filtering params
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

    image = Image.open("res/crate.jpg")
    img_data = numpy.array(list(image.getdata()), numpy.uint8)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 420, 420, 0, GL_RGB, GL_UNSIGNED_BYTE, img_data)

    glUseProgram(shader)

    glClearColor(0.2, 0.3, 0.2, 1.0)

    while not glfw.window_should_close(window):
        glfw.poll_events()

        glClear(GL_COLOR_BUFFER_BIT)

        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, None)

        glfw.swap_buffers(window)

    glfw.terminate()


if __name__ == "__main__":
    main()

期望:

expectation

结果:

expectation

帮助。

2 个答案:

答案 0 :(得分:1)

加载图像后,图像的格式为'JPEG'

您必须将图像转换为RGB格式

image = image.convert('RGB')

,然后将图像从上到下翻转:

image = image.transpose(Image.FLIP_TOP_BOTTOM)

在加载图像之前,必须将GL_UNPACK_ALIGNMENT设置为glPixelStorei的1,因为图像的行长未对齐4:

image = Image.open("res/crate.jpg") 
image = image.convert('RGB')
image = image.transpose(Image.FLIP_TOP_BOTTOM)    
img_data = numpy.array(list(image.getdata()), numpy.uint8)

glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 420, 420, 0, GL_RGB, GL_UNSIGNED_BYTE, img_data)

当然,您也可以使用RGBA格式:

image = Image.open("res/crate.jpg") 
image = image.convert('RGBA')
image = image.transpose(Image.FLIP_TOP_BOTTOM)    
img_data = numpy.array(list(image.getdata()), numpy.uint8)

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 420, 420, 0, GL_RGBA, GL_UNSIGNED_BYTE, img_data)

答案 1 :(得分:0)

    image = Image.open("res/crate.jpg")
image = image.convert('RGB')
image = image.transpose(Image.FLIP_TOP_BOTTOM)
img_data = np.array(list(image.getdata()), np.uint8)

glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 420, 420, 0, GL_RGB, GL_UNSIGNED_BYTE, img_data)

#image = Image.open("res/crate.jpg")
#image = image.convert('RGBA')
#image = image.transpose(Image.FLIP_TOP_BOTTOM)
#img_data = np.array(list(image.getdata()), np.uint8)

#glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 420, 420, 0, GL_RGBA, GL_UNSIGNED_BYTE, img_data)

这两种方法都能解决我的问题,所以感谢所有帮助过的人