使用 PyOpenGL 在 Pygame 中渲染图像
Rendering Image in Pygame Using PyOpenGL
我正在为我学校的计算机科学俱乐部开展一个项目,同时尝试学习 Pygame/PyOpenGL。
现在我只是想做一些基本的事情。我正在尝试使用 Pygame 和 PyOpenGL 在 window 中渲染图像。这是我的代码的 link(我不确定 Github 存储库是否正常)。
请求的代码(在 github 上阅读起来更容易):
import pygame
from OpenGL.GL import *
from OpenGL.GL import shaders
import unittest
import numpy as np
from ctypes import sizeof, c_float, c_void_p
def renderSplash(image):
# using resources in open gl generally follows the form of generate, bind, modify
# Generate: request a buffer for our vertices
vbo = glGenBuffers(1)
# Bind: set the newly requested buffer as the active GL_ARRAY_BUFFER.
# All subsequent modifications of GL_ARRAY_BUFFER will affect our vbo
glBindBuffer(GL_ARRAY_BUFFER, vbo)
# Modify: Tell OpenGL to load data into the buffer.
# I've added two more coordinates to each vertex here for determining the position within the texture.
# These two additional coordinates are typically refered to as uv coordinates.
# Also there are now two triangles that cover the entire viewport.
vertex_data = np.array([-1, -1, 0, 0, -1, 1, 0, 1, 1, 1, 1, 1, -1, -1, 0, 0, 1, 1, 1, 1, 1, -1, 1, 0], np.float32)
glBufferData(GL_ARRAY_BUFFER, vertex_data, GL_STATIC_DRAW)
vertex_position_attribute_location = 0
uv_attribute_location = 1
# glVertexAttribPointer basically works in the same way as glVertexPointer with two exceptions:
# First, it can be used to set the data source for any vertex attributes.
# Second, it has an option to normalize the data, which I have set to GL_FALSE.
glVertexAttribPointer(vertex_position_attribute_location, 2, GL_FLOAT, GL_FALSE, sizeof(c_float)*4, c_void_p(0))
# vertex attributes need to be enabled
glEnableVertexAttribArray(0)
glVertexAttribPointer(uv_attribute_location, 2, GL_FLOAT, GL_FALSE, sizeof(c_float)*4, c_void_p(sizeof(c_float)*2))
glEnableVertexAttribArray(1)
# Generate: request a texture
image_texture = glGenTextures(1)
# Bind: set the newly requested texture as the active GL_TEXTURE_2D.
# All subsequent modifications of GL_TEXTURE_2D will affect our texture (or how it is used)
glBindTexture(GL_TEXTURE_2D, image_texture)
width = image.get_width()
height = image.get_height()
# retrieve a byte string representation of the image.
# The 3rd parameter tells pygame to return a vertically flipped image, as the coordinate system used
# by pygame differs from that used by OpenGL
image_data = pygame.image.tostring(image, "RGBA", True)
# Modify: Tell OpenGL to load data into the image
mip_map_level = 0
glTexImage2D(GL_TEXTURE_2D, mip_map_level, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data)
# set the filtering mode for the texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
vertex_shader = shaders.compileShader("""
#version 330
layout(location = 0) in vec2 pos;
layout(location = 1) in vec2 uvIn;
out vec2 uv;
void main() {
gl_Position = vec4(pos, 0, 1);
uv = uvIn;
}
""", GL_VERTEX_SHADER)
fragment_shader = shaders.compileShader("""
#version 330
out vec4 fragColor;
in vec2 uv;
uniform sampler2D tex;
void main() {
fragColor = texture(tex, uv);
}
""", GL_FRAGMENT_SHADER)
shader_program = shaders.compileProgram(vertex_shader, fragment_shader)
glEnableClientState(GL_VERTEX_ARRAY)
# Enable alpha blending
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glUseProgram(shader_program)
glDrawArrays(GL_TRIANGLES, 0, 6)
def main():
pygame.quit()
pygame.init()
image = pygame.image.load("Background.jpg")
width = image.get_width()
height = image.get_height()
# width = 1920
# height = 1080
size = (width,height)
pygame.display.set_mode(size, pygame.OPENGL | pygame.DOUBLEBUF | pygame.HWSURFACE)
glViewport(0, 0, width, height)
renderSplash(image)
pygame.display.flip()
close_window()
def close_window():
key_pressed = False
while not key_pressed:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
key_pressed = True
main()
我的问题是当我 运行 SplashScreen.py 在我的桌面上(Win10 Pro,1903,OS Build 18362.86,Python 3.7.2)我得到以下信息
按要求以文本格式输出:
pygame 1.9.6
Hello from the pygame community. https://www.pygame.org/contribute.html
Traceback (most recent call last):
File "SplashScreen.py", line 122, in <module>
main()
File "SplashScreen.py", line 111, in main
renderSplash(image)
File "SplashScreen.py", line 95, in renderSplash
glDrawArrays(GL_TRIANGLES, 0, 6)
File "C:\Users\LukeJ\AppData\Roaming\Python\Python37\site-packages\OpenGL\platform\baseplatform.py", line 402, in __call__
return self( *args, **named )
OSError: exception: access violation reading 0x0000000000000000
但是如果我 运行 我的笔记本电脑上的这段代码(Win10 Pro,1903,OS Build 18362.86,Python 3.7.2),它工作正常。
我的代码是不是做错了什么?我需要做什么来测试这个问题并希望在我的代码中修复它?
删除
glEnableClientState(GL_VERTEX_ARRAY)
您的代码将起作用。
glEnableClientState(GL_VERTEX_ARRAY)
enables the client-side capability for vertex coordinates, it activates the deprecated fixed function attribute and is related to Legacy OpenGL.
这抵消了顶点属性规范和 glEnableVertexAttribArray(0)
.
固定函数顶点坐标必须由 glVertexPointer
rather than glVertexAttribPointer
定义。 "access violation reading 0x0000000000000000"出现,因为没有固定函数函数顶点数据集,但是启用了。
我正在为我学校的计算机科学俱乐部开展一个项目,同时尝试学习 Pygame/PyOpenGL。
现在我只是想做一些基本的事情。我正在尝试使用 Pygame 和 PyOpenGL 在 window 中渲染图像。这是我的代码的 link(我不确定 Github 存储库是否正常)。
请求的代码(在 github 上阅读起来更容易):
import pygame
from OpenGL.GL import *
from OpenGL.GL import shaders
import unittest
import numpy as np
from ctypes import sizeof, c_float, c_void_p
def renderSplash(image):
# using resources in open gl generally follows the form of generate, bind, modify
# Generate: request a buffer for our vertices
vbo = glGenBuffers(1)
# Bind: set the newly requested buffer as the active GL_ARRAY_BUFFER.
# All subsequent modifications of GL_ARRAY_BUFFER will affect our vbo
glBindBuffer(GL_ARRAY_BUFFER, vbo)
# Modify: Tell OpenGL to load data into the buffer.
# I've added two more coordinates to each vertex here for determining the position within the texture.
# These two additional coordinates are typically refered to as uv coordinates.
# Also there are now two triangles that cover the entire viewport.
vertex_data = np.array([-1, -1, 0, 0, -1, 1, 0, 1, 1, 1, 1, 1, -1, -1, 0, 0, 1, 1, 1, 1, 1, -1, 1, 0], np.float32)
glBufferData(GL_ARRAY_BUFFER, vertex_data, GL_STATIC_DRAW)
vertex_position_attribute_location = 0
uv_attribute_location = 1
# glVertexAttribPointer basically works in the same way as glVertexPointer with two exceptions:
# First, it can be used to set the data source for any vertex attributes.
# Second, it has an option to normalize the data, which I have set to GL_FALSE.
glVertexAttribPointer(vertex_position_attribute_location, 2, GL_FLOAT, GL_FALSE, sizeof(c_float)*4, c_void_p(0))
# vertex attributes need to be enabled
glEnableVertexAttribArray(0)
glVertexAttribPointer(uv_attribute_location, 2, GL_FLOAT, GL_FALSE, sizeof(c_float)*4, c_void_p(sizeof(c_float)*2))
glEnableVertexAttribArray(1)
# Generate: request a texture
image_texture = glGenTextures(1)
# Bind: set the newly requested texture as the active GL_TEXTURE_2D.
# All subsequent modifications of GL_TEXTURE_2D will affect our texture (or how it is used)
glBindTexture(GL_TEXTURE_2D, image_texture)
width = image.get_width()
height = image.get_height()
# retrieve a byte string representation of the image.
# The 3rd parameter tells pygame to return a vertically flipped image, as the coordinate system used
# by pygame differs from that used by OpenGL
image_data = pygame.image.tostring(image, "RGBA", True)
# Modify: Tell OpenGL to load data into the image
mip_map_level = 0
glTexImage2D(GL_TEXTURE_2D, mip_map_level, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data)
# set the filtering mode for the texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
vertex_shader = shaders.compileShader("""
#version 330
layout(location = 0) in vec2 pos;
layout(location = 1) in vec2 uvIn;
out vec2 uv;
void main() {
gl_Position = vec4(pos, 0, 1);
uv = uvIn;
}
""", GL_VERTEX_SHADER)
fragment_shader = shaders.compileShader("""
#version 330
out vec4 fragColor;
in vec2 uv;
uniform sampler2D tex;
void main() {
fragColor = texture(tex, uv);
}
""", GL_FRAGMENT_SHADER)
shader_program = shaders.compileProgram(vertex_shader, fragment_shader)
glEnableClientState(GL_VERTEX_ARRAY)
# Enable alpha blending
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glUseProgram(shader_program)
glDrawArrays(GL_TRIANGLES, 0, 6)
def main():
pygame.quit()
pygame.init()
image = pygame.image.load("Background.jpg")
width = image.get_width()
height = image.get_height()
# width = 1920
# height = 1080
size = (width,height)
pygame.display.set_mode(size, pygame.OPENGL | pygame.DOUBLEBUF | pygame.HWSURFACE)
glViewport(0, 0, width, height)
renderSplash(image)
pygame.display.flip()
close_window()
def close_window():
key_pressed = False
while not key_pressed:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
key_pressed = True
main()
我的问题是当我 运行 SplashScreen.py 在我的桌面上(Win10 Pro,1903,OS Build 18362.86,Python 3.7.2)我得到以下信息
按要求以文本格式输出:
pygame 1.9.6
Hello from the pygame community. https://www.pygame.org/contribute.html
Traceback (most recent call last):
File "SplashScreen.py", line 122, in <module>
main()
File "SplashScreen.py", line 111, in main
renderSplash(image)
File "SplashScreen.py", line 95, in renderSplash
glDrawArrays(GL_TRIANGLES, 0, 6)
File "C:\Users\LukeJ\AppData\Roaming\Python\Python37\site-packages\OpenGL\platform\baseplatform.py", line 402, in __call__
return self( *args, **named )
OSError: exception: access violation reading 0x0000000000000000
但是如果我 运行 我的笔记本电脑上的这段代码(Win10 Pro,1903,OS Build 18362.86,Python 3.7.2),它工作正常。
我的代码是不是做错了什么?我需要做什么来测试这个问题并希望在我的代码中修复它?
删除
glEnableClientState(GL_VERTEX_ARRAY)
您的代码将起作用。
glEnableClientState(GL_VERTEX_ARRAY)
enables the client-side capability for vertex coordinates, it activates the deprecated fixed function attribute and is related to Legacy OpenGL.
这抵消了顶点属性规范和 glEnableVertexAttribArray(0)
.
固定函数顶点坐标必须由 glVertexPointer
rather than glVertexAttribPointer
定义。 "access violation reading 0x0000000000000000"出现,因为没有固定函数函数顶点数据集,但是启用了。