Skip to content

Commit

Permalink
Support divisors in attribute format
Browse files Browse the repository at this point in the history
There are no reasons implementing this in a custom way causing confusion
  • Loading branch information
einarf committed Aug 4, 2019
1 parent 12b739c commit 4675a25
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 12 deletions.
35 changes: 27 additions & 8 deletions moderngl_window/opengl/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,23 @@
from functools import lru_cache
from typing import List

VALID_DIVISORS = ['v', 'i']


class BufferFormat:

def __init__(self, format_string: str, components: int, bytes_per_component: int):
def __init__(self, format_string: str, components: int, bytes_per_component: int, per_instance=False):
"""
Args:
format_string (str): moderngl format string
components (int): components
byte_size (int): bytes per component
per_instance (bool): Instanced attribute
"""
self.format = format_string
self.components = components
self.bytes_per_component = bytes_per_component
self.per_instance = per_instance

@property
def bytes_total(self) -> int:
Expand All @@ -41,26 +45,38 @@ def pad_str(self) -> str:
return "{}x{}".format(self.components, self.bytes_per_component)

def __str__(self) -> str:
return "<BufferFormat {} {} {}>".format(self.format, self.components, self.bytes_per_component)
return "<BufferFormat {} components={} bytes_per_component={}>".format(
self.format, self.components, self.bytes_per_component)

def __repr__(self) -> str:
return str(self)


@lru_cache(maxsize=200)
def attribute_format(fmt: str) -> BufferFormat:
@lru_cache(maxsize=500)
def attribute_format(attr_format: str) -> BufferFormat:
"""Look up info about an attribute format.
Translate the format into a BufferFormat instance
containing things like byte size and components
Args:
frmt (str): Format of an attribute
buffer_format (str): Format of an attribute
Returns:
BufferFormat instance
"""
if not fmt:
raise ValueError("Cannot resolve buffer format: '{}'".format(fmt))
if not attr_format:
raise ValueError("Cannot resolve buffer format: '{}'".format(attr_format))

parts = attr_format.split('/')

# Parse out divisor if present
# Examples: 3f/i, 3f/v
fmt = parts[0]
divisor = ''
if len(parts) > 1:
divisor = parts[1]
if divisor not in VALID_DIVISORS:
raise ValueError("Invalid attribute divisor '{}' in '{}'".format(divisor, buffer_format))

# Parse out out component count and actual format
parts = re.split(r'([fiud])', fmt)
Expand All @@ -71,11 +87,14 @@ def attribute_format(fmt: str) -> BufferFormat:
else:
bformat = fmt

# Construct specific buffer format
fmt_info = buffer_format(bformat)
per_instance = divisor == 'i'
return BufferFormat(
'{}{}'.format(components, bformat),
'{}{}{}'.format(components, bformat, "/i" if per_instance else ''),
components,
fmt_info.bytes_per_component,
per_instance=per_instance,
)


Expand Down
6 changes: 2 additions & 4 deletions moderngl_window/opengl/vao.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ def transform(self, program: moderngl.Program, buffer: moderngl.Buffer,

vao.transform(buffer, mode=mode, vertices=vertices, first=first, instances=instances)

def buffer(self, buffer, buffer_format: str, attribute_names, per_instance=False):
def buffer(self, buffer, buffer_format: str, attribute_names: List[str]):
"""
Register a buffer/vbo for the VAO. This can be called multiple times.
adding multiple buffers (interleaved or not)
Expand All @@ -185,8 +185,6 @@ def buffer(self, buffer, buffer_format: str, attribute_names, per_instance=False
buffer: The buffer data. Can be ``numpy.array``, ``moderngl.Buffer`` or ``bytes``.
buffer_format (str): The format of the buffer. (eg. ``3f 3f`` for interleaved positions and normals).
attribute_names: A list of attribute names this buffer should map to.
Keyword Args:
per_instance (bool): Is this buffer per instance data for instanced rendering?
Returns:
The ``moderngl.Buffer`` instance object. This is handy when providing ``bytes`` and ``numpy.array``.
"""
Expand All @@ -211,7 +209,7 @@ def buffer(self, buffer, buffer_format: str, attribute_names, per_instance=False
if len(formats) != len(attribute_names):
raise VAOError("Format '{}' does not describe attributes {}".format(buffer_format, attribute_names))

self._buffers.append(BufferInfo(buffer, buffer_format, attribute_names, per_instance=per_instance))
self._buffers.append(BufferInfo(buffer, buffer_format, attribute_names))
self.vertex_count = self._buffers[-1].vertices

return buffer
Expand Down

0 comments on commit 4675a25

Please sign in to comment.