Python OpenGL 不会加载纹理

Python OpenGL will not load texture

我正在学习一个教程系列,其中我们在 Python OpenGL 中制作了一个带有纹理的立方体。出于某种原因,当我 运行 代码时,它会产生一个空白屏幕,这是最奇怪的。请帮助我,我迷路了,最后期限快到了。

在上一个中,我不得不添加一些 window 提示和一个顶点数组对象,由于一些愚蠢的原因,本教程没有包含这些对象。有什么我需要change/add的吗,因为我真的卡住了。

import glfw
from OpenGL.GL import *
from OpenGL.GL.shaders import compileProgram, compileShader
import numpy as np
import pyrr
from PIL import Image


vertex_src = """

# version 330

layout(location = 0) in vec3 a_position;
layout(location = 1) in vec3 a_color;
layout(location = 2) in vec2 a_texture;

uniform mat4 rotation;

out vec3 v_color;
out vec2 v_texture;

void main()
{
    gl_Position = rotation * vec4(a_position, 1.0);
    v_color = a_color;
    v_texture = a_texture;

    //v_texture = 1 - a_texture;                        //Flips the texture vertically and horizontally
    //v_texture = vec2(a_texture.s, 1 - a_texture.t);   //Flips the texture vertically
}

"""


fragment_src = """

#version 330

in vec3 v_color;
in vec2 v_texture;

out vec4 out_color;

uniform sampler2D s_texture;

void main()
{
    out_color = texture(s_texture, v_texture);  // * vec4(v_color, 1.0f);
}

"""



#glfw callback functions
def window_resize(window, width, height):
    glViewport(0, 0, width, height)


#initialising glfw library
if not glfw.init():
    raise Exception("glfw cannot be initialised")



glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 2)
glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, GL_TRUE)
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)


#creating the window
window = glfw.create_window(1280, 720, "My OpenGL Window", None, None)


#Check if window was created
if not window:
    glfw.terminate()
    raise Exception("glfw window cannot be created!")


glfw.set_window_pos(window, 400, 200)
glfw.set_window_size_callback(window, window_resize)
glfw.make_context_current(window)


vertices = [
-0.5, -0.5, 0.5,   1.0, 0.0, 0.0,   0.0, 0.0,
0.5, -0.5, 0.5,   0.0, 1.0, 0.0,   1.0, 0.0,
0.5, -0.5, 0.5,   0.0, 0.0, 1.0,   1.0, 1.0,
-0.5, 0.5, 0.5,   1.0, 1.0, 1.0,   0.0, 1.0,

-0.5, -0.5, -0.5,   1.0, 0.0, 0.0,   0.0, 0.0,
0.5, -0.5, -0.5,   0.0, 1.0, 0.0,   1.0, 0.0,
0.5, 0.5, -0.5,   0.0, 0.0, 1.0,   1.0, 1.0,
0.5, 0.5, -0.5,   1.0, 1.0, 1.0,   0.0, 1.0,

0.5, -0.5, -0.5,   1.0, 0.0, 0.0,   0.0, 0.0,
0.5, 0.5, -0.5,   0.0, 1.0, 0.0,   1.0, 0.0,
0.5, 0.5, 0.5,   0.0, 0.0, 1.0,   1.0, 1.0,
0.5, -0.5, 0.5,   1.0, 1.0, 1.0,   0.0, 1.0,

-0.5, 0.5, -0.5,   1.0, 0.0, 0.0,   0.0, 0.0,
-0.5, -0.5, -0.5,   0.0, 1.0, 0.0,   1.0, 0.0,
-0.5, -0.5, 0.5,   0.0, 0.0, 1.0,   1.0, 1.0,
-0.5, 0.5, 0.5,   1.0, 1.0, 1.0,   0.0, 1.0,

-0.5, -0.5, -0.5,   1.0, 0.0, 0.0,   0.0, 0.0,
0.5, -0.5, -0.5,   0.0, 1.0, 0.0,   1.0, 0.0,
0.5, -0.5, 0.5,   0.0, 0.0, 1.0,   1.0, 1.0,
-0.5, -0.5, 0.5,   1.0, 1.0, 1.0,   0.0, 1.0,

0.5, 0.5, -0.5,   1.0, 0.0, 0.0,   0.0, 0.0,
-0.5, 0.5, -0.5,   0.0, 1.0, 0.0,   1.0, 0.0,
-0.5, 0.5, 0.5,   0.0, 0.0, 1.0,   1.0, 1.0,
0.5, 0.5, 0.5,   1.0, 1.0, 1.0,   0.0, 1.0,
]


indices = [
0, 1, 2, 2, 3, 0,
4, 5, 6, 6, 7, 4,
8, 9, 10, 10, 11, 8,
12, 13, 14, 14, 15, 12,
16, 17, 18, 18, 19, 16,
20, 21, 22, 22, 23, 20
]


vertices = np.array(vertices, dtype=np.float32)
indices = np.array(indices, dtype=np.uint32)

shader = compileProgram(compileShader(vertex_src, GL_VERTEX_SHADER), compileShader(fragment_src, GL_FRAGMENT_SHADER))


VBO = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, VBO)
glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, vertices, GL_STATIC_DRAW)

#Vertex array object
VAO = glGenVertexArrays(1)
glBindVertexArray(VAO)

glEnableVertexAttribArray(0)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertices.itemsize * 8, ctypes.c_void_p(0))

glEnableVertexAttribArray(1)
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertices.itemsize * 8, ctypes.c_void_p(12))

glEnableVertexAttribArray(2)
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, vertices.itemsize * 8, ctypes.c_void_p(24))

texture = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texture)



glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)


image = Image.open("my_pic.png")
image = image.transpose(Image.FLIP_TOP_BOTTOM)

img_data = image.convert("RGBA").tobytes()
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width, image.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img_data)

glUseProgram(shader)
glClearColor(0, 0.1, 0.3, 1)
glEnable(GL_DEPTH_TEST)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)


rotation_loc = glGetUniformLocation(shader, "rotation")


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

    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)

    rot_x = pyrr.Matrix44.from_x_rotation(0.5 * glfw.get_time())
    rot_y = pyrr.Matrix44.from_y_rotation(0.8 * glfw.get_time())

    glUniformMatrix4fv(rotation_loc, 1, GL_FALSE, pyrr.matrix44.multiply(rot_x, rot_y))

    glDrawElements(GL_TRIANGLES, len(indices), GL_UNSIGNED_INT, None)

    glfw.swap_buffers(window)


glfw.terminate()

glDrawElements render primitives specified by the indexes in the index buffer. You missed the Index buffers (GL_ELEMENT_ARRAY_BUFFER)。由于索引缓冲区是在顶点数组对象中声明的,所以在创建和绑定VAO之前必须先创建和绑定:

AO = glGenVertexArrays(1)
glBindVertexArray(VAO)

IBO = glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.nbytes, indices, GL_STATIC_DRAW)