Moved display items to GL folder

This commit is contained in:
2024-06-21 11:53:34 -05:00
parent bba4a83240
commit 3bc2f0d372
38 changed files with 358 additions and 706 deletions

View File

@ -7,7 +7,8 @@
target_sources(${DAWN_TARGET_NAME}
PRIVATE
BackBuffer.cpp
Texture.cpp
Texture.cpp
RenderManager.cpp
)
# Subdirs

View File

@ -0,0 +1,31 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "RenderManager.hpp"
#include "game/Game.hpp"
using namespace Dawn;
RenderManager::RenderManager() :
shaderManager()
{
}
void RenderManager::init(const Game &game) {
backBuffer = std::make_shared<BackBuffer>();
backBuffer->setClearColor(COLOR_CORNFLOWER_BLUE);
}
void RenderManager::update(const Game &game) {
backBuffer->bind();
backBuffer->clear(RENDER_TARGET_CLEAR_COLOR | RENDER_TARGET_CLEAR_DEPTH);
}
std::shared_ptr<BackBuffer> RenderManager::getBackBufferRenderTarget() {
return backBuffer;
}
RenderManager::~RenderManager() {
}

View File

@ -0,0 +1,54 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
#include "display/RenderTarget.hpp"
#include "display/shader/ShaderManager.hpp"
#include "display/BackBuffer.hpp"
namespace Dawn {
class Game;
class RenderManager {
private:
std::shared_ptr<BackBuffer> backBuffer = nullptr;
public:
ShaderManager shaderManager;
/**
* Creates a render manager.
*/
RenderManager();
/**
* Initializes the render manager, called by the game during the initial
* set up of the engine.
*
* @param game Game that requested the render manager to initialize.
*/
void init(const Game &game);
/**
* Performs an update/tick of the render manager. This would be the game
* asking the RenderManager to do the rendering.
*/
void update(const Game &game);
/**
* Returns the back buffer render target. This is the render target that
* is used to render to the screen.
*
* @return The back buffer render target.
*/
std::shared_ptr<BackBuffer> getBackBufferRenderTarget();
/**
* Destroys the render manager.
*/
~RenderManager();
};
}

View File

@ -0,0 +1,71 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "event/Event.hpp"
#define RENDER_TARGET_CLEAR_COLOR (1 << 0)
#define RENDER_TARGET_CLEAR_DEPTH (1 << 1)
namespace Dawn {
class RenderTarget {
public:
Event<float_t, float_t> onResize;
/**
* Return the width of the render target.
*
* @return The width of the render target.
*/
virtual float_t getWidth() = 0;
/**
* Return the height of the render target.
*
* @return The height of the render target.
*/
virtual float_t getHeight() = 0;
/**
* Returns the scale (as in pixel density) of the render target. This is
* typically 1.0f, but on high DPI displays this may be 2.0f or higher.
*
* @return The scale of the render target.
*/
virtual float_t getScale() = 0;
/**
* Sets the clear color of the render target when the clear method for
* the color buffer is requested.
*
* @param color Color to use for the clear operation.
*/
virtual void setClearColor(const struct Color color) = 0;
/**
* Request the existing data in the render target to be cleared out. We
* typically assume the render target can support multiple buffer types,
* so you can opt to only clear certain buffer types.
*
* @param clearFlags Flags to request what is going to be cleared.
*/
virtual void clear(const int32_t clearFlags) = 0;
/**
* Bind the render target for rendering to. The proceeding render requests
* will want to render to this render target directly. In future I may
* see if we can have multiple render targets bound at once to make this
* operation perform faster.
*/
virtual void bind() = 0;
/**
* Destroys the render target.
*/
virtual ~RenderTarget() {
}
};
}

View File

@ -62,10 +62,6 @@ void Texture::setSize(
this->bufferRaw(NULL);
}
// bool_t Texture::isReady() {
// return this->id != -1;
// }
void Texture::updateTextureProperties() {
auto setWrapMode = [](GLenum axis, enum TextureWrapMode wm) {
switch(wm) {

View File

@ -5,14 +5,38 @@
#pragma once
#include "dawnopengl.hpp"
#include "display/ITexture.hpp"
#include "display/Color.hpp"
namespace Dawn {
class TextureRenderTarget;
typedef GLuint textureslot_t;
class Texture : public ITexture {
enum class TextureFormat {
R = 1,
RG = 2,
RGB = 3,
RGBA = 4
};
enum class TextureWrapMode {
REPEAT = 0,
MIRRORED_REPEAT = 1,
CLAMP_TO_EDGE = 2,
CLAMP_TO_BORDER = 3
};
enum class TextureFilterMode {
NEAREST = 0,
LINEAR = 1
};
enum class TextureDataFormat {
UNSIGNED_BYTE = sizeof(uint8_t),
FLOAT = sizeof(float_t)
};
class Texture {
private:
int32_t width = -1;
int32_t height = -1;
@ -24,20 +48,84 @@ namespace Dawn {
void bufferRaw(const void *data);
public:
int32_t getWidth() override;
int32_t getHeight() override;
enum TextureWrapMode wrapModeX = TextureWrapMode::REPEAT;
enum TextureWrapMode wrapModeY = TextureWrapMode::REPEAT;
enum TextureFilterMode filterModeMin = TextureFilterMode::NEAREST;
enum TextureFilterMode filterModeMag = TextureFilterMode::NEAREST;
enum TextureFilterMode mipMapFilterModeMin = TextureFilterMode::NEAREST;
enum TextureFilterMode mipMapFilterModeMag = TextureFilterMode::NEAREST;
/**
* Returns the width of the texture.
*
* @return Width of the texture.
*/
int32_t getWidth();
/**
* Returns the height of the texture.
*
* @return Height of the texture.
*/
int32_t getHeight();
/**
* Initializes a texture.
*
* @param width Width of the texture (in pixels).
* @param height Height of the texture (in pixels).
* @param format Data format of the texture to use.
* @param dataFormat Data format of the texture to use.
*/
void setSize(
const int32_t width,
const int32_t height,
const enum TextureFormat format,
const enum TextureDataFormat dataForat
) override;
bool_t isReady() override;
void buffer(const struct ColorU8 pixels[]) override;
void buffer(const struct Color pixels[]);
void buffer(const uint8_t pixels[]) override;
void bind(const uint8_t slot) override;
);
/**
* Returns true only when the texture has been loaded, sized and put on
* the gpu for rendering.
*
* @return True if ready, otherwise false.
*/
bool_t isReady();
/**
* Buffer pixel data onto the GPU. Pixel buffering is rather costly so
* avoid doing this too often.
*
* @param pixels Array of pixels you're trying to buffer.
*/
void buffer(const struct ColorU8 pixels[]);
/**
* Buffer pixel data onto the GPU. Pixel buffering is rather costly so
* avoid doing this too often.
*
* @param pixels Array of pixels you're trying to buffer.
*/
void buffer(const struct Color pixels[]);
/**
* Buffer pixel data onto the GPU. Pixel buffering is rather costly so
* avoid doing this too often.
*
* @param pixels Array of pixels you're trying to buffer.
*/
void buffer(const uint8_t pixels[]);
/**
* Binds the texture to the given slot (for use by the shaders).
*
* @param slot Slot to bind to.
*/
void bind(const uint8_t slot);
/*
* Destructs and disposes the texture off the GPU.
*/
~Texture();
};
}

View File

@ -6,5 +6,7 @@
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
CubeMesh.cpp
Mesh.cpp
QuadMesh.cpp
)

View File

@ -0,0 +1,70 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "CubeMesh.hpp"
using namespace Dawn;
void CubeMesh::buffer(
const std::shared_ptr<Mesh> mesh,
const glm::vec3 pos,
const glm::vec3 size,
const int32_t verticeStart,
const int32_t indiceStart
) {
glm::vec3 positions[CUBE_VERTICE_COUNT] = {
pos,
glm::vec3(pos.x+size.x, pos.y, pos.z),
glm::vec3(pos.x, pos.y+size.y, pos.z),
glm::vec3(pos.x+size.x, pos.y+size.y, pos.z),
glm::vec3(pos.x, pos.y, pos.z+size.z),
glm::vec3(pos.x+size.x, pos.y, pos.z+size.z),
glm::vec3(pos.x, pos.y+size.y, pos.z+size.z),
pos + size
};
glm::vec2 coordinates[CUBE_VERTICE_COUNT] = {
glm::vec2(0, 0),
glm::vec2(1, 0),
glm::vec2(0, 1),
glm::vec2(1, 1),
glm::vec2(0, 0),
glm::vec2(1, 0),
glm::vec2(0, 1),
glm::vec2(1, 1)
};
int32_t indices[CUBE_INDICE_COUNT] = {
// Back
verticeStart, verticeStart + 1, verticeStart + 3,
verticeStart, verticeStart + 2, verticeStart + 3,
// Right
verticeStart + 1, verticeStart + 5, verticeStart + 7,
verticeStart + 1, verticeStart + 3, verticeStart + 7,
// Left
verticeStart + 4, verticeStart, verticeStart + 2,
verticeStart + 4, verticeStart + 6, verticeStart + 2,
// Front
verticeStart + 5, verticeStart + 4, verticeStart + 6,
verticeStart + 5, verticeStart + 7, verticeStart + 6,
// Top
verticeStart + 7, verticeStart + 2, verticeStart + 6,
verticeStart + 7, verticeStart + 3, verticeStart + 2,
// Bottom
verticeStart + 1, verticeStart, verticeStart + 4,
verticeStart + 1, verticeStart + 4, verticeStart + 5
};
mesh->bufferPositions(verticeStart, positions, CUBE_VERTICE_COUNT);
mesh->bufferCoordinates(verticeStart, coordinates, CUBE_VERTICE_COUNT);
mesh->bufferIndices(indiceStart, indices, CUBE_INDICE_COUNT);
}

View File

@ -0,0 +1,30 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/mesh/Mesh.hpp"
#define CUBE_VERTICE_COUNT 8
#define CUBE_INDICE_COUNT 36
namespace Dawn {
class CubeMesh {
public:
/**
* Buffers cube mesh vertices and indices into the given mesh.
*
* @param size The size of the cube.
* @param verticeStart The starting index of the vertices.
* @param indiceStart The starting index of the indices.
*/
static void buffer(
const std::shared_ptr<Mesh> mesh,
const glm::vec3 pos,
const glm::vec3 size,
const int32_t verticeStart,
const int32_t indiceStart
);
};
}

View File

@ -216,35 +216,10 @@ void Mesh::draw(
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,
drawMode,
drawCount,
GL_UNSIGNED_INT,
(void *)(sizeof(int32_t) * start)

View File

@ -4,48 +4,104 @@
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
#include "dawnopengl.hpp"
#include "display/mesh/IMesh.hpp"
namespace Dawn {
class Mesh : public IMesh {
enum MeshDrawMode {
TRIANGLES = GL_TRIANGLES,
TRIANGLE_STRIP = GL_TRIANGLE_STRIP,
TRIANGLE_FAN = GL_TRIANGLE_FAN,
LINES = GL_LINES,
POINTS = GL_POINTS,
LINE_STRIP = GL_LINE_STRIP
};
class Mesh {
protected:
GLuint vertexBuffer = -1;
GLuint indexBuffer = -1;
GLuint vertexArray = -1;
/** How many vertices are in the mesh */
int32_t verticeCount = -1;
/** How many indices are in the mesh */
int32_t indiceCount = -1;
public:
/**
* Create a new set of buffers for the mesh to use.
*
* @param verticeCount How many Vertices will this buffer support.
* @param indiceCount How many Indices will this buffer support.
*/
void createBuffers(
const int32_t verticeCount,
const int32_t indiceCount
) override;
);
void disposeBuffers() override;
/**
* Cleanup the buffers on a given mesh. This is useful if you intend to
* expand the count of vertices your mesh supports.
*/
void disposeBuffers();
/**
* Write vertice positions to the mesh.
*
* @param pos Position, within the buffer, to write to.
* @param positions Array of positions to write.
* @param len How many positions are in the array.
*/
void bufferPositions(
const int32_t pos,
const glm::vec3 positions[],
const int32_t len
) override;
);
/**
* Write vertice coordinates to the mesh.
*
* @param pos Position, within the buffer, to write to.
* @param coordinates Array of coordinates to write.
* @param len How many coordinates are in the array.
*/
void bufferCoordinates(
const int32_t pos,
const glm::vec2 coordinates[],
const int32_t len
) override;
);
/**
* Write indices to the mesh.
*
* @param pos Position, within the buffer, to write to.
* @param indices Array of indices to write.
* @param len How many indices are in the array.
*/
void bufferIndices(
const int32_t pos,
const int32_t indices[],
const int32_t len
) override;
);
/**
* Draw a primitive. Primitives are drawn by their indices.
*
* @param drawMode Which drawing mode to use to draw the primitive.
* @param start Start indice (index) to draw.
* @param count Count of indices to draw. Use -1 to draw all.
*/
void draw(
const enum MeshDrawMode drawMode,
const int32_t start,
const int32_t count
) override;
);
/**
* Cleanup a previously initiated mesh.
*/
~Mesh();
};
}

View File

@ -0,0 +1,72 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "QuadMesh.hpp"
using namespace Dawn;
void QuadMesh::buffer(
const std::shared_ptr<Mesh> mesh,
const glm::vec4 positions,
const glm::vec4 coordinates,
const int32_t verticeStart,
const int32_t indiceStart,
const float_t depth
) {
glm::vec3 vertices[QUAD_VERTICE_COUNT] = {
glm::vec3(positions.x, positions.y, depth),
glm::vec3(positions.z, positions.y, depth),
glm::vec3(positions.x, positions.w, depth),
glm::vec3(positions.z, positions.w, depth)
};
glm::vec2 coords[QUAD_VERTICE_COUNT] = {
glm::vec2(coordinates.x, coordinates.y),
glm::vec2(coordinates.z, coordinates.y),
glm::vec2(coordinates.x, coordinates.w),
glm::vec2(coordinates.z, coordinates.w)
};
int32_t indices[QUAD_INDICE_COUNT] = {
verticeStart, verticeStart + 1, verticeStart + 3,
verticeStart, verticeStart + 2, verticeStart + 3
};
mesh->bufferPositions(verticeStart, vertices, QUAD_VERTICE_COUNT);
mesh->bufferCoordinates(verticeStart, coords, QUAD_VERTICE_COUNT);
mesh->bufferIndices(indiceStart, indices, QUAD_INDICE_COUNT);
}
void QuadMesh::bufferWithIndex(
const std::shared_ptr<Mesh> mesh,
const glm::vec4 positions,
const glm::vec4 coordinates,
const int32_t verticeStart,
const int32_t indiceStart,
const int32_t indexOffset
) {
glm::vec3 vertices[QUAD_VERTICE_COUNT] = {
glm::vec3(positions.x, positions.y, indexOffset),
glm::vec3(positions.z, positions.y, indexOffset + 1),
glm::vec3(positions.x, positions.w, indexOffset + 2),
glm::vec3(positions.z, positions.w, indexOffset + 3)
};
glm::vec2 coords[QUAD_VERTICE_COUNT] = {
glm::vec2(coordinates.x, coordinates.y),
glm::vec2(coordinates.z, coordinates.y),
glm::vec2(coordinates.x, coordinates.w),
glm::vec2(coordinates.z, coordinates.w)
};
int32_t indices[QUAD_INDICE_COUNT] = {
verticeStart, verticeStart + 1, verticeStart + 3,
verticeStart, verticeStart + 2, verticeStart + 3
};
mesh->bufferPositions(verticeStart, vertices, QUAD_VERTICE_COUNT);
mesh->bufferCoordinates(verticeStart, coords, QUAD_VERTICE_COUNT);
mesh->bufferIndices(indiceStart, indices, QUAD_INDICE_COUNT);
}

View File

@ -0,0 +1,55 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/mesh/Mesh.hpp"
#define QUAD_VERTICE_COUNT 4
#define QUAD_INDICE_COUNT 6
namespace Dawn {
class QuadMesh {
public:
/**
* Buffers quad mesh vertices and indices into the given mesh.
*
* @param mesh The mesh to buffer into.
* @param positions The positions of the vertices.
* @param coordinates The coordinates of the vertices.
* @param verticeStart The starting index of the vertices.
* @param indiceStart The starting index of the indices.
* @param depth The depth of the vertices (Z coordinate).
*/
static void buffer(
const std::shared_ptr<Mesh> mesh,
const glm::vec4 positions,
const glm::vec4 coordinates,
const int32_t verticeStart,
const int32_t indiceStart,
const float_t depth = 0.0f
);
/**
* Buffers quad mesh vertices and indices into the given mesh. This will
* store the index of the vertice in the Z component, allowing you to find
* which vertex ID you are rendering in your shader.
*
* @param mesh The mesh to buffer into.
* @param positions The positions of the vertices.
* @param coordinates The coordinates of the vertices.
* @param verticeStart The starting index of the vertices.
* @param indiceStart The starting index of the indices.
* @param indexOffset The offset to add to the index of each vertex.
*/
static void bufferWithIndex(
const std::shared_ptr<Mesh> mesh,
const glm::vec4 positions,
const glm::vec4 coordinates,
const int32_t verticeStart,
const int32_t indiceStart,
const int32_t indexOffset = 0
);
};
}

View File

@ -5,4 +5,39 @@
#include "Shader.hpp"
using namespace Dawn;
using namespace Dawn;
size_t shaderParameterTypeGetSize(const enum ShaderParameterType type) {
switch(type) {
case ShaderParameterType::VEC2:
return sizeof(glm::vec2);
case ShaderParameterType::VEC3:
return sizeof(glm::vec3);
case ShaderParameterType::VEC4:
return sizeof(glm::vec4);
case ShaderParameterType::MAT3:
return sizeof(glm::mat3);
case ShaderParameterType::MAT4:
return sizeof(glm::mat4);
case ShaderParameterType::COLOR:
return sizeof(struct Color);
case ShaderParameterType::FLOAT:
return sizeof(float);
case ShaderParameterType::INT:
return sizeof(int32_t);
case ShaderParameterType::TEXTURE:
return sizeof(shadertexturebinding_t);
default:
assertUnreachable("Unknown ShaderParameterType");
return 0;
};
}

View File

@ -5,7 +5,6 @@
#pragma once
#include "display/shader/ShaderStage.hpp"
#include "display/shader/IShader.hpp"
#include "error/assert.hpp"
#include "error/assertgl.hpp"
#include "display/Color.hpp"
@ -21,17 +20,22 @@ namespace Dawn {
GLSL_330_CORE
};
class ShaderBase {
};
template<typename T>
class Shader : public IShader<T> {
class Shader : public ShaderBase {
private:
std::vector<std::shared_ptr<ShaderStage>> stages;
std::vector<struct ShaderParameter> parameters;
std::vector<struct IShaderStructure> structures;
enum ShaderOpenGLVariant variant;
GLuint shaderProgram = -1;
protected:
T data;
/**
* Overridable function to get the stages for the shader.
*
@ -50,11 +54,29 @@ namespace Dawn {
) = 0;
public:
/**
* Returns the currently uploaded data on the Shader.
*
* @return The uploaded data.
*/
T getData() {
return data;
}
/**
* Sets the entire data to be uploaded.
*
* @param data Data to be uploaded.
*/
void setData(const T data) {
this->data = data;
}
/**
* Initializes the shader, this needs to be called before the shader can
* be used.
*/
void init() override {
void init() {
// Determine which kind of OpenGL shader to use.
variant = ShaderOpenGLVariant::GLSL_330_CORE;
@ -136,7 +158,7 @@ namespace Dawn {
* Binds the shader as the current one, does not upload any data, somewhat
* relies on something else uploading the data.
*/
void bind() override {
void bind() {
glUseProgram(shaderProgram);
assertNoGLError();
}
@ -144,7 +166,7 @@ namespace Dawn {
/**
* Uploads the data to the GPU.
*/
void upload() override {
void upload() {
switch(this->variant) {
case ShaderOpenGLVariant::GLSL_330_CORE:
for(auto param : parameters) {
@ -222,6 +244,9 @@ namespace Dawn {
}
}
/**
* Disposes of the shader.
*/
~Shader() {
// Delete the structures
for(auto structure : structures) {
@ -235,4 +260,12 @@ namespace Dawn {
assertNoGLError();
}
};
/**
* Returns the size of the ShaderParameterType.
*
* @param type The type to get the size of.
* @return Size of the type.
*/
size_t shaderParameterTypeGetSize(const enum Dawn::ShaderParameterType type);
}

View File

@ -0,0 +1,45 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/shader/Shader.hpp"
namespace Dawn {
class ShaderManager {
private:
std::vector<std::shared_ptr<ShaderBase>> shaders;
public:
/**
* Retreives an instance of the shader from the shader manager. If the
* shader does not exist it will be created.
*
* @tparam T Type of shader to retreive.
* @return Shader instance.
*/
template<class T>
std::shared_ptr<T> getShader() {
auto itShaders = shaders.begin();
while(itShaders != shaders.end()) {
// auto shader = itShaders->lock();
// if(!shader) {
// itShaders = shaders.erase(itShaders);
// continue;
// }
// std::shared_ptr<T> casted = std::dynamic_pointer_cast<T>(shader);
auto shader = *itShaders;
std::shared_ptr<T> casted = std::dynamic_pointer_cast<T>(shader);
if(casted) return casted;
itShaders++;
}
auto newShader = std::make_shared<T>();
shaders.push_back(newShader);
newShader->init();
return newShader;
}
};
}

View File

@ -4,10 +4,23 @@
// https://opensource.org/licenses/MIT
#pragma once
#include "display/shader/IShader.hpp"
#include "dawn.hpp"
#include "dawnopengl.hpp"
namespace Dawn {
enum class ShaderParameterType {
VEC2,
VEC3,
VEC4,
MAT3,
MAT4,
COLOR,
FLOAT,
INT,
TEXTURE,
BOOLEAN
};
struct ShaderParameter {
std::string name;
size_t offset;

View File

@ -12,7 +12,7 @@ using namespace Dawn;
ShaderStage::ShaderStage(
const enum ShaderStageType type,
const std::string source
) : IShaderStage(type) {
) : type(type) {
// Get OpenGL Shader Type
GLenum shaderType;
switch(this->type) {

View File

@ -4,13 +4,20 @@
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
#include "dawnopengl.hpp"
#include "display/shader/IShaderStage.hpp"
namespace Dawn {
class ShaderStage : public IShaderStage {
enum class ShaderStageType {
VERTEX,
FRAGMENT,
// COMPUTE
};
class ShaderStage {
public:
GLuint id = -1;
const enum ShaderStageType type;
/**
* Constructs a new ShaderStage.