Split QuadVertexArrayBuffer off of VertexArrayBuffer

This commit is contained in:
David Vierra 2015-05-12 15:59:30 -10:00
parent 7cb73dacf7
commit 89e01a809e
6 changed files with 98 additions and 48 deletions

View File

@ -9,7 +9,7 @@ from mcedit2.rendering.blockmeshes import standardCubeTemplates
from mcedit2.rendering.blockmeshes import ChunkMeshBase from mcedit2.rendering.blockmeshes import ChunkMeshBase
from mcedit2.rendering.layers import Layer from mcedit2.rendering.layers import Layer
from mcedit2.rendering.slices import _XYZ from mcedit2.rendering.slices import _XYZ
from mcedit2.rendering.vertexarraybuffer import VertexArrayBuffer from mcedit2.rendering.vertexarraybuffer import QuadVertexArrayBuffer
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -27,7 +27,7 @@ class EntityMeshBase(ChunkMeshBase):
if bounds: if bounds:
positions = [p for p in positions if p in bounds] positions = [p for p in positions if p in bounds]
vertexBuffer = VertexArrayBuffer(len(positions) * 6, lights=False, textures=False) vertexBuffer = QuadVertexArrayBuffer(len(positions) * 6, lights=False, textures=False)
vertexBuffer.buffer.shape = (len(positions), 6) + vertexBuffer.buffer.shape[-2:] vertexBuffer.buffer.shape = (len(positions), 6) + vertexBuffer.buffer.shape[-2:]
if len(positions): if len(positions):
positions = numpy.array(positions, dtype=float) positions = numpy.array(positions, dtype=float)

View File

@ -7,7 +7,7 @@ import numpy
from mcedit2.rendering import renderstates, scenegraph from mcedit2.rendering import renderstates, scenegraph
from mcedit2.rendering.blockmeshes import standardCubeTemplates from mcedit2.rendering.blockmeshes import standardCubeTemplates
from mcedit2.rendering.blockmeshes import ChunkMeshBase from mcedit2.rendering.blockmeshes import ChunkMeshBase
from mcedit2.rendering.vertexarraybuffer import VertexArrayBuffer from mcedit2.rendering.vertexarraybuffer import QuadVertexArrayBuffer
from mceditlib import faces from mceditlib import faces
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -76,7 +76,7 @@ class LowDetailBlockMesh(ChunkMeshBase):
flatcolors = dim.blocktypes.mapColor[topBlocks, topBlockData][:, numpy.newaxis, :] flatcolors = dim.blocktypes.mapColor[topBlocks, topBlockData][:, numpy.newaxis, :]
yield yield
vertexBuffer = VertexArrayBuffer(len(x), textures=False, lights=False) vertexBuffer = QuadVertexArrayBuffer(len(x), textures=False, lights=False)
vertexBuffer.vertex[..., 0] = x[:, numpy.newaxis] vertexBuffer.vertex[..., 0] = x[:, numpy.newaxis]
vertexBuffer.vertex[..., 1] = y[:, numpy.newaxis] vertexBuffer.vertex[..., 1] = y[:, numpy.newaxis]

View File

@ -9,7 +9,7 @@ from mcedit2.rendering.blockmeshes import standardCubeTemplates
from mcedit2.rendering.blockmeshes import ChunkMeshBase from mcedit2.rendering.blockmeshes import ChunkMeshBase
from mcedit2.rendering.layers import Layer from mcedit2.rendering.layers import Layer
from mcedit2.rendering.slices import _XYZ, _RGBA from mcedit2.rendering.slices import _XYZ, _RGBA
from mcedit2.rendering.vertexarraybuffer import VertexArrayBuffer from mcedit2.rendering.vertexarraybuffer import QuadVertexArrayBuffer
from mceditlib import faces from mceditlib import faces
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -84,7 +84,7 @@ class TerrainPopulatedRenderer(ChunkMeshBase):
] ]
visibleFaces = numpy.array(visibleFaces, dtype='bool') visibleFaces = numpy.array(visibleFaces, dtype='bool')
verts = self.vertexTemplate[visibleFaces] verts = self.vertexTemplate[visibleFaces]
buffer = VertexArrayBuffer(0, textures=False, lights=False) buffer = QuadVertexArrayBuffer(0, textures=False, lights=False)
buffer.buffer = verts buffer.buffer = verts
self.sceneNode = scenegraph.VertexNode(buffer) self.sceneNode = scenegraph.VertexNode(buffer)

View File

@ -10,7 +10,7 @@ cimport numpy
from mcedit2.rendering import renderstates, scenegraph from mcedit2.rendering import renderstates, scenegraph
from mcedit2.rendering.layers import Layer from mcedit2.rendering.layers import Layer
from mcedit2.rendering.vertexarraybuffer import VertexArrayBuffer from mcedit2.rendering.vertexarraybuffer import QuadVertexArrayBuffer
cimport mcedit2.rendering.blockmodels as blockmodels cimport mcedit2.rendering.blockmodels as blockmodels
from libc.stdlib cimport malloc, realloc, free from libc.stdlib cimport malloc, realloc, free
@ -292,7 +292,7 @@ class BlockModelMesh(object):
vertexBuffer = <float *>realloc(vertexBuffer, buffer_size * sizeof(float) * quadFloats) vertexBuffer = <float *>realloc(vertexBuffer, buffer_size * sizeof(float) * quadFloats)
if buffer_ptr: # now buffer size if buffer_ptr: # now buffer size
vertexArray = VertexArrayBuffer(buffer_ptr) vertexArray = QuadVertexArrayBuffer(buffer_ptr)
vabuffer = vertexArray.buffer vabuffer = vertexArray.buffer
memcpy(vabuffer.data, vertexBuffer, buffer_ptr * sizeof(float) * quadFloats) memcpy(vabuffer.data, vertexBuffer, buffer_ptr * sizeof(float) * quadFloats)
self.sceneNode = scenegraph.VertexNode(vertexArray) self.sceneNode = scenegraph.VertexNode(vertexArray)

View File

@ -11,7 +11,7 @@ from mcedit2.rendering.chunknode import ChunkGroupNode, ChunkNode
from mcedit2.rendering.depths import DepthOffset from mcedit2.rendering.depths import DepthOffset
from mcedit2.rendering.renderstates import _RenderstateAlphaBlendNode from mcedit2.rendering.renderstates import _RenderstateAlphaBlendNode
from mcedit2.rendering.scenegraph import VertexNode, RenderstateNode from mcedit2.rendering.scenegraph import VertexNode, RenderstateNode
from mcedit2.rendering.vertexarraybuffer import VertexArrayBuffer from mcedit2.rendering.vertexarraybuffer import QuadVertexArrayBuffer
from mcedit2.util import profiler from mcedit2.util import profiler
from mcedit2.util.glutils import gl from mcedit2.util.glutils import gl
from mceditlib import faces from mceditlib import faces
@ -227,9 +227,9 @@ class SelectionScene(scenegraph.Node):
vertexArrays = [] vertexArrays = []
for (face, exposedFaceMask) in enumerate(self.exposedBlockMasks(sectionMask)): for (face, exposedFaceMask) in enumerate(self.exposedBlockMasks(sectionMask)):
blockIndices = sectionMask[1:-1, 1:-1, 1:-1] & exposedFaceMask blockMask = sectionMask[1:-1, 1:-1, 1:-1] & exposedFaceMask
vertexBuffer = VertexArrayBuffer.fromIndices(face, blockIndices, False, False) vertexBuffer = QuadVertexArrayBuffer.fromBlockMask(face, blockMask, False, False)
if not len(vertexBuffer.vertex): if not len(vertexBuffer.vertex):
continue continue

View File

@ -13,18 +13,42 @@ log = logging.getLogger(__name__)
class VertexArrayBuffer(object): class VertexArrayBuffer(object):
texOffset = None texOffset = None
lightOffset = None lightOffset = None
def __init__(self, count, textures=True, lights=True): def __init__(self, shape, gl_type, textures=True, lights=True):
""" """
Vertex buffer, stores an array of `count` quad vertexes with a number of elements determined by textures and Vertex buffer, stores an array of `shape` vertexes with a number of elements per vertex
lights. determined by textures and lights. Also stores a gl_type such as GL.GL_QUADS that will
be passed to glDrawArrays when drawing the array buffer (perhaps doesn't belong here? xxx)
Shape is a value or a tuple of values that defines the number of vertexes. Shape is similar
to a numpy array's shape and defines the shape of the underlying buffer array.
Element types:
vertex:
x: float32
y: float32
z: float32
texcoord:
s: float32 (with textures=True)
t: float32 (with textures=True)
lightcoord:
bl: float32 (with lights=True)
sl: float32 (with lights=True)
rgba:
rgba: uint32 (four uint8s packed with r in the most significant byte)
Access elements using .vertex, .texcoord, .lightcoord, .rgba Access elements using .vertex, .texcoord, .lightcoord, .rgba
:type count: int :type shape: int | tuple[int]
:type textures: bool :type textures: bool
:type lights: bool :type lights: bool
:return: :return:
:rtype: VertexArrayBuffer :rtype: VertexArrayBuffer
""" """
if not isinstance(shape, tuple):
shape = (shape,)
self.elements = 4 self.elements = 4
if textures: if textures:
self.texOffset = self.elements - 1 self.texOffset = self.elements - 1
@ -34,44 +58,15 @@ class VertexArrayBuffer(object):
self.elements += 2 self.elements += 2
self.rgbaOffset = self.elements - 1 self.rgbaOffset = self.elements - 1
self.buffer = numpy.zeros((count, 4, self.elements), dtype='f4') self.shape = shape
self.gl_type = GL.GL_QUADS self.buffer = numpy.zeros(shape + (self.elements,), dtype='f4')
self.gl_type = gl_type
self.lights = lights self.lights = lights
self.textures = textures self.textures = textures
self.rgba[:] = 0xff self.rgba[:] = 0xff
@classmethod
def fromIndices(cls, face, blockIndices, textures=True, lights=True):
"""
:param face:
:type face:
:param blockIndices:
:type blockIndices:
:param textures:
:type textures:
:param lights:
:type lights:
:return:
:rtype: VertexArrayBuffer
"""
y, z, x = blockIndices.nonzero()
vertexBuffer = cls(len(x), textures, lights)
if len(x) == 0:
return vertexBuffer
vertexBuffer.vertex[..., 0] = x[..., None]
vertexBuffer.vertex[..., 1] = y[..., None]
vertexBuffer.vertex[..., 2] = z[..., None]
vertexBuffer.vertex[:] += standardCubeTemplates[face, ..., 0:3]
if lights:
vertexBuffer.lightcoord[:] = [[[0.5, 0.5]]]
return vertexBuffer
def copy(self): def copy(self):
copy = VertexArrayBuffer(len(self.buffer), self.textures, self.lights) copy = VertexArrayBuffer(self.shape, self.gl_type, self.textures, self.lights)
copy.buffer[:] = self.buffer copy.buffer[:] = self.buffer
return copy return copy
@ -112,3 +107,58 @@ class VertexArrayBuffer(object):
def __len__(self): def __len__(self):
return len(self.buffer) return len(self.buffer)
class QuadVertexArrayBuffer(VertexArrayBuffer):
def __init__(self, count, textures=True, lights=True):
"""
VertexArrayBuffer subclass specialized to store an array of quads. Initalizes an array
with shape=(count, 4) and provides a `fromBlockMask` method to create an array with
x,y,z elements taken from the positions of the True values in a 3D mask array.
:param count:
:type count:
:param textures:
:type textures:
:param lights:
:type lights:
:return:
:rtype:
"""
super(QuadVertexArrayBuffer, self).__init__((count, 4), GL.GL_QUADS, textures, lights)
@classmethod
def fromBlockMask(cls, face, blockMask, textures=True, lights=True):
"""
Create a vertex array using a face direction and a 3D mask array (ordered y,z,x as
in ChunkSection arrays). The array's x, y, z elements are initialized to the corners
of a quad facing the indicated direction and in the position of each True value in the mask array.
This was used a lot for the pre-model block rendering and it may still come in handy.
:param face:
:type face:
:param blockMask:
:type blockMask:
:param textures:
:type textures:
:param lights:
:type lights:
:return:
:rtype: QuadVertexArrayBuffer
"""
y, z, x = blockMask.nonzero()
vertexBuffer = cls(len(x), textures, lights)
if len(x) == 0:
return vertexBuffer
vertexBuffer.vertex[..., 0] = x[..., None]
vertexBuffer.vertex[..., 1] = y[..., None]
vertexBuffer.vertex[..., 2] = z[..., None]
vertexBuffer.vertex[:] += standardCubeTemplates[face, ..., 0:3]
if lights:
vertexBuffer.lightcoord[:] = [[[0.5, 0.5]]]
return vertexBuffer