Skip to content

Commit

Permalink
Remove need for dynamic VBOs
Browse files Browse the repository at this point in the history
  • Loading branch information
ultraq committed Jun 28, 2024
1 parent 0862da9 commit 8b3157c
Show file tree
Hide file tree
Showing 10 changed files with 36 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ class Map extends Node<Map> {
return scene
.requestCreateOrGet(new MeshRequest(MeshType.TRIANGLES,
new VertexBufferLayout(Attribute.POSITION, Attribute.COLOUR, Attribute.TEXTURE_UVS),
allVertices, Colour.WHITE, allTextureUVs, allIndices, false))
allVertices, Colour.WHITE, allTextureUVs, allIndices))
.thenAcceptAsync { newMesh ->
fullMesh = newMesh
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,14 @@ interface GraphicsRenderer extends AutoCloseable, EventTarget {
*/
default Mesh createMesh(MeshType type, VertexBufferLayout layout, Vector2f[] vertices, Colour colour) {

return createMesh(type, layout, vertices, colour, null, null, false)
return createMesh(type, layout, vertices, colour, null, null)
}

/**
* Create a mesh with all of the mesh parts.
*/
Mesh createMesh(MeshType type, VertexBufferLayout layout, Vector2f[] vertices, Colour colour, Vector2f[] textureUVs,
int[] indices, boolean dynamic)
int[] indices)

/**
* Create a new shader program from the given configuration, or return the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ interface GraphicsRequests {

@ImmutableOptions(knownImmutables = ['layout', 'colour'])
static record MeshRequest(MeshType type, VertexBufferLayout layout, Vector2f[] vertices, Colour colour,
Vector2f[] textureUVs, int[] indices, boolean dynamic) implements Request<Mesh> {
Vector2f[] textureUVs, int[] indices) implements Request<Mesh> {

MeshRequest(MeshType type, VertexBufferLayout layout, Vector2f[] vertices, Colour colour, int[] indices, boolean dynamic) {
this(type, layout, vertices, colour, null, indices, dynamic)
MeshRequest(MeshType type, VertexBufferLayout layout, Vector2f[] vertices, Colour colour, int[] indices) {
this(type, layout, vertices, colour, null, indices)
}

MeshRequest(MeshType type, VertexBufferLayout layout, Vector2f[] vertices, Colour colour) {
this(type, layout, vertices, colour, null, null, false)
this(type, layout, vertices, colour, null, null)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ class GraphicsSystem extends EngineSystem implements GraphicsRequests {
var resource = switch (request) {
case ShaderRequest -> renderer.createShader(request.shaderConfig())
case MeshRequest -> renderer.createMesh(request.type(), request.layout(), request.vertices(), request.colour(),
request.textureUVs(), request.indices(), request.dynamic())
request.textureUVs(), request.indices())
case SpriteMeshRequest -> renderer.createSpriteMesh(request.surface(), request.textureUVs())
case TextureRequest -> renderer.createTexture(request.width(), request.height(), request.format(), request.data())
case SpriteSheetRequest -> renderer.createSpriteSheet(request.width(), request.height(), request.format(), request.data())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,4 @@ abstract class Mesh implements GraphicsResource {
* Use this mesh in upcoming render operations.
*/
abstract void bind()

/**
* Update the textureUVs part of the mesh data. This is only allowed on
* meshes that have been configured to use dynamic buffer data.
*/
abstract void updateTextureUvs(Vector2f[] textureUVs)
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ abstract class Shader implements GraphicsResource {
final Attribute[] attributes
final Uniform[] uniforms

private final Map<String, Object> lastValues = [:]

/**
* Update a shader's uniforms using the given context.
*/
Expand All @@ -49,7 +51,26 @@ abstract class Shader implements GraphicsResource {
* Apply a data uniform to the shader. If {@code data} is an array, it can be
* used to determine the shader type (eg: 2 floats = vec2).
*/
abstract void setUniformGeneric(String name, Object data)
void setUniformGeneric(String name, Object data) {

if (data == null) {
throw new IllegalArgumentException("Data value for key ${name} was null")
}

// Only perform an update if there was a change in the value since last time
if (lastValues[name] != data) {
lastValues[name] = data

switch (data) {
case Float -> setUniform(name, data)
case Float[] -> setUniform(name, (float[])data)
case Integer -> setUniform(name, data)
case Integer[] -> setUniform(name, (int[])data)
case Matrix4f -> setUniform(name, data)
default -> throw new UnsupportedOperationException("Data type of ${data.class.simpleName} not supported")
}
}
}

/**
* Apply a data uniform to the shader. The type of data is determined by the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,13 @@ class OpenGLMesh extends Mesh {
final int vertexArrayId
final int vertexBufferId
final int elementBufferId
final boolean dynamic

private Vector2f[] lastTextureUVs

/**
* Constructor, creates a new OpenGL mesh.
*/
OpenGLMesh(int type, VertexBufferLayout layout, Vector2f[] vertices, Colour colour, Vector2f[] textureUVs,
int[] indices, boolean dynamic) {
OpenGLMesh(int type, VertexBufferLayout layout, Vector2f[] vertices, Colour colour, Vector2f[] textureUVs, int[] indices) {

super(type, layout, vertices, colour, textureUVs, indices)

Expand All @@ -73,7 +71,7 @@ class OpenGLMesh extends Mesh {
}
}
vertexBuffer.flip()
glBufferData(GL_ARRAY_BUFFER, vertexBuffer, dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW)
glBufferData(GL_ARRAY_BUFFER, vertexBuffer, GL_STATIC_DRAW)

layout.attributes.each { attribute ->
glEnableVertexAttribArray(attribute.location)
Expand All @@ -96,7 +94,6 @@ class OpenGLMesh extends Mesh {
elementBufferId = 0
}

this.dynamic = dynamic
lastTextureUVs = textureUVs
}

Expand All @@ -115,28 +112,4 @@ class OpenGLMesh extends Mesh {
glDeleteBuffers(vertexBufferId)
glDeleteVertexArrays(vertexArrayId)
}

@Override
void updateTextureUvs(Vector2f[] textureUVs) {

if (!this.textureUVs) {
throw new IllegalStateException('Cannot update textureUVs on a mesh that has no textureUVs to begin with')
}

if (!dynamic) {
throw new IllegalStateException('Cannot update textureUVs on a mesh that was created without a dynamic buffer')
}

if (textureUVs != lastTextureUVs) {
stackPush().withCloseable { stack ->
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferId)
textureUVs.eachWithIndex { textureUv, index ->
glBufferSubData(GL_ARRAY_BUFFER,
(layout.sizeInBytes() * index) + layout.offsetOfInBytes(Attribute.TEXTURE_UVS),
textureUv.get(stack.mallocFloat(Vector2f.FLOATS)))
}
}
lastTextureUVs = textureUVs
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -192,10 +192,10 @@ class OpenGLRenderer implements GraphicsRenderer {

@Override
Mesh createMesh(MeshType type, VertexBufferLayout layout, Vector2f[] vertices, Colour colour, Vector2f[] textureUVs,
int[] indices, boolean dynamic) {
int[] indices) {

var mesh = new OpenGLMesh(type == MeshType.LINES ? GL_LINES : type == MeshType.LINE_LOOP ? GL_LINE_LOOP : GL_TRIANGLES,
layout, vertices, colour, textureUVs, indices, dynamic)
layout, vertices, colour, textureUVs, indices)
trigger(new MeshCreatedEvent(mesh))
return mesh
}
Expand Down Expand Up @@ -229,8 +229,7 @@ class OpenGLRenderer implements GraphicsRenderer {
surface as Vector2f[],
Colour.WHITE,
textureUVs as Vector2f[],
[0, 1, 3, 1, 2, 3] as int[],
true
0, 1, 3, 1, 2, 3
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,23 +118,6 @@ class OpenGLShader extends Shader {
return glGetUniformLocation(programId, name)
}

@Override
void setUniformGeneric(String name, Object data) {

if (data == null) {
throw new IllegalArgumentException("Data value for key ${name} was null")
}

switch (data) {
case float, Float -> setUniform(name, (float)data)
case float[], Float[] -> setUniform(name, (float[])data)
case int, Integer -> setUniform(name, (int)data)
case int[], Integer[] -> setUniform(name, (int[])data)
case Matrix4f -> setUniform(name, data)
default -> throw new UnsupportedOperationException("Data type of ${data.class.simpleName} not supported")
}
}

@Override
void setUniform(String name, float[] data) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class Primitive extends Node<Primitive> implements GraphicsElement {
scene
.requestCreateOrGet(type == MeshType.TRIANGLES ?
new MeshRequest(type, new VertexBufferLayout(Attribute.POSITION, Attribute.COLOUR), this.points, colour,
[0, 1, 3, 1, 2, 3] as int[], false) :
[0, 1, 3, 1, 2, 3] as int[]) :
new MeshRequest(type, new VertexBufferLayout(Attribute.POSITION, Attribute.COLOUR), this.points, colour))
.thenAcceptAsync { newMesh ->
mesh = newMesh
Expand Down

0 comments on commit 8b3157c

Please sign in to comment.