Wayland环境下glVertexAttribPointer报无有效上下文如何解决
问题描述
尝试绘制彩色三角形,使用现代OpenGL通过顶点属性数组传输数据。
顶点着色器与片元着色器仅实现颜色从输入到输出的透传逻辑,无特殊代码
问题代码片段:
pg.init() triangle = np.array( triangle, dtype=np.float32 ) triangle_buffer = glGenBuffers( 1 ) glBindBuffer( GL_ARRAY_BUFFER, triangle_buffer ) glBufferData( GL_ARRAY_BUFFER, triangle.nbytes, triangle, GL_STATIC_DRAW ) vertex_shader = compileShader( vertex_src, GL_VERTEX_SHADER ) fragment_shader = compileShader( fragment_src, GL_FRAGMENT_SHADER ) shader_program = compileProgram( vertex_shader, fragment_shader ) glUseProgram( shader_program ) glEnableVertexAttribArray( 0 ) glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, triangle.itemsize * 6, ctypes.c_void_p( 0 ) )
运行时抛出异常:
OpenGL.error.Error: Attempt to retrieve context when no valid context Process finished with exit code 1
问题原因
该报错的核心触发逻辑是:所有OpenGL API调用都依赖当前线程绑定的有效渲染上下文,现有代码仅调用pg.init()完成pygame库本身的初始化,既没有创建支持OpenGL的窗口,也没有生成、绑定对应的OpenGL上下文,因此执行任何OpenGL指令都会抛出上下文不存在的错误。
修复方案
必须把所有OpenGL相关逻辑放到上下文创建完成之后执行,具体初始化流程调整如下:
pg.init()执行完成后,先通过gl_set_attribute配置OpenGL版本、渲染模式等上下文参数,适配现代OpenGL核心模式- 调用
pg.display.set_mode时传入OPENGL、DOUBLEBUF标识创建渲染窗口,该步骤会自动生成匹配配置的OpenGL上下文 - 上下文创建完成后,再执行VBO创建、着色器编译、顶点属性绑定等原有逻辑
修正后的初始化代码参考:
import pygame as pg from pygame.locals import * import numpy as np from OpenGL.GL import * from OpenGL.GL.shaders import compileShader, compileProgram pg.init() # 配置OpenGL上下文参数,版本可根据自身需求调整,这里用3.3核心模式适配现代OpenGL写法 pg.display.gl_set_attribute(pg.GL_CONTEXT_MAJOR_VERSION, 3) pg.display.gl_set_attribute(pg.GL_CONTEXT_MINOR_VERSION, 3) pg.display.gl_set_attribute(pg.GL_CONTEXT_PROFILE_MASK, pg.GL_CONTEXT_PROFILE_CORE) pg.display.gl_set_attribute(pg.GL_DOUBLEBUFFER, 1) # 创建带OpenGL标识的窗口,生成有效上下文 screen = pg.display.set_mode((800, 600), DOUBLEBUF | OPENGL) # 原有OpenGL逻辑放在上下文创建之后即可正常执行 triangle = np.array( triangle, dtype=np.float32 ) triangle_buffer = glGenBuffers( 1 ) glBindBuffer( GL_ARRAY_BUFFER, triangle_buffer ) glBufferData( GL_ARRAY_BUFFER, triangle.nbytes, triangle, GL_STATIC_DRAW ) vertex_shader = compileShader( vertex_src, GL_VERTEX_SHADER ) fragment_shader = compileShader( fragment_src, GL_FRAGMENT_SHADER ) shader_program = compileProgram( vertex_shader, fragment_shader ) glUseProgram( shader_program ) glEnableVertexAttribArray( 0 ) glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, triangle.itemsize * 6, ctypes.c_void_p( 0 ) ) # 补充说明:目前代码只绑定了位置顶点属性,要实现彩色三角形需要额外绑定颜色属性,偏移量为位置数据长度即triangle.itemsize*3
内容的提问来源于stack exchange,提问作者vasya-gaikin
相关产品推荐
相关产品推荐

