下面是我目前的代码:
main.py -
from Application import Application
if __name__ == '__main__':
app = Application()
app.run()
Triangle.py -
import contextlib
import logging as log
from OpenGL import GL as gl
import ctypes
import sys
class Triangle:
vertex_array_id = 0
vertex_data = []
program_id = 0
shader_id = 0
def __init__(self):
print('Triangle.__init__(self)')
self.create_vertex_buffer()
self.load_shaders()
def create_vertex_array_object(self):
log.debug('create_vertex_array_object(self):')
self.vertex_array_id = gl.glGenVertexArrays(1)
try:
gl.glBindVertexArray(self.vertex_array_id)
yield
finally:
log.debug('~create_vertex_array_object(self):')
gl.glDeleteVertexArrays(1, [self.vertex_array_id])
def create_vertex_buffer(self):
with self.create_vertex_array_object():
# A triangle
self.vertex_data = [-1, -1, 0,
1, -1, 0,
0, 1, 0]
attr_id = 0 # No particular reason for 0,
# but must match the layout location in the shader.
log.debug('creating and binding the vertex buffer (VBO)')
vertex_buffer = gl.glGenBuffers(1)
try:
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vertex_buffer)
array_type = (gl.GLfloat * len(self.vertex_data))
gl.glBufferData(gl.GL_ARRAY_BUFFER,
len(self.vertex_data) * ctypes.sizeof(ctypes.c_float),
array_type(*self.vertex_data),
gl.GL_STATIC_DRAW)
log.debug('setting the vertex attributes')
gl.glVertexAttribPointer(
attr_id, # attribute 0.
3, # components per vertex attribute
gl.GL_FLOAT, # type
False, # to be normalized?
0, # stride
None # array buffer offset
)
gl.glEnableVertexAttribArray(attr_id) # use currently bound VAO
yield
finally:
log.debug('cleaning up buffer')
# gl.glDisableVertexAttribArray(attr_id)
# gl.glDeleteBuffers(1, [vertex_buffer])
def load_shaders(self):
shaders = {
gl.GL_VERTEX_SHADER: '''\
#version 330 core
layout(location = 0) in vec3 vertexPosition_modelspace;
void main(){
gl_Position.xyz = vertexPosition_modelspace;
gl_Position.w = 1.0;
}
''',
gl.GL_FRAGMENT_SHADER: '''\
#version 330 core
out vec3 color;
void main(){
color = vec3(1,0,0);
}
'''
}
log.debug('creating the shader program')
self.program_id = gl.glCreateProgram()
try:
shader_ids = []
for shader_type, shader_src in shaders.items():
self.shader_id = gl.glCreateShader(shader_type)
gl.glShaderSource(self.shader_id, shader_src)
log.debug(f'compiling the {shader_type} shader')
gl.glCompileShader(self.shader_id)
# check if compilation was successful
result = gl.glGetShaderiv(self.shader_id, gl.GL_COMPILE_STATUS)
info_log_len = gl.glGetShaderiv(self.shader_id, gl.GL_INFO_LOG_LENGTH)
if info_log_len:
logmsg = gl.glGetShaderInfoLog(self.shader_id)
log.error(logmsg)
sys.exit(10)
gl.glAttachShader(self.program_id, self.shader_id)
shader_ids.append(self.shader_id)
log.debug('linking shader program')
gl.glLinkProgram(self.program_id)
# check if linking was successful
result = gl.glGetProgramiv(self.program_id, gl.GL_LINK_STATUS)
info_log_len = gl.glGetProgramiv(self.program_id, gl.GL_INFO_LOG_LENGTH)
if info_log_len:
logmsg = gl.glGetProgramInfoLog(self.program_id)
log.error(logmsg)
sys.exit(11)
log.debug('installing shader program into rendering state')
gl.glUseProgram(self.program_id)
yield
finally:
log.debug('cleaning up shader program')
for self.shader_id in self.shader_ids:
gl.glDetachShader(self.program_id, self.shader_id)
gl.glDeleteShader(self.shader_id)
gl.glUseProgram(0)
gl.glDeleteProgram(self.program_id)
def render(self):
gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3) # Starting from vertex 0
Application.py -
import contextlib
import glfw
import sys
from OpenGL import GL as gl
import logging as log
from Triangle import Triangle
class Application:
tri = Triangle()
def __init__(self):
print("Application.__init__(self)")
@contextlib.contextmanager
def create_main_window(self):
log.debug('create_main_window(self):')
if not glfw.init():
sys.exit(1)
try:
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, True)
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
title = 'Tutorial 2: First Triangle'
window = glfw.create_window(500, 400, title, None, None)
if not window:
sys.exit(2)
glfw.make_context_current(window)
gl.glClearColor(0, 0, 0.4, 0)
yield window
finally:
log.debug('~create_main_window(self):')
glfw.terminate()
def main_loop(self, window):
while (
glfw.get_key(window, glfw.KEY_ESCAPE) != glfw.PRESS and
not glfw.window_should_close(window)
):
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
self.tri.render()
glfw.swap_buffers(window)
glfw.poll_events()
def run(self):
log.basicConfig(level=log.DEBUG)
with self.create_main_window() as window:
self.main_loop(window)
从控制台上,我看到了以下内容:
DEBUG:root:create_main_window(self):
Triangle.__init__(self)
Application.__init__(self)
DEBUG:root:~create_main_window(self):
Traceback (most recent call last):
File "C:\Users\prussos\PycharmProjects\pythonProject3\main.py", line 5, in <module>
app.run()
File "C:\Users\prussos\PycharmProjects\pythonProject3\Application.py", line 51, in run
self.main_loop(window)
File "C:\Users\prussos\PycharmProjects\pythonProject3\Application.py", line 44, in main_loop
self.tri.render()
File "C:\Users\prussos\PycharmProjects\pythonProject3\Triangle.py", line 131, in render
gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3) # Starting from vertex 0
File "C:\Users\prussos\PycharmProjects\pythonProject3\venv\lib\site-packages\OpenGL\platform\baseplatform.py", line 415, in __call__
return self( *args, **named )
File "C:\Users\prussos\PycharmProjects\pythonProject3\venv\lib\site-packages\OpenGL\error.py", line 230, in glCheckError
raise self._errorClass(
OpenGL.error.GLError: GLError(
err = 1282,
description = b'invalid operation',
baseOperation = glDrawArrays,
cArguments = (GL_TRIANGLES, 0, 3)
)
Process finished with exit code 1
似乎有一个绘图错误正在发生,但我真的不太清楚如何开始解决这个问题。代码从gitlabs转移到一个基于类的系统为python。所以,一个绘制数组,这是一个无效的操作什么可能是来自OpenGL库的人足够熟悉它知道什么地方编辑这里?
1条答案
按热度按时间cygmwpex1#
调用OpenGL指令时,需要一个有效的最新OpenGL上下文。OpenGL上下文是用OpenGl窗口创建的。OpenGL对象( VAO 、VBO和着色器)是在
Triangle
类的构造函数中创建的。因此,只有在创建OpenGL窗口后,才能构造此类的对象: