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.layers import Layer
from mcedit2.rendering.slices import _XYZ
from mcedit2.rendering.vertexarraybuffer import VertexArrayBuffer
from mcedit2.rendering.vertexarraybuffer import QuadVertexArrayBuffer
log = logging.getLogger(__name__)
@ -27,7 +27,7 @@ class EntityMeshBase(ChunkMeshBase):
if 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:]
if len(positions):
positions = numpy.array(positions, dtype=float)

View File

@ -7,7 +7,7 @@ import numpy
from mcedit2.rendering import renderstates, scenegraph
from mcedit2.rendering.blockmeshes import standardCubeTemplates
from mcedit2.rendering.blockmeshes import ChunkMeshBase
from mcedit2.rendering.vertexarraybuffer import VertexArrayBuffer
from mcedit2.rendering.vertexarraybuffer import QuadVertexArrayBuffer
from mceditlib import faces
log = logging.getLogger(__name__)
@ -76,7 +76,7 @@ class LowDetailBlockMesh(ChunkMeshBase):
flatcolors = dim.blocktypes.mapColor[topBlocks, topBlockData][:, numpy.newaxis, :]
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[..., 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.layers import Layer
from mcedit2.rendering.slices import _XYZ, _RGBA
from mcedit2.rendering.vertexarraybuffer import VertexArrayBuffer
from mcedit2.rendering.vertexarraybuffer import QuadVertexArrayBuffer
from mceditlib import faces
log = logging.getLogger(__name__)
@ -84,7 +84,7 @@ class TerrainPopulatedRenderer(ChunkMeshBase):
]
visibleFaces = numpy.array(visibleFaces, dtype='bool')
verts = self.vertexTemplate[visibleFaces]
buffer = VertexArrayBuffer(0, textures=False, lights=False)
buffer = QuadVertexArrayBuffer(0, textures=False, lights=False)
buffer.buffer = verts
self.sceneNode = scenegraph.VertexNode(buffer)

View File

@ -10,7 +10,7 @@ cimport numpy
from mcedit2.rendering import renderstates, scenegraph
from mcedit2.rendering.layers import Layer
from mcedit2.rendering.vertexarraybuffer import VertexArrayBuffer
from mcedit2.rendering.vertexarraybuffer import QuadVertexArrayBuffer
cimport mcedit2.rendering.blockmodels as blockmodels
from libc.stdlib cimport malloc, realloc, free
@ -292,7 +292,7 @@ class BlockModelMesh(object):
vertexBuffer = <float *>realloc(vertexBuffer, buffer_size * sizeof(float) * quadFloats)
if buffer_ptr: # now buffer size
vertexArray = VertexArrayBuffer(buffer_ptr)
vertexArray = QuadVertexArrayBuffer(buffer_ptr)
vabuffer = vertexArray.buffer
memcpy(vabuffer.data, vertexBuffer, buffer_ptr * sizeof(float) * quadFloats)
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.renderstates import _RenderstateAlphaBlendNode
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.glutils import gl
from mceditlib import faces
@ -227,9 +227,9 @@ class SelectionScene(scenegraph.Node):
vertexArrays = []
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):
continue

View File

@ -13,18 +13,42 @@ log = logging.getLogger(__name__)
class VertexArrayBuffer(object):
texOffset = 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
lights.
Vertex buffer, stores an array of `shape` vertexes with a number of elements per vertex
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
:type count: int
:type shape: int | tuple[int]
:type textures: bool
:type lights: bool
:return:
:rtype: VertexArrayBuffer
"""
if not isinstance(shape, tuple):
shape = (shape,)
self.elements = 4
if textures:
self.texOffset = self.elements - 1
@ -34,44 +58,15 @@ class VertexArrayBuffer(object):
self.elements += 2
self.rgbaOffset = self.elements - 1
self.buffer = numpy.zeros((count, 4, self.elements), dtype='f4')
self.gl_type = GL.GL_QUADS
self.shape = shape
self.buffer = numpy.zeros(shape + (self.elements,), dtype='f4')
self.gl_type = gl_type
self.lights = lights
self.textures = textures
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):
copy = VertexArrayBuffer(len(self.buffer), self.textures, self.lights)
copy = VertexArrayBuffer(self.shape, self.gl_type, self.textures, self.lights)
copy.buffer[:] = self.buffer
return copy
@ -112,3 +107,58 @@ class VertexArrayBuffer(object):
def __len__(self):
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