fix(shader): Add proper VAO setup for OpenGL 3.3 core profile

- Create _create_quad_vao() method that creates VAO with vertex buffer
- Use explicit vertex attributes (a_position, a_texcoord) in shaders
- Bind VAO before glDrawArrays calls
- Use ctypes for proper buffer sizing
This commit is contained in:
2026-03-13 21:35:23 -04:00
parent 1d36357c64
commit aed461ef28
2 changed files with 42 additions and 28 deletions

View File

@@ -162,6 +162,7 @@ class BlurPipeline:
self.h_blur_program: int | None = None
self.v_blur_program: int | None = None
self.deepsea_program: int | None = None
self._quad_vao: int | None = None
self._fb_width: int = 0
self._fb_height: int = 0
self._fb_scale: int = 1
@@ -209,6 +210,26 @@ class BlurPipeline:
gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
return fbo, tex
def _create_quad_vao(self) -> int:
import ctypes
vao = gl.glGenVertexArrays(1)
gl.glBindVertexArray(vao)
vertices = (ctypes.c_float * 16)(
-1.0, -1.0, 0.0, 0.0,
1.0, -1.0, 1.0, 0.0,
-1.0, 1.0, 0.0, 1.0,
1.0, 1.0, 1.0, 1.0
)
vbo = gl.glGenBuffers(1)
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo)
gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(vertices), vertices, gl.GL_STATIC_DRAW)
gl.glEnableVertexAttribArray(0)
gl.glVertexAttribPointer(0, 2, gl.GL_FLOAT, gl.GL_FALSE, 16, None)
gl.glEnableVertexAttribArray(1)
gl.glVertexAttribPointer(1, 2, gl.GL_FLOAT, gl.GL_FALSE, 16, ctypes.c_void_p(8))
gl.glBindVertexArray(0)
return vao
def setup_fbos(self, width: int, height: int, fb_scale: float = 1.0):
scale = max(1, int(fb_scale))
blur_w = max(1, (width * scale) // 4)
@@ -225,8 +246,8 @@ class BlurPipeline:
def compile_blur_shaders(self):
vert_src = """
#version 330 core
in vec2 a_position;
in vec2 a_texcoord;
layout(location = 0) in vec2 a_position;
layout(location = 1) in vec2 a_texcoord;
out vec2 v_uv;
void main() {
gl_Position = vec4(a_position, 0.0, 1.0);
@@ -289,8 +310,8 @@ void main() {
def compile_deepsea_shader(self):
vert_src = """
#version 330 core
in vec2 a_position;
in vec2 a_texcoord;
layout(location = 0) in vec2 a_position;
layout(location = 1) in vec2 a_texcoord;
out vec2 v_uv;
void main() {
gl_Position = vec4(a_position, 0.0, 1.0);
@@ -356,9 +377,10 @@ void main() {
}
"""
self.deepsea_program = self._compile_shader(vert_src, frag_src)
self._quad_vao = self._create_quad_vao()
def render_deepsea_to_fbo(self, width: int, height: int, time: float):
if not self.deepsea_program or not self.scene_fbo:
if not self.deepsea_program or not self.scene_fbo or not self._quad_vao:
return
scene_w = width * self._fb_scale
scene_h = height * self._fb_scale
@@ -367,19 +389,15 @@ void main() {
gl.glClearColor(0.01, 0.05, 0.12, 1.0)
gl.glClear(gl.GL_COLOR_BUFFER_BIT)
gl.glUseProgram(self.deepsea_program)
u_time = gl.glGetUniformLocation(self.deepsea_program, "u_time")
if u_time != -1:
gl.glUniform1f(u_time, time)
u_res = gl.glGetUniformLocation(self.deepsea_program, "u_resolution")
if u_res != -1:
gl.glUniform2f(u_res, float(scene_w), float(scene_h))
# Draw fullscreen quad using deprecated but working glBegin/glEnd
gl.glBegin(gl.GL_TRIANGLE_STRIP)
gl.glVertex2f(-1.0, -1.0); gl.glTexCoord2f(0.0, 0.0)
gl.glVertex2f( 1.0, -1.0); gl.glTexCoord2f(1.0, 0.0)
gl.glVertex2f(-1.0, 1.0); gl.glTexCoord2f(0.0, 1.0)
gl.glVertex2f( 1.0, 1.0); gl.glTexCoord2f(1.0, 1.0)
gl.glEnd()
u_time_loc = gl.glGetUniformLocation(self.deepsea_program, "u_time")
if u_time_loc != -1:
gl.glUniform1f(u_time_loc, time)
u_res_loc = gl.glGetUniformLocation(self.deepsea_program, "u_resolution")
if u_res_loc != -1:
gl.glUniform2f(u_res_loc, float(scene_w), float(scene_h))
gl.glBindVertexArray(self._quad_vao)
gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 4)
gl.glBindVertexArray(0)
gl.glUseProgram(0)
gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
@@ -393,12 +411,9 @@ void main() {
u_ts = gl.glGetUniformLocation(program, "u_texel_size")
if u_ts != -1:
gl.glUniform2f(u_ts, texel_size[0], texel_size[1])
gl.glBegin(gl.GL_TRIANGLE_STRIP)
gl.glVertex2f(-1.0, -1.0); gl.glTexCoord2f(0.0, 0.0)
gl.glVertex2f( 1.0, -1.0); gl.glTexCoord2f(1.0, 0.0)
gl.glVertex2f(-1.0, 1.0); gl.glTexCoord2f(0.0, 1.0)
gl.glVertex2f( 1.0, 1.0); gl.glTexCoord2f(1.0, 1.0)
gl.glEnd()
gl.glBindVertexArray(self._quad_vao)
gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 4)
gl.glBindVertexArray(0)
gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
gl.glUseProgram(0)
@@ -445,6 +460,8 @@ void main() {
if progs:
for p in progs:
gl.glDeleteProgram(p)
if self._quad_vao:
gl.glDeleteVertexArrays(1, [self._quad_vao])
self.scene_fbo = None
self.scene_tex = None
self.blur_fbo_a = None
@@ -454,3 +471,4 @@ void main() {
self.h_blur_program = None
self.v_blur_program = None
self.deepsea_program = None
self._quad_vao = None