Bump engine submodule and freeze batchs.

This commit is contained in:
Roz K 2023-01-03 05:32:45 +01:00
parent a96ea8bb6b
commit e90f198fa0
Signed by: roz
GPG Key ID: 51FBF4E483E1C822
4 changed files with 55 additions and 35 deletions

2
engine

@ -1 +1 @@
Subproject commit ed87f292ffa3cf89903cddcdec396115893f7d66
Subproject commit baac333b44118e17e46f85fc8637aa5ff7f519fc

View File

@ -13,54 +13,70 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from ctypes import c_ubyte, c_uint, c_void_p, addressof
from ctypes import c_ubyte, c_uint, c_void_p, POINTER, addressof
from engine import (
buffer, INSTANCE_FLAG_SPAWNED, BATCH_MAX_SIZE, param_type, params_format,
create_batch, fill_batch, draw_batch, destroy_batch)
_c_ubyte_p = POINTER(c_ubyte)
_c_uint_p = POINTER(c_uint)
class Batch:
__slots__ = '_batch', '_static', 'vertices', 'size', 'max_size', 'flags', 'meshes', 'params', '_params', '__dict__'
__slots__ = ('_batch', 'vertices', 'max_size', 'size',
'flags', '_flags', 'mesh', '_meshes', 'param', '_params', '_name', '__dict__')
def __init__(self, vertices, max_size, max_meshes, **params_decls):
assert max_size <= BATCH_MAX_SIZE
nparams = len(params_decls)
names = params_decls.keys()
formats = params_decls.values()
self._batch = create_batch(vertices._vertices, max_size, max_meshes, params_format(*formats))
self._static = False
self.vertices = vertices
self.size = 0
self.max_size = max_size
self.flags = buffer(c_ubyte, max_size)
self.meshes = buffer(c_uint, max_size)
self.params = tuple(map(lambda f: buffer(param_type(f), max_size), formats))
if nparams:
self._params = (c_void_p * nparams)(*map(addressof, self.params))
self._batch = create_batch(vertices._vertices, max_size, max_meshes, params_format(*params_decls.values()))
else:
self._batch = create_batch(vertices._vertices, max_size, max_meshes, None)
self.vertices = vertices
self.max_size = max_size
self.size = 0
self.flags = buffer(c_ubyte, max_size)
self._flags = _c_ubyte_p(self.flags)
self.mesh = buffer(c_uint, max_size)
self._meshes = _c_uint_p(self.mesh)
if nparams:
self.param = tuple(map(lambda f: buffer(param_type(f), max_size), params_decls.values()))
self._params = (c_void_p * nparams)(*map(addressof, self.param))
self._name = dict(zip(params_decls.keys(), range(nparams)))
for name, value in zip(params_decls.keys(), self.param):
setattr(self, name, value)
else:
self.param = None
self._params = None
for name, value in zip(names, self.params):
setattr(self, name, value)
self._name = None
def __del__(self):
destroy_batch(self._batch)
def spawn(self, model, *params):
assert len(params) == len(self.params)
def spawn(self, flags, mesh, **params):
index = self.size
assert index < self.max_size
self.flags[index] = model.flags | INSTANCE_FLAG_SPAWNED
self.meshes[index] = model.mesh
for self_params, param in zip(self.params, params):
self_params[index] = param
self.flags[index] = flags | INSTANCE_FLAG_SPAWNED
self.mesh[index] = mesh
for name, value in params.items():
getattr(self, name)[index] = value
self.size += 1
return index
def make_static(self):
fill_batch(self._batch, self.size, self.flags, self.meshes, self._params)
self._static = True
def freeze(self, flags = None, mesh = None, **params):
if flags is not None:
self._flags = None if flags else _c_ubyte_p(self.flags)
if mesh is not None:
self._meshes = None if mesh else _c_uint_p(self.mesh)
for name, value in params.items():
if value is not None:
index = self._name[name]
self._params[index] = None if value else addressof(self.param[index])
def fill(self):
fill_batch(self._batch, self.size, self._flags, self._meshes, self._params)
def draw(self):
if not self._static:
fill_batch(self._batch, self.size, self.flags, self.meshes, self._params)
fill_batch(self._batch, self.size, self._flags, self._meshes, self._params)
draw_batch(self._batch)

View File

@ -16,5 +16,5 @@
class Entity:
__slots__ = 'index'
def __init__(self, batch, model, *params):
self.index = batch.spawn(model, *params)
def __init__(self, batch, flags, mesh, **params):
self.index = batch.spawn(flags, mesh, **params)

View File

@ -76,7 +76,7 @@ class TestEntity(Entity):
__slots__ = 'translation', 'orientation', 'spawn_translation', 'spawn_orientation'
def __init__(self, batch, model, translation, orientation):
Entity.__init__(self, batch, model, translation, orientation)
Entity.__init__(self, batch, model.flags, model.mesh, translation = translation, orientation = orientation)
self.translation = batch.translation[self.index]
self.orientation = batch.orientation[self.index]
self.spawn_translation = translation
@ -165,8 +165,10 @@ def create_scene(keyboard, mouse):
model = mud_model
else:
model = rock_model
tiles_batch.spawn(model, vec3(float(((mx - 128) * 8) + 4), float(((127 - my) * 8) + 4), 0.0))
tiles_batch.make_static()
tiles_batch.spawn(model.flags, model.mesh,
translation = vec3(float(((mx - 128) * 8) + 4), float(((127 - my) * 8) + 4), 0.0))
tiles_batch.fill()
tiles_batch.freeze(flags = True, mesh = True, translation = True)
tests_texture = Texture(*archive.get_texture('tests'))
tests_vertices = Vertices(*archive.get_vertices('tests'))
@ -179,9 +181,11 @@ def create_scene(keyboard, mouse):
blob_forward = math.vec3_normalize((sun_direction[0], sun_direction[1], 0.0))
blob_right = math.vec3_cross(blob_forward, math.vec3_up)
blob_orientation = mat3(vec3(*blob_right), vec3(*blob_forward), vec3_up)
blob = TestEntity(tests_batch, blob_model, vec3(-100.0, -500.0, 0.0), blob_orientation)
cube = TestEntity(tests_batch, cube_model, vec3(100.0, -500.0, 0.0), mat3_identity)
clouds = TestEntity(tests_batch, clouds_model, vec3(0.0, 0.0, 32.0), mat3_identity)
blob = TestEntity(tests_batch, blob_model, translation = vec3(-100.0, -500.0, 0.0), orientation = blob_orientation)
cube = TestEntity(tests_batch, cube_model, translation = vec3(100.0, -500.0, 0.0), orientation = mat3_identity)
clouds = TestEntity(tests_batch, clouds_model, translation = vec3(0.0, 0.0, 32.0), orientation = mat3_identity)
tests_batch.fill()
tests_batch.freeze(flags = True, mesh = True)
sea_polar_textures = sea.load_polar_textures(('data/sea_bump1.png', 'data/sea_bump2.png'))
sea_detail_texture = sea.load_detail_texture('data/sea_bump.png')