I'm really new to this community. I'm sorry for any mistakes in advance.I'm making a game like minecraft with GLFW and OpenGL. The problem is, itI just renders two faces correctly and the other faces havecan't render a wierd glitchVBO while I update it from another thread. Here is my code:
# imports
import glfw
from OpenGL.GL import *
from OpenGL.GLU import *
# internal imports
from core.renderer import *
from terrain import *
from player import *
if not glfw.init():
raise Exception("glfw can not be initialized!")
window = glfw.create_window(800, 500, "PyCraft", None, None)
glfw.make_context_current(window)
renderer = TerrainRenderer(window)
player = Player(window)
renderer.texture_manager.add_from_folder("assets/textures/block/")
renderer.texture_manager.save("atlas.png")
renderer.texture_manager.bind()
glEnable(GL_DEPTH_TEST)
glEnable(GL_CULL_FACE)
glCullFace(GL_BACK)
# glEnable(GL_FOG)
glFogfv(GL_FOG_COLOR, (GLfloat * int(8))(0.5, 0.69, 1.0, 10))
glHint(GL_FOG_HINT, GL_DONT_CARE)
glFogi(GL_FOG_MODE, GL_LINEAR)
glFogf(GL_FOG_START, 303)
glFogf(GL_FOG_END, 10010)
renderer.texture_manager.add_from_folder("assets/textures/block/")
renderer.texture_manager.save("atlas.png")
renderer.texture_manager.bind()
world = World(renderer, player)
world.generate()
# get window size
def get_window_size():
width, height = glfw.get_window_size(window)
return width, height
def _setup_3d():
w, h = get_window_size()
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(70, w / h, 0.1, 1000)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
def _update_3dupdate_on_resize():
_setup_3d()
glViewport(0, 0, *get_window_size())
def add_cube(x, y, z):
X, Y, Z = x + 1, y + 1, z + 1
renderer.add((x, Y, Z, X, Y, Z, X, Y, z, x, Y, z), renderer.texture_manager.get_texture("grass"))
renderer.add((x, y, z, X, y, z, X, y, Z, x, y, Z), renderer.texture_manager.get_texture("grass"))
renderer.add((x, y, z, x, y, Z, x, Y, Z, x, Y, z), renderer.texture_manager.get_texture("grass"))
renderer.add((X, y, Z, X, y, z, X, Y, z, X, Y, Z), renderer.texture_manager.get_texture("grass"))
renderer.add((x, y, Z, X, y, Z, X, Y, Z, x, Y, Z), renderer.texture_manager.get_texture("grass"))
renderer.add((X, y, z, x, y, z, x, Y, z, X, Y, z), renderer.texture_manager.get_texture("grass"))
add_cube(0, 0, -2)
# mainloop
while not glfw.window_should_close(window):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
_update_3dupdate_on_resize()
_setup_3d()
glClearColor(0.5, 0.7, 1, 1.0)
player.update()
rendererplayer.render_translate()
glfw.poll_events()
glfw.swap_buffers(window)
glfw.terminate()
# imports
import glfw, numpy
from OpenGL.GL import *
from ctypes import *
from core.texture_manager import *
import threading
import numpy as np
glfw.init()
class TerrainRendererVBOManager:
def __init__(self, windowrenderer):
self.event = threading.Event()
self.to_add = []
self._len = 0
self.parent = window
self.vertices = []
self.texCoordsrenderer = []
self.create_vbo(window)
renderer
self.texture_manager = TextureAtlas()
glEnable(GL_TEXTURE_2D)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glEnableClientStaterun(GL_TEXTURE_COORD_ARRAY)
glEnableClientState (GL_VERTEX_ARRAY)
def shared_contextrun(self, window):
glfw.window_hint(glfw.VISIBLE, glfw.FALSE)
for window2i =in glfwself.create_window(500,500, "Window 2", None, window)
glfwrenderer.make_context_current(window2)
to_add[:self.event.set()
while not glfwrenderer.window_should_close(window)to_add_count]:
if len(self.to_addrenderer.vertices.extend(i[0]) > 0:
i = self.to_addrenderer.poptexCoords.extend(0i[1])
bytes_vertices_ = np.array(i[0]).nbytesi
bytes_texCoords = npself.arrayrenderer.to_add.remove(i[1]i).nbytes
glBindBuffer(GL_ARRAY_BUFFER, self.renderer.vbo)
glBufferSubData(GL_ARRAY_BUFFER, len(self._lenrenderer.vertices), bytes_verticeslen(_[0]) * 4, (c_floatGLfloat * len(i[0]_[0]))(*i[0]*_[0]))
glVertexPointer glFlush(3, GL_FLOAT, 0, None)
glVertexPointer(3, GL_FLOAT, 0, glFlush(None)
glTexCoordPointer(3, GL_FLOAT, 0, None)
glBindBuffer(GL_ARRAY_BUFFER, self.renderer.vbo_1)
glBufferSubData(GL_ARRAY_BUFFER, len(self._lenrenderer.texCoords), bytes_texCoordslen(_[1]) * 4, (c_floatGLfloat * len(i[1]_[1]))(*i[1])*_[1])
glTexCoordPointer(2, GL_FLOAT, 0, None)
glFlush()
class TerrainRenderer:
def glVertexPointer__init__(3, GL_FLOAT, 0self, Nonewindow):
glTexCoordPointer(3, GL_FLOAT,self.window 0,= None)window
self.vertices +== i[0][]
self.texCoords +== i[1][]
self.to_add = []
self.to_add_count = 256
self._len +=vbo, bytes_vertices
self.vbo_1 = glGenBuffers (2)
glBindBuffer(GL_ARRAY_BUFFER, glfwself.poll_events(vbo)
glBufferData(GL_ARRAY_BUFFER, 12 * 4, glfw.swap_buffers(window2None, GL_STATIC_DRAW)
glfwself.terminate()
vbo_manager def= create_vboVBOManager(self, window):
self.vbo, self.vbo_1texture_manager = glGenBuffers TextureAtlas(2)
glBindBufferglEnable(GL_ARRAY_BUFFER, self.vboGL_TEXTURE_2D)
glBufferDataglEnable(GL_ARRAY_BUFFER, 64000000, None, GL_STATIC_DRAWGL_BLEND)
glBindBufferglBlendFunc(GL_ARRAY_BUFFERGL_SRC_ALPHA, self.vbo_1GL_ONE_MINUS_SRC_ALPHA)
glBufferDataglEnableClientState(GL_ARRAY_BUFFER, 64000000, None, GL_STATIC_DRAWGL_TEXTURE_COORD_ARRAY)
glfw.make_context_currentglEnableClientState (NoneGL_VERTEX_ARRAY)
def load_assets_from(self, other_renderer):
thread = threading.Thread(target=self.shared_context, args=[window], daemon=True)
self.texture_manager = other_renderer.texture_manager
thread.startdef render(self):
self.event.wait()try:
glfw self.make_context_currentvbo_manager.run(window)
def add(self, vertices, texCoords) except RuntimeError:
self.to_add.append((tuple(vertices), tuple(texCoords)))
def render(self):pass
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, len(self._lenvertices))
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
It is expected that all faces of the above cube are lime.
Right now, it shows no errors, but it does not render the cube properly. The attached GIF explains what I mean.
When I use this code in rendererworld.py, it works just fine!
# imports
import glfw, numpy
from OpenGL.GLterrain import *
from ctypesplayer import *
from core.texture_managerrenderer import *
import threading
import random
import glfw
def execute_with_delay(func, delay):
threading.initTimer(delay, func).start()
class VBOManagerThreadedChunkGenerator():
def __init__(self, rendererworld):
self.rendererthread = rendererthreading.Thread(target=self.run, daemon=True)
self.run()world = world
defself.event run= threading.Event(self):
forself.event.wait()
i in self.renderer glfw.to_add[:make_context_current(self.rendererworld.to_add_count]:parent.window)
def run(self,):
selfglfw.rendererwindow_hint(glfw.verticesVISIBLE, glfw.extend(i[0]FALSE)
window2 = glfw.create_window(300, 300, "Window 2", None, self.rendererworld.texCoordsparent.extend(i[1]window)
glfw.make_context_current(window2)
self.renderer.to_addevent.removeset(i)
glBindBuffer(GL_ARRAY_BUFFER, self.renderer.vbo = TerrainRenderer(window2)
glBufferData(GL_ARRAY_BUFFER, lenrenderer.load_assets_from(self.rendererworld.verticesparent)
* 4, (c_float * len(self.renderer.vertices))(*self.renderer.vertices), GL_STATIC_DRAW) while True:
glFlush for i in range(self.world.to_generate):
glVertexPointer(3, GL_FLOAT, 0, None)
chunk = i
glTexCoordPointer(3, GL_FLOAT, 0, None)
glBindBuffer(GL_ARRAY_BUFFER, renderer = self.rendererworld.vbo_1)parent
glBufferData(GL_ARRAY_BUFFER, len(self chunk.generate(renderer.texCoords)
* 4, (c_float * len( self.renderer.texCoords))(*selfworld.renderer.texCoords), GL_STATIC_DRAW)= renderer
glFlush() self.world.to_generate = []
class TerrainRendererWorld:
def __init__(self, windowrenderer, player):
self.windowparent = window
renderer
self.verticeschunks = []{}
self.texCoordsblocks = []
{}
self.to_addposition = [](0 * 16, 0 * 16)
self.to_add_countrender_distance = 256
1
self.vbo,infgen_threshold = 1
self.vbo_1block_types = glGenBuffers all_blocks(2renderer)
glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
to_generate = []
glBufferData(GL_ARRAY_BUFFER, 12 * 4,self.player None,= GL_STATIC_DRAW)player
self.vbo_managerthread = VBOManagerThreadedChunkGenerator(self)
self.thread.start()
self.texture_managerevent = TextureAtlas()
self.thread.event
glEnableself.event.wait(GL_TEXTURE_2D)
def glEnableblock_exists(GL_BLENDself, position):
glBlendFuncreturn position in self.blocks
def _add_chunk(GL_SRC_ALPHAself, GL_ONE_MINUS_SRC_ALPHAposition):
glEnableClientStateself.chunks[position] = Chunk(GL_TEXTURE_COORD_ARRAYself.parent, self, position)
def add_chunk(self, position):
glEnableClientStateexecute_with_delay(lambda: self._add_chunk(GL_VERTEX_ARRAYposition), random.randrange(1, 2))
def rendergenerate(self):
tryfor i in range(self.position[0] - self.render_distance, self.position[0] + self.render_distance + 1):
for j in range(self.vbo_managerposition[1] - self.run(render_distance, self.position[1] + self.render_distance + 1):
except RuntimeError:
if (i, j) not in pass
self.chunks:
glClear self.add_chunk(GL_COLOR_BUFFER_BIT(i, j))
def update_infgen(self, position):
glEnable player_pos = (GL_TEXTURE_2Dposition[0] // 16, position[2] // 16)
glEnable(GL_BLEND)if player_pos[0] - self.position[0] > self.infgen_threshold:
glBlendFunc self.position = (GL_SRC_ALPHAself.position[0] + 2, GL_ONE_MINUS_SRC_ALPHAself.position[1])
glBindBuffer (GL_ARRAY_BUFFER, self.vbogenerate()
glVertexPointerelif (3,player_pos[0] GL_FLOAT,- 0,self.position[0] None)< -self.infgen_threshold:
glBindBuffer self.position = (GL_ARRAY_BUFFERself.position[0] - 2, self.vbo_1position[1])
glTexCoordPointer(2, GL_FLOAT, 0, None self.generate()
glDrawArraysif (GL_QUADS,player_pos[1] 0,- len(self.vertices))position[1] > self.infgen_threshold:
glDisable self.position = (GL_TEXTURE_2Dself.position[0], self.position[1] + 2)
glDisable self.generate(GL_BLEND)
def add( elif player_pos[1] - self,.position[1] posList,< texCoords)-self.infgen_threshold:
self.to_add.append(position = (numpyself.array(posList)position[0], numpyself.array(texCoords)position[1] - 2)
self.generate()
def update_vborender(self):
passself.parent.render()
self.update_infgen(self.player.pos)
Why does this code work and not the previous one? Have I missed something?
Right now, it shows no errors, just hangs the window before it even starts rendering. Any help will be highly appreciated.
