The problem
I’m just trying to make a game like minecraft, but I can’t add to a vbo from another thread. I’ve created a basic batch renderer with a texture coord pointer too. But when I implement threading, the strange thing is that the window just hangs closes after the data has been added to the VBO
Code
As given in my other VBO question, I have implemented:
# imports
import glfw, numpy
from OpenGL.GL import *
from ctypes import *
import threading
from core.texture_manager import *
event = threading.Event()
glfw.init()
class ThreadedVBOManager:
def __init__(self, renderer):
self.renderer = renderer
glfw.make_context_current(None)
self.thread = threading.Thread(target=self.run, daemon=True)
self.thread.start()
event.wait()
glfw.make_context_current(self.renderer.window)
def run(self):
glfw.window_hint(glfw.VISIBLE, glfw.FALSE)
self.window = glfw.create_window(300, 300, "Window 2", None, self.renderer.window)
glfw.make_context_current(self.window)
event.set()
while not glfw.window_should_close(self.window):
for i in self.renderer.to_add:
glBindBuffer(GL_ARRAY_BUFFER, self.renderer.vbo)
self.renderer.vertices.extend(i[0])
self.renderer.texCoords.extend(i[1])
self.renderer.vertices_added = len(self.renderer.vertices)
glBufferData(GL_ARRAY_BUFFER, self.renderer.vertices_added * 4, None, GL_STATIC_DRAW)
glBufferSubData(GL_ARRAY_BUFFER, 0, i[0].nbytes, (GLfloat * i[0].nbytes)(*i[0]))
glFlush()
glVertexPointer(3, GL_FLOAT, 0, None)
glTexCoordPointer(3, GL_FLOAT, 0, None)
glBindBuffer(GL_ARRAY_BUFFER, self.renderer.vbo_1)
glBufferSubData(GL_ARRAY_BUFFER, 0, i[1].nbytes, (GLfloat * i[1].nbytes)(*i[1]))
glFlush()
glfw.poll_events()
glfw.swap_buffers(self.window)
class TerrainRenderer:
def __init__(self, window):
self.window = window
self.vertices = []
self.texCoords = []
self.to_add = []
self.vertices_added = 0
self.vbo, self.vbo_1 = glGenBuffers (2)
glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
glBufferData(GL_ARRAY_BUFFER, 12 * 4, None, GL_STATIC_DRAW)
self.vbo_manager = ThreadedVBOManager(self)
self.texture_manager = TextureAtlas()
glEnable(GL_TEXTURE_2D)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glEnableClientState(GL_TEXTURE_COORD_ARRAY)
glEnableClientState (GL_VERTEX_ARRAY)
def render(self):
glClear (GL_COLOR_BUFFER_BIT)
glEnable(GL_TEXTURE_2D)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glBindBuffer (GL_ARRAY_BUFFER, self.vbo)
glVertexPointer (3, GL_FLOAT, 0, None)
glBindBuffer(GL_ARRAY_BUFFER, self.vbo_1)
glTexCoordPointer(2, GL_FLOAT, 0, None)
glDrawArrays (GL_QUADS, 0, self.vertices_added)
glDisable(GL_TEXTURE_2D)
glDisable(GL_BLEND)
def add(self, posList, texCoords):
self.to_add.append((numpy.array(posList), numpy.array(texCoords)))
def update_vbo(self):
pass
Sometimes it gives this error too:
OpenGL.error.GLError: GLError(
err = 1281,
description = b'invalid value',
baseOperation = glBufferSubData,
pyArgs = (
GL_ARRAY_BUFFER,
0,
64,
<core.renderer.c_float_Array_64 object at 0x000001964F159840>,
),
cArgs = (
GL_ARRAY_BUFFER,
0,
64,
<core.renderer.c_float_Array_64 object at 0x000001964F159840>,
),
cArguments = (
GL_ARRAY_BUFFER,
0,
64,
<core.renderer.c_float_Array_64 object at 0x000001964F159840>,
)
)