New scene items system
This commit is contained in:
16
src/dawnopengl/display/CMakeLists.txt
Normal file
16
src/dawnopengl/display/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
||||
# Copyright (c) 2022 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
# target_sources(${DAWN_TARGET_NAME}
|
||||
# PRIVATE
|
||||
# RenderManager.cpp
|
||||
# BackBufferRenderTarget.cpp
|
||||
# Texture.cpp
|
||||
# TextureRenderTarget.cpp
|
||||
# )
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(mesh)
|
10
src/dawnopengl/display/mesh/CMakeLists.txt
Normal file
10
src/dawnopengl/display/mesh/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
# Copyright (c) 2022 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
Mesh.cpp
|
||||
)
|
251
src/dawnopengl/display/mesh/Mesh.cpp
Normal file
251
src/dawnopengl/display/mesh/Mesh.cpp
Normal file
@ -0,0 +1,251 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "assert/assert.hpp"
|
||||
#include "assert/assertgl.hpp"
|
||||
#include "display/mesh/Mesh.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void Mesh::createBuffers(
|
||||
const int32_t verticeCount,
|
||||
const int32_t indiceCount
|
||||
) {
|
||||
assertTrue(verticeCount > 0, "Vertice count must be greater than zero.");
|
||||
assertTrue(indiceCount > 0, "Indice count must be greater than zero.");
|
||||
|
||||
this->disposeBuffers();
|
||||
|
||||
this->verticeCount = verticeCount;
|
||||
this->indiceCount = indiceCount;
|
||||
|
||||
auto sizePos = sizeof(glm::vec3) * verticeCount;
|
||||
auto sizeInds = sizeof(meshindice_t) * indiceCount;
|
||||
auto sizeCoords = sizeof(glm::vec2) * verticeCount;
|
||||
|
||||
// Generate vertex array, I don't think I need to do this tbh.
|
||||
glGenVertexArrays(1, &this->vertexArray);
|
||||
assertNoGLError();
|
||||
glBindVertexArray(this->vertexArray);
|
||||
assertNoGLError();
|
||||
|
||||
// Create some buffers, one for the vertex data, one for the indices
|
||||
GLuint buffer[2];
|
||||
glGenBuffers(2, buffer);
|
||||
assertNoGLError();
|
||||
this->vertexBuffer = buffer[0];
|
||||
if(this->vertexBuffer < 0) assertUnreachable("Can't make vertex buffer");
|
||||
this->indexBuffer = buffer[1];
|
||||
if(this->indexBuffer < 0) assertUnreachable("Can't make index buffer");
|
||||
|
||||
// Buffer an empty set of data then buffer each component
|
||||
glBindBuffer(GL_ARRAY_BUFFER, this->vertexBuffer);
|
||||
assertNoGLError();
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->indexBuffer);
|
||||
assertNoGLError();
|
||||
glBufferData(GL_ARRAY_BUFFER, sizePos+sizeCoords, 0, GL_DYNAMIC_DRAW);
|
||||
assertNoGLError();
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeInds, 0, GL_DYNAMIC_DRAW);
|
||||
assertNoGLError();
|
||||
|
||||
// Setup the attrib pointers
|
||||
size_t offset = 0;
|
||||
glVertexAttribPointer(
|
||||
0, sizeof(glm::vec3) / sizeof(float_t),
|
||||
GL_FLOAT, GL_FALSE,
|
||||
0, (void *)offset
|
||||
);
|
||||
assertNoGLError();
|
||||
glEnableVertexAttribArray(0);
|
||||
assertNoGLError();
|
||||
|
||||
offset += sizePos;
|
||||
glVertexAttribPointer(
|
||||
1, sizeof(glm::vec2) / sizeof(float_t),
|
||||
GL_FLOAT, GL_FALSE,
|
||||
0, (void *)offset
|
||||
);
|
||||
assertNoGLError();
|
||||
glEnableVertexAttribArray(1);
|
||||
assertNoGLError();
|
||||
}
|
||||
|
||||
void Mesh::disposeBuffers() {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
assertNoGLError();
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
assertNoGLError();
|
||||
|
||||
if(this->vertexBuffer != -1) {
|
||||
glDeleteBuffers(1, &this->vertexBuffer);
|
||||
assertNoGLError();
|
||||
this->vertexBuffer = -1;
|
||||
this->verticeCount = -1;
|
||||
}
|
||||
|
||||
if(this->indexBuffer != -1) {
|
||||
glDeleteBuffers(1, &this->indexBuffer);
|
||||
assertNoGLError();
|
||||
this->indexBuffer = -1;
|
||||
this->indiceCount = -1;
|
||||
}
|
||||
|
||||
if(this->vertexArray) {
|
||||
glDeleteVertexArrays(1, &this->vertexArray);
|
||||
assertNoGLError();
|
||||
this->vertexArray = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void Mesh::bufferPositions(
|
||||
const int32_t pos,
|
||||
const glm::vec3 positions[],
|
||||
const int32_t len
|
||||
) {
|
||||
assertNotNull(positions, "Positions cannot be null");
|
||||
assertTrue(pos >= 0 && pos < verticeCount, "Position must be within range");
|
||||
assertTrue(pos+len <= verticeCount, "Position + Length must be within range");
|
||||
assertTrue(len > 0, "Length must be greater than zero");
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
|
||||
assertNoGLError();
|
||||
glBufferSubData(
|
||||
GL_ARRAY_BUFFER,
|
||||
sizeof(glm::vec3) * pos,
|
||||
sizeof(glm::vec3) * len,
|
||||
(void*)positions
|
||||
);
|
||||
assertNoGLError();
|
||||
}
|
||||
|
||||
void Mesh::bufferCoordinates(
|
||||
const int32_t pos,
|
||||
const glm::vec2 coordinates[],
|
||||
const int32_t len
|
||||
) {
|
||||
assertNotNull(coordinates, "Coordinates cannot be null");
|
||||
assertTrue(pos >= 0 && pos < verticeCount, "Position must be within range");
|
||||
assertTrue(pos+len <= verticeCount, "Position + Length must be within range");
|
||||
assertTrue(len > 0, "Length must be greater than zero");
|
||||
|
||||
auto offsetCoordinates = (
|
||||
(sizeof(glm::vec3) * this->verticeCount) +
|
||||
(sizeof(glm::vec2) * pos)
|
||||
);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, this->vertexBuffer);
|
||||
assertNoGLError();
|
||||
glBufferSubData(
|
||||
GL_ARRAY_BUFFER,
|
||||
offsetCoordinates,
|
||||
sizeof(glm::vec2) * len,
|
||||
(void*)coordinates
|
||||
);
|
||||
assertNoGLError();
|
||||
}
|
||||
|
||||
void Mesh::bufferIndices(
|
||||
const int32_t pos,
|
||||
const int32_t indices[],
|
||||
const int32_t len
|
||||
) {
|
||||
assertNotNull(indices, "Indices cannot be null");
|
||||
assertTrue(pos >= 0 && pos < indiceCount, "Position must be within range");
|
||||
assertTrue(pos+len <= indiceCount, "Position + Length must be within range");
|
||||
assertTrue(len > 0, "Length must be greater than zero");
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
|
||||
assertNoGLError();
|
||||
glBufferSubData(
|
||||
GL_ELEMENT_ARRAY_BUFFER,
|
||||
sizeof(meshindice_t) * pos,
|
||||
sizeof(meshindice_t) * len,
|
||||
(void*)indices
|
||||
);
|
||||
assertNoGLError();
|
||||
}
|
||||
|
||||
void Mesh::draw(
|
||||
const enum MeshDrawMode drawMode,
|
||||
const int32_t start,
|
||||
const int32_t count
|
||||
) {
|
||||
if(
|
||||
count == 0 ||
|
||||
this->vertexBuffer == -1 ||
|
||||
this->indexBuffer == -1
|
||||
) return;
|
||||
|
||||
int32_t drawCount = count;
|
||||
if(count == -1) drawCount = this->indiceCount;
|
||||
|
||||
// Re-Bind the buffers
|
||||
glBindVertexArray(this->vertexArray);
|
||||
assertNoGLError();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, this->vertexBuffer);
|
||||
assertNoGLError();
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->indexBuffer);
|
||||
assertNoGLError();
|
||||
|
||||
// Re-Calculate the attrib pointers.
|
||||
size_t offset = 0;
|
||||
glVertexAttribPointer(
|
||||
0, sizeof(glm::vec3) / sizeof(float_t),
|
||||
GL_FLOAT, GL_FALSE,
|
||||
0, (void *)offset
|
||||
);
|
||||
assertNoGLError();
|
||||
glEnableVertexAttribArray(0);
|
||||
assertNoGLError();
|
||||
|
||||
offset += sizeof(glm::vec3) * this->verticeCount;
|
||||
glVertexAttribPointer(
|
||||
1, sizeof(glm::vec2) / sizeof(float_t),
|
||||
GL_FLOAT, GL_FALSE,
|
||||
0, (void *)offset
|
||||
);
|
||||
assertNoGLError();
|
||||
glEnableVertexAttribArray(1);
|
||||
assertNoGLError();
|
||||
|
||||
GLuint glDrawMode;
|
||||
switch(drawMode) {
|
||||
case MeshDrawMode::TRIANGLES:
|
||||
glDrawMode = GL_TRIANGLES;
|
||||
break;
|
||||
|
||||
case MeshDrawMode::TRIANGLE_STRIP:
|
||||
glDrawMode = GL_TRIANGLE_STRIP;
|
||||
break;
|
||||
|
||||
case MeshDrawMode::TRIANGLE_FAN:
|
||||
glDrawMode = GL_TRIANGLE_FAN;
|
||||
break;
|
||||
|
||||
case MeshDrawMode::LINES:
|
||||
glDrawMode = GL_LINES;
|
||||
break;
|
||||
|
||||
case MeshDrawMode::POINTS:
|
||||
glDrawMode = GL_POINTS;
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unsupported draw mode");
|
||||
}
|
||||
|
||||
// Render the elements.
|
||||
glDrawElements(
|
||||
glDrawMode,
|
||||
drawCount,
|
||||
GL_UNSIGNED_INT,
|
||||
(void *)(sizeof(int32_t) * start)
|
||||
);
|
||||
assertNoGLError();
|
||||
}
|
||||
|
||||
Mesh::~Mesh() {
|
||||
this->disposeBuffers();
|
||||
}
|
48
src/dawnopengl/display/mesh/Mesh.hpp
Normal file
48
src/dawnopengl/display/mesh/Mesh.hpp
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/mesh/IMesh.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class Mesh : public IMesh {
|
||||
protected:
|
||||
GLuint vertexBuffer = -1;
|
||||
GLuint indexBuffer = -1;
|
||||
GLuint vertexArray = -1;
|
||||
|
||||
public:
|
||||
void createBuffers(
|
||||
const int32_t verticeCount,
|
||||
const int32_t indiceCount
|
||||
) override;
|
||||
|
||||
void disposeBuffers() override;
|
||||
|
||||
void bufferPositions(
|
||||
const int32_t pos,
|
||||
const glm::vec3 positions[],
|
||||
const int32_t len
|
||||
) override;
|
||||
|
||||
void bufferCoordinates(
|
||||
const int32_t pos,
|
||||
const glm::vec2 coordinates[],
|
||||
const int32_t len
|
||||
) override;
|
||||
|
||||
void bufferIndices(
|
||||
const int32_t pos,
|
||||
const int32_t indices[],
|
||||
const int32_t len
|
||||
) override;
|
||||
|
||||
void draw(
|
||||
const enum MeshDrawMode drawMode,
|
||||
const int32_t start,
|
||||
const int32_t count
|
||||
) override;
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user