adds labyrinth and subjects as well as performance increases
This commit is contained in:
parent
6c5cae958b
commit
0638d5e666
10 changed files with 1591 additions and 234 deletions
Objects
|
@ -19,6 +19,9 @@ class Structure(Renderable):
|
|||
self.Objects = {}
|
||||
self.vais = {}
|
||||
self.dirty = True
|
||||
self.dirty_pos = True
|
||||
self.dirty_color = True
|
||||
self.dirty_size = True
|
||||
|
||||
self.x_offset = x_offset
|
||||
self.y_offset = y_offset
|
||||
|
@ -31,6 +34,7 @@ class Structure(Renderable):
|
|||
@x_offset.setter
|
||||
def x_offset(self, value):
|
||||
self.dirty = True
|
||||
self.dirty_pos = True
|
||||
self._x_offset = value
|
||||
|
||||
@property
|
||||
|
@ -40,6 +44,7 @@ class Structure(Renderable):
|
|||
@y_offset.setter
|
||||
def y_offset(self, value):
|
||||
self.dirty = True
|
||||
self.dirty_pos = True
|
||||
self._y_offset = value
|
||||
|
||||
@property
|
||||
|
@ -49,6 +54,7 @@ class Structure(Renderable):
|
|||
@z_offset.setter
|
||||
def z_offset(self, value):
|
||||
self.dirty = True
|
||||
self.dirty_pos = True
|
||||
self._z_offset = value
|
||||
|
||||
def addShape(self, program, shape):
|
||||
|
@ -56,6 +62,9 @@ class Structure(Renderable):
|
|||
self.Objects[program] = []
|
||||
self.Objects[program].append(shape)
|
||||
self.dirty = True
|
||||
self.dirty_color = True
|
||||
self.dirty_pos = True
|
||||
self.dirty_size = True
|
||||
|
||||
def removeShape(self, program, shape):
|
||||
if program in self.Objects.keys():
|
||||
|
@ -63,72 +72,89 @@ class Structure(Renderable):
|
|||
if len(self.Objects[program]) == 0:
|
||||
self.Objects.pop(program)
|
||||
self.dirty = True
|
||||
self.dirty_color = True
|
||||
self.dirty_pos = True
|
||||
self.dirty_size = True
|
||||
|
||||
def buildvertexArrays(self):
|
||||
if self.dirty:
|
||||
self.clearVertexArrays()
|
||||
# self.clearVertexArrays()
|
||||
glEnableClientState(GL_VERTEX_ARRAY)
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY)
|
||||
glEnableClientState(GL_NORMAL_ARRAY)
|
||||
glEnableClientState(GL_COLOR_ARRAY)
|
||||
self.vais = {}
|
||||
|
||||
for key, objects in self.Objects.items():
|
||||
tvai = GLuint(0)
|
||||
tpbi = GLuint(0)
|
||||
tcbi = GLuint(0)
|
||||
tsbi = GLuint(0)
|
||||
num = len(objects)
|
||||
|
||||
glGenVertexArrays(1, tvai)
|
||||
needs_new_buffers = key not in self.vais.keys()
|
||||
if needs_new_buffers:
|
||||
tvai = GLuint(0)
|
||||
tpbi = GLuint(0)
|
||||
tcbi = GLuint(0)
|
||||
tsbi = GLuint(0)
|
||||
num = len(objects)
|
||||
else:
|
||||
tvai, tpbi, tcbi, tsbi, num = self.vais[key]
|
||||
if needs_new_buffers:
|
||||
glGenVertexArrays(1, tvai)
|
||||
glBindVertexArray(tvai)
|
||||
if self.dirty_pos:
|
||||
if needs_new_buffers:
|
||||
vid = glGetAttribLocation(key, "in_position")
|
||||
glEnableVertexAttribArray(vid)
|
||||
|
||||
vid = glGetAttribLocation(key, "in_position")
|
||||
glEnableVertexAttribArray(vid)
|
||||
|
||||
tpbi = glGenBuffers(1)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tpbi)
|
||||
positions = []
|
||||
for o in objects:
|
||||
positions.append(o.pos[0] + self.x_offset)
|
||||
positions.append(o.pos[1] + self.y_offset)
|
||||
positions.append(o.pos[2] + self.z_offset)
|
||||
glBufferData(GL_ARRAY_BUFFER, np.array(positions, dtype=np.float32), GL_STATIC_DRAW)
|
||||
glVertexAttribPointer(vid, 3, GL_FLOAT, GL_FALSE, 0, None)
|
||||
self.check_error("Could not create position buffer")
|
||||
|
||||
colors = []
|
||||
for o in objects:
|
||||
colors.append(o.color[0])
|
||||
colors.append(o.color[1])
|
||||
colors.append(o.color[2])
|
||||
tcbi = glGenBuffers(1)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tcbi)
|
||||
glBufferData(GL_ARRAY_BUFFER, np.array(colors, dtype=np.float32), GL_STATIC_DRAW)
|
||||
vc = glGetAttribLocation(key, "MyInColor")
|
||||
if vc != -1:
|
||||
glEnableVertexAttribArray(vc)
|
||||
glVertexAttribPointer(vc, 3, GL_FLOAT, GL_FALSE, 0, None)
|
||||
self.check_error("Could not create color buffer")
|
||||
|
||||
if hasattr(objects[0], 'size'):
|
||||
sizes = []
|
||||
tpbi = glGenBuffers(1)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tpbi)
|
||||
positions = []
|
||||
for o in objects:
|
||||
sizes.append(o.size[0])
|
||||
sizes.append(o.size[1])
|
||||
sizes.append(o.size[2])
|
||||
tsbi = glGenBuffers(1)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tsbi)
|
||||
glBufferData(GL_ARRAY_BUFFER, np.array(sizes, dtype=np.float32), GL_STATIC_DRAW)
|
||||
vs = glGetAttribLocation(key, "MyInSize")
|
||||
if vs != -1:
|
||||
glEnableVertexAttribArray(vs)
|
||||
glVertexAttribPointer(vs, 3, GL_FLOAT, GL_FALSE, 0, None)
|
||||
self.check_error("Could not create size buffer")
|
||||
positions.append(o.pos[0] + self.x_offset)
|
||||
positions.append(o.pos[1] + self.y_offset)
|
||||
positions.append(o.pos[2] + self.z_offset)
|
||||
glBufferData(GL_ARRAY_BUFFER, np.array(positions, dtype=np.float32), GL_STATIC_DRAW)
|
||||
if needs_new_buffers:
|
||||
glVertexAttribPointer(vid, 3, GL_FLOAT, GL_FALSE, 0, None)
|
||||
self.check_error("Could not create position buffer")
|
||||
|
||||
if self.dirty_color:
|
||||
colors = []
|
||||
for o in objects:
|
||||
colors.append(o.color[0])
|
||||
colors.append(o.color[1])
|
||||
colors.append(o.color[2])
|
||||
if needs_new_buffers:
|
||||
tcbi = glGenBuffers(1)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tcbi)
|
||||
glBufferData(GL_ARRAY_BUFFER, np.array(colors, dtype=np.float32), GL_STATIC_DRAW)
|
||||
if needs_new_buffers:
|
||||
vc = glGetAttribLocation(key, "MyInColor")
|
||||
if vc != -1:
|
||||
glEnableVertexAttribArray(vc)
|
||||
glVertexAttribPointer(vc, 3, GL_FLOAT, GL_FALSE, 0, None)
|
||||
self.check_error("Could not create color buffer")
|
||||
|
||||
if self.dirty_size:
|
||||
if hasattr(objects[0], 'size'):
|
||||
sizes = []
|
||||
for o in objects:
|
||||
sizes.append(o.size[0])
|
||||
sizes.append(o.size[1])
|
||||
sizes.append(o.size[2])
|
||||
if needs_new_buffers:
|
||||
tsbi = glGenBuffers(1)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tsbi)
|
||||
glBufferData(GL_ARRAY_BUFFER, np.array(sizes, dtype=np.float32), GL_STATIC_DRAW)
|
||||
if needs_new_buffers:
|
||||
vs = glGetAttribLocation(key, "MyInSize")
|
||||
if vs != -1:
|
||||
glEnableVertexAttribArray(vs)
|
||||
glVertexAttribPointer(vs, 3, GL_FLOAT, GL_FALSE, 0, None)
|
||||
self.check_error("Could not create size buffer")
|
||||
|
||||
glBindVertexArray(0)
|
||||
self.vais[key] = (tvai, tpbi, tcbi, tsbi, num)
|
||||
self.dirty = False
|
||||
self.dirty_pos = False
|
||||
self.dirty_color = False
|
||||
self.dirty_size = False
|
||||
|
||||
def clearVertexArrays(self):
|
||||
temp = dict(self.vais)
|
||||
|
|
176
Objects/World.py
176
Objects/World.py
|
@ -1,3 +1,5 @@
|
|||
import time
|
||||
|
||||
from Lights.Lights import Light
|
||||
from Objects.Objects import Object
|
||||
from Objects.Renderable import Renderable
|
||||
|
@ -9,7 +11,8 @@ import math
|
|||
import numpy as np
|
||||
import random
|
||||
import sys
|
||||
|
||||
import ctypes
|
||||
float_pointer = ctypes.POINTER(ctypes.c_float)
|
||||
# Plate Types
|
||||
SEA_PLATE = 0
|
||||
CONTINENTAL_PLATE = 1
|
||||
|
@ -22,6 +25,7 @@ METAMORPH_STONE = 3
|
|||
SEDIMENTAL_STONE = 4
|
||||
SEDIMENT = 5
|
||||
|
||||
|
||||
class WorldChunk(Structure):
|
||||
def __init__(self, width: int, length: int, height: int, programs: dict):
|
||||
assert width > 0, 'Width must be greater than 0'
|
||||
|
@ -38,6 +42,8 @@ class WorldChunk(Structure):
|
|||
self.height = height
|
||||
self.programs = programs
|
||||
|
||||
self.objects = {}
|
||||
|
||||
for x in range(width):
|
||||
self.content.append([])
|
||||
self.visible.append([])
|
||||
|
@ -54,6 +60,7 @@ class WorldChunk(Structure):
|
|||
assert 0 <= z < self.height, 'Put out of bounds for z coordinate! Must be between 0 and %i' % self.height
|
||||
no_visibility_changes = (self.content[x][y][z] is None) == (new_object is None)
|
||||
|
||||
old_object = self.content[x][y][z]
|
||||
self.content[x][y][z] = new_object
|
||||
new_object.translate(translate(x, y, z))
|
||||
|
||||
|
@ -87,6 +94,32 @@ class WorldChunk(Structure):
|
|||
else:
|
||||
self.visible[x][y][z - 1] += change
|
||||
|
||||
# todo: add visibility check for object listing
|
||||
added = False
|
||||
if old_object is not None:
|
||||
if new_object is not None and type(old_object) == type(new_object):
|
||||
new_object.buffer_id = old_object.buffer_id
|
||||
self.objects[self.programs[type(old_object)]][old_object.buffer_id] = new_object
|
||||
added = True
|
||||
else:
|
||||
# todo: maybe replace the element with a placeholder that is skipped when rendering/ saving and have a
|
||||
# cleanup task, since this could be exploited to lower update rates
|
||||
leading = self.objects[self.programs[type(old_object)]][:old_object.buffer_id]
|
||||
following = self.objects[self.programs[type(old_object)]][old_object.buffer_id + 1:]
|
||||
for element in following:
|
||||
element.buffer_id -= 1
|
||||
self.objects[self.programs[type(old_object)]] = leading + following
|
||||
|
||||
if not added and new_object is not None:
|
||||
if self.programs[type(new_object)] not in self.objects.keys():
|
||||
self.objects[self.programs[type(new_object)]] = []
|
||||
new_object.buffer_id = len(self.objects[self.programs[type(new_object)]])
|
||||
self.objects[self.programs[type(new_object)]].append(new_object)
|
||||
|
||||
self.dirty = True
|
||||
self.dirty_pos = True
|
||||
self.dirty_color = True
|
||||
self.dirty_size = True
|
||||
return visible_carry_over
|
||||
|
||||
def get_object(self, x: int, y: int, z: int):
|
||||
|
@ -112,80 +145,92 @@ class WorldChunk(Structure):
|
|||
|
||||
def buildvertexArrays(self):
|
||||
if self.dirty:
|
||||
self.clearVertexArrays()
|
||||
# self.clearVertexArrays()
|
||||
glEnableClientState(GL_VERTEX_ARRAY)
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY)
|
||||
glEnableClientState(GL_NORMAL_ARRAY)
|
||||
glEnableClientState(GL_COLOR_ARRAY)
|
||||
self.vais = {}
|
||||
|
||||
objects = {}
|
||||
counts = {}
|
||||
for x in range(self.width):
|
||||
for y in range(self.length):
|
||||
for z in range(self.height):
|
||||
if self.content[x][y][z] is not None: # and self.visible[x][y][z] > 0: TODO: check visibility...
|
||||
if self.programs[type(self.content[x][y][z])] not in objects.keys():
|
||||
objects[self.programs[type(self.content[x][y][z])]] = []
|
||||
counts[self.programs[type(self.content[x][y][z])]] = 0
|
||||
objects[self.programs[type(self.content[x][y][z])]].append(self.content[x][y][z])
|
||||
counts[self.programs[type(self.content[x][y][z])]] += 1
|
||||
for key, object_list in self.objects.items():
|
||||
needs_new_buffers = key not in self.vais.keys()
|
||||
if needs_new_buffers:
|
||||
tvai = GLuint(0)
|
||||
tpbi = GLuint(0)
|
||||
tcbi = GLuint(0)
|
||||
tsbi = GLuint(0)
|
||||
|
||||
for key, object_list in objects.items():
|
||||
tvai = GLuint(0)
|
||||
tpbi = GLuint(0)
|
||||
tcbi = GLuint(0)
|
||||
tsbi = GLuint(0)
|
||||
|
||||
glGenVertexArrays(1, tvai)
|
||||
glGenVertexArrays(1, tvai)
|
||||
else:
|
||||
tvai, tpbi, tcbi, tsbi, old_len = self.vais[key]
|
||||
glBindVertexArray(tvai)
|
||||
|
||||
vid = glGetAttribLocation(key, "in_position")
|
||||
glEnableVertexAttribArray(vid)
|
||||
if self.dirty_pos:
|
||||
if needs_new_buffers:
|
||||
vid = glGetAttribLocation(key, "in_position")
|
||||
glEnableVertexAttribArray(vid)
|
||||
tpbi = glGenBuffers(1)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tpbi)
|
||||
positions = []
|
||||
for index, o in enumerate(object_list):
|
||||
o.buffer_id = index
|
||||
positions.append(o.pos[0] + self.x_offset)
|
||||
positions.append(o.pos[1] + self.y_offset)
|
||||
positions.append(o.pos[2] + self.z_offset)
|
||||
|
||||
tpbi = glGenBuffers(1)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tpbi)
|
||||
positions = []
|
||||
for o in object_list:
|
||||
positions.append(o.pos[0] + self.x_offset)
|
||||
positions.append(o.pos[1] + self.y_offset)
|
||||
positions.append(o.pos[2] + self.z_offset)
|
||||
glBufferData(GL_ARRAY_BUFFER, np.array(positions, dtype=np.float32), GL_STATIC_DRAW)
|
||||
glVertexAttribPointer(vid, 3, GL_FLOAT, GL_FALSE, 0, None)
|
||||
self.check_error("Could not create position buffer")
|
||||
glBufferData(GL_ARRAY_BUFFER, np.array(positions, dtype=np.float32), GL_STATIC_DRAW)
|
||||
|
||||
colors = []
|
||||
for o in object_list:
|
||||
colors.append(o.color[0])
|
||||
colors.append(o.color[1])
|
||||
colors.append(o.color[2])
|
||||
tcbi = glGenBuffers(1)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tcbi)
|
||||
glBufferData(GL_ARRAY_BUFFER, np.array(colors, dtype=np.float32), GL_STATIC_DRAW)
|
||||
vc = glGetAttribLocation(key, "MyInColor")
|
||||
if vc != -1:
|
||||
glEnableVertexAttribArray(vc)
|
||||
glVertexAttribPointer(vc, 3, GL_FLOAT, GL_FALSE, 0, None)
|
||||
if needs_new_buffers:
|
||||
glVertexAttribPointer(vid, 3, GL_FLOAT, GL_FALSE, 0, None)
|
||||
self.check_error("Could not create position buffer")
|
||||
|
||||
if self.dirty_color:
|
||||
colors = []
|
||||
for o in object_list:
|
||||
colors.append(o.color[0])
|
||||
colors.append(o.color[1])
|
||||
colors.append(o.color[2])
|
||||
if needs_new_buffers:
|
||||
tcbi = glGenBuffers(1)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tcbi)
|
||||
if needs_new_buffers or old_len != len(object_list):
|
||||
glBufferData(GL_ARRAY_BUFFER, np.array(colors, dtype=np.float32), GL_STATIC_DRAW)
|
||||
else:
|
||||
# todo: check if this improves anything. Timewise it seems to be the same
|
||||
ptr = ctypes.cast(glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE), float_pointer)
|
||||
for index, value in enumerate(colors):
|
||||
ptr[index] = value
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER)
|
||||
if needs_new_buffers:
|
||||
vc = glGetAttribLocation(key, "MyInColor")
|
||||
if vc != -1:
|
||||
glEnableVertexAttribArray(vc)
|
||||
glVertexAttribPointer(vc, 3, GL_FLOAT, GL_FALSE, 0, None)
|
||||
self.check_error("Could not create color buffer")
|
||||
|
||||
if hasattr(object_list[0], 'size'):
|
||||
sizes = []
|
||||
for o in object_list:
|
||||
sizes.append(o.size[0])
|
||||
sizes.append(o.size[1])
|
||||
sizes.append(o.size[2])
|
||||
tsbi = glGenBuffers(1)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tsbi)
|
||||
glBufferData(GL_ARRAY_BUFFER, np.array(sizes, dtype=np.float32), GL_STATIC_DRAW)
|
||||
vs = glGetAttribLocation(key, "MyInSize")
|
||||
if vs != -1:
|
||||
glEnableVertexAttribArray(vs)
|
||||
glVertexAttribPointer(vs, 3, GL_FLOAT, GL_FALSE, 0, None)
|
||||
if self.dirty_size:
|
||||
if hasattr(object_list[0], 'size'):
|
||||
sizes = []
|
||||
for o in object_list:
|
||||
sizes.append(o.size[0])
|
||||
sizes.append(o.size[1])
|
||||
sizes.append(o.size[2])
|
||||
if needs_new_buffers:
|
||||
tsbi = glGenBuffers(1)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tsbi)
|
||||
glBufferData(GL_ARRAY_BUFFER, np.array(sizes, dtype=np.float32), GL_STATIC_DRAW)
|
||||
if needs_new_buffers:
|
||||
vs = glGetAttribLocation(key, "MyInSize")
|
||||
if vs != -1:
|
||||
glEnableVertexAttribArray(vs)
|
||||
glVertexAttribPointer(vs, 3, GL_FLOAT, GL_FALSE, 0, None)
|
||||
self.check_error("Could not create size buffer")
|
||||
|
||||
glBindVertexArray(0)
|
||||
self.vais[key] = (tvai, tpbi, tcbi, tsbi, counts[key])
|
||||
self.vais[key] = (tvai, tpbi, tcbi, tsbi, len(object_list))
|
||||
self.dirty = False
|
||||
self.dirty_pos = False
|
||||
self.dirty_color = False
|
||||
self.dirty_size = False
|
||||
|
||||
def render(self, proj_matrix, geometry_rot_matrix, alternate_programs=None,
|
||||
preselected_program=None, projection_pos=None, rot_pos=None):
|
||||
|
@ -204,6 +249,17 @@ class WorldChunk(Structure):
|
|||
if self.content[x][y][z] is not None:
|
||||
self.content[x][y][z].setColor(r, g, b)
|
||||
self.dirty = True
|
||||
self.dirty_color = True
|
||||
|
||||
def load(self):
|
||||
for x in range(self.width):
|
||||
for y in range(self.length):
|
||||
for z in range(self.height):
|
||||
if self.content[x][y][z] is not None: # and self.visible[x][y][z] > 0: TODO: check visibility...
|
||||
if self.programs[type(self.content[x][y][z])] not in self.objects.keys():
|
||||
self.objects[self.programs[type(self.content[x][y][z])]] = []
|
||||
self.objects[self.programs[type(self.content[x][y][z])]].append(self.content[x][y][z])
|
||||
|
||||
|
||||
class World(Renderable):
|
||||
def __init__(self, chunk_size_x: int, chunk_size_y: int, chunk_size_z: int,
|
||||
|
@ -488,6 +544,8 @@ class World(Renderable):
|
|||
y % self.chunk_size_y,
|
||||
z % self.chunk_size_z,
|
||||
r, g, b)
|
||||
else:
|
||||
print('Changing color of nonexistant element!')
|
||||
|
||||
def put_object(self, x: int, y: int, z: int, new_object: Object):
|
||||
x = x % (self.chunk_size_x * self.chunk_n_x)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue