Dawn reset
This commit is contained in:
@ -1,69 +0,0 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "dawnopengl.hpp"
|
||||
#include "assert/assert.hpp"
|
||||
#include "assert/assertgl.hpp"
|
||||
#include "util/Flag.hpp"
|
||||
#include "BackBufferRenderTarget.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
BackBufferRenderTarget::BackBufferRenderTarget() {
|
||||
|
||||
}
|
||||
|
||||
float_t BackBufferRenderTarget::getScale() {
|
||||
return this->scale;
|
||||
}
|
||||
|
||||
float_t BackBufferRenderTarget::getWidth() {
|
||||
return this->width;
|
||||
}
|
||||
|
||||
float_t BackBufferRenderTarget::getHeight() {
|
||||
return this->height;
|
||||
}
|
||||
|
||||
void BackBufferRenderTarget::setSize(
|
||||
const float_t width,
|
||||
const float_t height
|
||||
) {
|
||||
if(this->width == width && this->height == height) return;
|
||||
|
||||
// Fixes a new bug that it seems GLFW has introduced.
|
||||
this->width = width == 0 ? 1 : width;
|
||||
this->height = height == 0 ? 1 : height;
|
||||
|
||||
onResize.emit(this->width, this->height);
|
||||
}
|
||||
|
||||
void BackBufferRenderTarget::setClearColor(const struct Color color) {
|
||||
this->clearColor = color;
|
||||
}
|
||||
|
||||
void BackBufferRenderTarget::clear(const int32_t clearFlags) {
|
||||
glClearColor(clearColor.r, clearColor.g, clearColor.b, 1.0f);
|
||||
assertNoGLError();
|
||||
|
||||
GLbitfield mask = 0;
|
||||
if(Flag::isOn(clearFlags, RENDER_TARGET_CLEAR_COLOR)) {
|
||||
mask |= GL_COLOR_BUFFER_BIT;
|
||||
}
|
||||
|
||||
if(Flag::isOn(clearFlags, RENDER_TARGET_CLEAR_DEPTH)) {
|
||||
mask |= GL_DEPTH_BUFFER_BIT;
|
||||
}
|
||||
|
||||
glClear(mask);
|
||||
assertNoGLError();
|
||||
}
|
||||
|
||||
void BackBufferRenderTarget::bind() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
assertNoGLError();
|
||||
glViewport(0, 0, (GLsizei)this->width, (GLsizei)this->height);
|
||||
assertNoGLError();
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/Color.hpp"
|
||||
#include "display/RenderTarget.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class BackBufferRenderTarget final : public RenderTarget {
|
||||
private:
|
||||
float_t width = 1;
|
||||
float_t height = 1;
|
||||
struct Color clearColor = COLOR_CORNFLOWER_BLUE;
|
||||
|
||||
public:
|
||||
float_t scale = 1.0f;
|
||||
|
||||
/**
|
||||
* Construct the back buffer render target.
|
||||
*/
|
||||
BackBufferRenderTarget();
|
||||
|
||||
float_t getScale() override;
|
||||
float_t getWidth() override;
|
||||
float_t getHeight() override;
|
||||
void setClearColor(const struct Color color) override;
|
||||
void clear(const int32_t) override;
|
||||
void bind() override;
|
||||
|
||||
/**
|
||||
* Requests to modify the viewport directly. This is mostly to be called
|
||||
* by whatever is setting the window/display resolution, so that the
|
||||
* backbuffer can keep track of what the viewport size is. This should
|
||||
* also be DPI aware, e.g. "4k @ 2xDPI, resulting in a 1080p equiv" should
|
||||
* still call this method with 3840, 2160.
|
||||
*
|
||||
* @param width New width of the back buffer.
|
||||
* @param height New height of the back buffer.
|
||||
*/
|
||||
void setSize(const float_t width, const float_t height);
|
||||
};
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
# 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
|
||||
BackBufferRenderTarget.cpp
|
||||
Texture.cpp
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(mesh)
|
||||
add_subdirectory(shader)
|
@ -1,213 +0,0 @@
|
||||
// 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 "Texture.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void Texture::bind(const uint8_t slot) {
|
||||
assertTrue(this->id != -1, "Texture is not ready!");
|
||||
glActiveTexture(GL_TEXTURE0 + slot);
|
||||
assertNoGLError();
|
||||
glBindTexture(GL_TEXTURE_2D, this->id);
|
||||
assertNoGLError();
|
||||
this->updateTextureProperties();
|
||||
}
|
||||
|
||||
int32_t Texture::getWidth() {
|
||||
return this->width;
|
||||
}
|
||||
|
||||
int32_t Texture::getHeight() {
|
||||
return this->height;
|
||||
}
|
||||
|
||||
bool_t Texture::isReady() {
|
||||
return this->id != -1;
|
||||
}
|
||||
|
||||
void Texture::setSize(
|
||||
const int32_t width,
|
||||
const int32_t height,
|
||||
const enum TextureFormat format,
|
||||
const enum TextureDataFormat dataFormat
|
||||
) {
|
||||
if(this->id != -1) {
|
||||
glDeleteTextures(1, &this->id);
|
||||
assertNoGLError();
|
||||
this->id = -1;
|
||||
}
|
||||
|
||||
int32_t maxSize;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize);
|
||||
assertTrue(width > 0 && width <= maxSize, "Width is out of bounds!");
|
||||
assertTrue(height > 0 && height <= maxSize, "Height is out of bounds!");
|
||||
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
this->format = format;
|
||||
this->dataFormat = dataFormat;
|
||||
|
||||
glGenTextures(1, &this->id);
|
||||
assertNoGLError();
|
||||
if(this->id <= 0) assertUnreachable("Texture generation failed!");
|
||||
|
||||
// Initialize the texture to blank
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
assertNoGLError();
|
||||
this->bufferRaw(NULL);
|
||||
}
|
||||
|
||||
// bool_t Texture::isReady() {
|
||||
// return this->id != -1;
|
||||
// }
|
||||
|
||||
void Texture::updateTextureProperties() {
|
||||
auto setWrapMode = [](GLenum axis, enum TextureWrapMode wm) {
|
||||
switch(wm) {
|
||||
case TextureWrapMode::REPEAT:
|
||||
glTexParameteri(GL_TEXTURE_2D, axis, GL_REPEAT);
|
||||
break;
|
||||
|
||||
case TextureWrapMode::MIRRORED_REPEAT:
|
||||
glTexParameteri(GL_TEXTURE_2D, axis, GL_MIRRORED_REPEAT);
|
||||
break;
|
||||
|
||||
case TextureWrapMode::CLAMP_TO_EDGE:
|
||||
glTexParameteri(GL_TEXTURE_2D, axis, GL_CLAMP_TO_EDGE);
|
||||
break;
|
||||
|
||||
case TextureWrapMode::CLAMP_TO_BORDER:
|
||||
glTexParameteri(GL_TEXTURE_2D, axis, GL_CLAMP_TO_BORDER);
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unknown wrap mode!");
|
||||
}
|
||||
assertNoGLError();
|
||||
};
|
||||
|
||||
setWrapMode(GL_TEXTURE_WRAP_S, this->wrapModeX);
|
||||
setWrapMode(GL_TEXTURE_WRAP_T, this->wrapModeY);
|
||||
|
||||
auto setFilterMode = [](
|
||||
GLenum minMag,
|
||||
enum TextureFilterMode filter,
|
||||
enum TextureFilterMode mapFilterMode
|
||||
) {
|
||||
switch(filter) {
|
||||
case TextureFilterMode::NEAREST: {
|
||||
glTexParameteri(GL_TEXTURE_2D, minMag, GL_NEAREST);
|
||||
break;
|
||||
}
|
||||
|
||||
case TextureFilterMode::LINEAR: {
|
||||
glTexParameteri(GL_TEXTURE_2D, minMag, GL_LINEAR);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
assertUnreachable("Unknown filter mode!");
|
||||
}
|
||||
}
|
||||
assertNoGLError();
|
||||
};
|
||||
|
||||
setFilterMode(
|
||||
GL_TEXTURE_MIN_FILTER, this->filterModeMin, this->mipMapFilterModeMin
|
||||
);
|
||||
setFilterMode(
|
||||
GL_TEXTURE_MAG_FILTER, this->filterModeMag, this->mipMapFilterModeMag
|
||||
);
|
||||
}
|
||||
|
||||
void Texture::bufferRaw(const void *data) {
|
||||
assertTrue(this->id != -1, "Texture is not ready!");
|
||||
|
||||
GLenum format;
|
||||
switch(this->format) {
|
||||
case TextureFormat::R:
|
||||
format = GL_RED;
|
||||
break;
|
||||
|
||||
case TextureFormat::RG:
|
||||
format = GL_RG;
|
||||
break;
|
||||
|
||||
case TextureFormat::RGB:
|
||||
format = GL_RGB;
|
||||
break;
|
||||
|
||||
case TextureFormat::RGBA:
|
||||
format = GL_RGBA;
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unknown texture format!");
|
||||
}
|
||||
|
||||
GLenum dataFormat;
|
||||
switch(this->dataFormat) {
|
||||
case TextureDataFormat::UNSIGNED_BYTE:
|
||||
dataFormat = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
|
||||
case TextureDataFormat::FLOAT:
|
||||
dataFormat = GL_FLOAT;
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unknown texture data format!");
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, this->id);
|
||||
assertNoGLError();
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D, 0, format,
|
||||
this->width, this->height,
|
||||
0, format, dataFormat, data
|
||||
);
|
||||
assertNoGLError();
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
assertNoGLError();
|
||||
}
|
||||
|
||||
void Texture::buffer(const struct ColorU8 pixels[]) {
|
||||
assertTrue(
|
||||
this->dataFormat == TextureDataFormat::UNSIGNED_BYTE,
|
||||
"Texture data format must be unsigned byte!"
|
||||
);
|
||||
this->bufferRaw((void*)pixels);
|
||||
}
|
||||
|
||||
void Texture::buffer(const struct Color pixels[]) {
|
||||
std::cout << "Correct buffer" << std::endl;
|
||||
assertTrue(
|
||||
this->dataFormat == TextureDataFormat::FLOAT,
|
||||
"Texture data format must be float!"
|
||||
);
|
||||
assertTrue(
|
||||
this->format == TextureFormat::RGBA,
|
||||
"Texture format must be RGBA!"
|
||||
);
|
||||
this->bufferRaw((void*)pixels);
|
||||
}
|
||||
|
||||
void Texture::buffer(const uint8_t pixels[]) {
|
||||
assertTrue(
|
||||
this->dataFormat == TextureDataFormat::UNSIGNED_BYTE,
|
||||
"Texture data format must be unsigned byte!"
|
||||
);
|
||||
this->bufferRaw((void*)pixels);
|
||||
}
|
||||
|
||||
Texture::~Texture() {
|
||||
if(this->id != -1) {
|
||||
glDeleteTextures(1, &this->id);
|
||||
assertNoGLError();
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnopengl.hpp"
|
||||
#include "display/ITexture.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class TextureRenderTarget;
|
||||
|
||||
typedef GLuint textureslot_t;
|
||||
|
||||
class Texture : public ITexture {
|
||||
private:
|
||||
int32_t width = -1;
|
||||
int32_t height = -1;
|
||||
GLuint id = -1;
|
||||
enum TextureFormat format;
|
||||
enum TextureDataFormat dataFormat;
|
||||
|
||||
void updateTextureProperties();
|
||||
void bufferRaw(const void *data);
|
||||
|
||||
public:
|
||||
int32_t getWidth() override;
|
||||
int32_t getHeight() override;
|
||||
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;
|
||||
|
||||
~Texture();
|
||||
};
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
# 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
|
||||
)
|
@ -1,257 +0,0 @@
|
||||
// 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.");
|
||||
|
||||
// Can we re-use the buffers?
|
||||
if(
|
||||
verticeCount <= this->verticeCount &&
|
||||
indiceCount <= this->indiceCount
|
||||
) return;
|
||||
|
||||
this->disposeBuffers();
|
||||
|
||||
this->verticeCount = verticeCount;
|
||||
this->indiceCount = indiceCount;
|
||||
|
||||
auto sizePos = sizeof(glm::vec3) * verticeCount;
|
||||
auto sizeInds = sizeof(int32_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(int32_t) * pos,
|
||||
sizeof(int32_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();
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnopengl.hpp"
|
||||
#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;
|
||||
|
||||
~Mesh();
|
||||
};
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
# Copyright (c) 2023 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
Shader.cpp
|
||||
ShaderStage.cpp
|
||||
SimpleTexturedShader.cpp
|
||||
UIShader.cpp
|
||||
ShaderParameter.cpp
|
||||
)
|
@ -1,8 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "Shader.hpp"
|
||||
|
||||
using namespace Dawn;
|
@ -1,238 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/shader/ShaderStage.hpp"
|
||||
#include "display/shader/IShader.hpp"
|
||||
#include "assert/assert.hpp"
|
||||
#include "assert/assertgl.hpp"
|
||||
#include "display/Color.hpp"
|
||||
#include "display/Texture.hpp"
|
||||
|
||||
#include "ShaderParameter.hpp"
|
||||
#include "ShaderStructure.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
typedef GLuint shadertexturebinding_t;
|
||||
|
||||
enum class ShaderOpenGLVariant {
|
||||
GLSL_330_CORE
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class Shader : public IShader<T> {
|
||||
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:
|
||||
/**
|
||||
* Overridable function to get the stages for the shader.
|
||||
*
|
||||
* @param variant The variant of the shader to use.
|
||||
* @param rel The relative data to use.
|
||||
* @param stages The stages to add to.
|
||||
* @param parameters The parameters to add to.
|
||||
* @param structures The structures to add to.
|
||||
*/
|
||||
virtual void getStages(
|
||||
const enum ShaderOpenGLVariant variant,
|
||||
const T *rel,
|
||||
std::vector<std::shared_ptr<ShaderStage>> &stages,
|
||||
std::vector<struct ShaderParameter> ¶meters,
|
||||
std::vector<struct IShaderStructure> &structures
|
||||
) = 0;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Initializes the shader, this needs to be called before the shader can
|
||||
* be used.
|
||||
*/
|
||||
void init() override {
|
||||
// Determine which kind of OpenGL shader to use.
|
||||
variant = ShaderOpenGLVariant::GLSL_330_CORE;
|
||||
|
||||
// Now get the stages
|
||||
T dummy;
|
||||
this->getStages(
|
||||
variant,
|
||||
&dummy,
|
||||
stages,
|
||||
parameters,
|
||||
structures
|
||||
);
|
||||
|
||||
// Create the shader program
|
||||
shaderProgram = glCreateProgram();
|
||||
assertNoGLError();
|
||||
|
||||
// Attach all the stages
|
||||
for(auto stage : stages) {
|
||||
glAttachShader(shaderProgram, stage->id);
|
||||
assertNoGLError();
|
||||
}
|
||||
|
||||
// Link and verify the program
|
||||
glLinkProgram(shaderProgram);
|
||||
assertNoGLError();
|
||||
|
||||
GLint status;
|
||||
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &status);
|
||||
assertNoGLError();
|
||||
assertTrue(status == GL_TRUE, "Failed to link shader program.");
|
||||
|
||||
// Map parameters correctly.
|
||||
std::for_each(
|
||||
parameters.begin(),
|
||||
parameters.end(),
|
||||
[&](struct ShaderParameter ¶m) {
|
||||
// Correct offset
|
||||
param.offset = param.offset - (size_t)(&dummy);
|
||||
param.location = glGetUniformLocation(
|
||||
shaderProgram,
|
||||
param.name.c_str()
|
||||
);
|
||||
assertNoGLError();
|
||||
assertTrue(
|
||||
param.location != -1,
|
||||
"Failed to get location for parameter %s.",
|
||||
param.name.c_str()
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// Map structures
|
||||
std::for_each(
|
||||
structures.begin(),
|
||||
structures.end(),
|
||||
[&](struct IShaderStructure &structure) {
|
||||
structure.offset = structure.offset - (size_t)(&dummy);
|
||||
structure.location = glGetUniformBlockIndex(
|
||||
shaderProgram,
|
||||
structure.structureName.c_str()
|
||||
);
|
||||
assertNoGLError();
|
||||
assertTrue(
|
||||
structure.location != -1,
|
||||
"Failed to get location for structure %s.",
|
||||
structure.structureName.c_str()
|
||||
);
|
||||
|
||||
// Create the buffer
|
||||
glGenBuffers(1, &structure.buffer);
|
||||
}
|
||||
);
|
||||
|
||||
this->bind();
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds the shader as the current one, does not upload any data, somewhat
|
||||
* relies on something else uploading the data.
|
||||
*/
|
||||
void bind() override {
|
||||
glUseProgram(shaderProgram);
|
||||
assertNoGLError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploads the data to the GPU.
|
||||
*/
|
||||
void upload() override {
|
||||
switch(this->variant) {
|
||||
case ShaderOpenGLVariant::GLSL_330_CORE:
|
||||
for(auto param : parameters) {
|
||||
void *value = (void*)(
|
||||
((size_t)&this->data) + param.offset
|
||||
);
|
||||
|
||||
switch(param.type) {
|
||||
case ShaderParameterType::MAT4: {
|
||||
glm::mat4 *matrix = (glm::mat4 *)value;
|
||||
if(param.count != 1) {
|
||||
assertUnreachable("I haven't implemented multiple mat4s");
|
||||
}
|
||||
glUniformMatrix4fv(
|
||||
param.location, 1, GL_FALSE, glm::value_ptr(*matrix)
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShaderParameterType::COLOR: {
|
||||
auto color = (Color *)value;
|
||||
glUniform4fv(
|
||||
param.location,
|
||||
param.count,
|
||||
(GLfloat*)value
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShaderParameterType::BOOLEAN: {
|
||||
glUniform1iv(param.location, param.count, (GLint*)value);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShaderParameterType::TEXTURE: {
|
||||
glUniform1iv(param.location, param.count, (GLint*)value);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
assertUnreachable("Unsupported ShaderParameterType");
|
||||
}
|
||||
}
|
||||
|
||||
assertNoGLError();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unsupported ShaderOpenGLVariant");
|
||||
}
|
||||
|
||||
// Upload structures
|
||||
for(auto structure : structures) {
|
||||
switch(structure.structureType) {
|
||||
case ShaderOpenGLStructureType::STD140: {
|
||||
// Upload the data
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, structure.buffer);
|
||||
assertNoGLError();
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, structure.location, structure.buffer);
|
||||
assertNoGLError();
|
||||
glBufferData(
|
||||
GL_UNIFORM_BUFFER,
|
||||
structure.size * structure.count,
|
||||
(void*)((size_t)&this->data + (size_t)structure.offset),
|
||||
GL_STATIC_DRAW
|
||||
);
|
||||
assertNoGLError();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assertUnreachable("Unsupported ShaderOpenGLStructureType");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~Shader() {
|
||||
// Delete the structures
|
||||
for(auto structure : structures) {
|
||||
assertTrue(structure.buffer != -1, "Invalid buffer.");
|
||||
glDeleteBuffers(1, &structure.buffer);
|
||||
assertNoGLError();
|
||||
}
|
||||
|
||||
// Delete the shader program
|
||||
glDeleteProgram(shaderProgram);
|
||||
assertNoGLError();
|
||||
}
|
||||
};
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "ShaderParameter.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
ShaderParameter::ShaderParameter(
|
||||
const std::string &name,
|
||||
const void *offset,
|
||||
const enum ShaderParameterType type,
|
||||
const size_t count
|
||||
) {
|
||||
this->name = name;
|
||||
this->offset = (size_t)offset;
|
||||
this->type = type;
|
||||
this->count = count;
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/shader/IShader.hpp"
|
||||
#include "dawnopengl.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
struct ShaderParameter {
|
||||
std::string name;
|
||||
size_t offset;
|
||||
enum ShaderParameterType type;
|
||||
size_t count;
|
||||
GLint location = -1;
|
||||
|
||||
/**
|
||||
* Construct a new shader parameter.
|
||||
*
|
||||
* @param name Name of the parameter within the shader.
|
||||
* @param offset Offset, relative to the structure of the data.
|
||||
* @param type Type of the parameter.
|
||||
* @param count How many elements in the array (if multiple).
|
||||
*/
|
||||
ShaderParameter(
|
||||
const std::string &name,
|
||||
const void *offset,
|
||||
const enum ShaderParameterType type,
|
||||
const size_t count = 1
|
||||
);
|
||||
};
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "assert/assertgl.hpp"
|
||||
#include "assert/assert.hpp"
|
||||
#include "ShaderStage.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
ShaderStage::ShaderStage(
|
||||
const enum ShaderStageType type,
|
||||
const std::string source
|
||||
) : IShaderStage(type) {
|
||||
// Get OpenGL Shader Type
|
||||
GLenum shaderType;
|
||||
switch(this->type) {
|
||||
case ShaderStageType::VERTEX:
|
||||
shaderType = GL_VERTEX_SHADER;
|
||||
break;
|
||||
|
||||
case ShaderStageType::FRAGMENT:
|
||||
shaderType = GL_FRAGMENT_SHADER;
|
||||
break;
|
||||
|
||||
// case ShaderStageType::COMPUTE:
|
||||
// shaderType = GL_COMPUTE;
|
||||
// break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unknown ShaderStageType");
|
||||
}
|
||||
|
||||
// Initialize the shader
|
||||
this->id = glCreateShader(shaderType);
|
||||
assertNoGLError();
|
||||
|
||||
// Compile the shader
|
||||
auto cSource = source.c_str();
|
||||
glShaderSource(this->id, 1, &cSource, NULL);
|
||||
assertNoGLError();
|
||||
glCompileShader(this->id);
|
||||
assertNoGLError();
|
||||
|
||||
// Validate
|
||||
GLint status;
|
||||
glGetShaderiv(this->id, GL_COMPILE_STATUS, &status);
|
||||
assertNoGLError();
|
||||
|
||||
if(!status) {
|
||||
// Failed to compile
|
||||
GLint logLength;
|
||||
glGetShaderiv(this->id, GL_INFO_LOG_LENGTH, &logLength);
|
||||
assertNoGLError();
|
||||
|
||||
GLchar *log = new GLchar[logLength];
|
||||
glGetShaderInfoLog(this->id, logLength, NULL, log);
|
||||
assertNoGLError();
|
||||
assertUnreachable("Failed to compile shader stage %i:\n%s", type, log);
|
||||
}
|
||||
}
|
||||
|
||||
ShaderStage::~ShaderStage() {
|
||||
if(this->id != -1) {
|
||||
glDeleteShader(this->id);
|
||||
assertNoGLError();
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnopengl.hpp"
|
||||
#include "display/shader/IShaderStage.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class ShaderStage : public IShaderStage {
|
||||
public:
|
||||
GLuint id = -1;
|
||||
|
||||
/**
|
||||
* Constructs a new ShaderStage.
|
||||
*
|
||||
* @param type The type of shader this is.
|
||||
* @param source The source code to compile.
|
||||
*/
|
||||
ShaderStage(const enum ShaderStageType type, const std::string source);
|
||||
|
||||
/**
|
||||
* Disposes of the shader stage.
|
||||
*/
|
||||
~ShaderStage();
|
||||
};
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma ocne
|
||||
#include "display/shader/ShaderParameter.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
enum class ShaderOpenGLStructureType {
|
||||
STD140
|
||||
};
|
||||
|
||||
struct IShaderStructure {
|
||||
std::string structureName;
|
||||
size_t offset;
|
||||
enum ShaderOpenGLStructureType structureType;
|
||||
size_t size;
|
||||
size_t count;
|
||||
std::vector<struct ShaderParameter> parameters;
|
||||
GLint location = -1;
|
||||
GLuint buffer = -1;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ShaderStructure final : public IShaderStructure {
|
||||
public:
|
||||
/**
|
||||
* Constructs a new shader structure. Shader structures allow for larger
|
||||
* amounts/volumes of data to be passed to the shader in a single call.
|
||||
* Ideally I wouldn't really need this as I wanted the entire shader to
|
||||
* basically be a single large structure, but OpenGL doesn't support that
|
||||
* so I have to do this instead.
|
||||
*
|
||||
* @param structureName Structure name within the shader.
|
||||
* @param offset Offset, within the data structure, that this structure
|
||||
* starts at.
|
||||
* @param structureType The type of structure data format to use.
|
||||
* @param getParameters A callback that, when invoked, will populate the
|
||||
* parameters vector with the parameters for this
|
||||
* structure.
|
||||
*/
|
||||
ShaderStructure(
|
||||
const std::string &structureName,
|
||||
const void *offset,
|
||||
const enum ShaderOpenGLStructureType structureType,
|
||||
std::function<
|
||||
void(const T&, std::vector<struct ShaderParameter>&)
|
||||
> getParameters,
|
||||
size_t count = 1
|
||||
) {
|
||||
this->structureName = structureName;
|
||||
this->offset = (size_t)offset;
|
||||
this->structureType = structureType;
|
||||
this->size = sizeof(T);
|
||||
this->count = count;
|
||||
this->parameters = std::vector<struct ShaderParameter>();
|
||||
|
||||
T dummy;
|
||||
getParameters(dummy, this->parameters);
|
||||
|
||||
// Update offsets.
|
||||
auto itParams = this->parameters.begin();
|
||||
while(itParams != this->parameters.end()) {
|
||||
struct ShaderParameter ¶m = *itParams;
|
||||
param.offset -= (size_t)(&dummy);
|
||||
|
||||
// Check for non-aligned OpenGL structures.
|
||||
if(param.offset % sizeof(glm::vec4) != 0) {
|
||||
assertUnreachable(
|
||||
"%s%s%s",
|
||||
"Non-aligned OpenGL structure detected on param ",
|
||||
param.name.c_str(),
|
||||
"!\nEnsure you have padded correctly."
|
||||
);
|
||||
}
|
||||
|
||||
if(
|
||||
itParams == (this->parameters.end() - 1) &&
|
||||
count > 1 &&
|
||||
(sizeof(T) % sizeof(glm::vec4)) != 0
|
||||
) {
|
||||
assertUnreachable(
|
||||
"%s%s%s",
|
||||
"Non-aligned OpenGL structure detected on last element in array structure on param ",
|
||||
param.name.c_str(),
|
||||
"!\nEnsure you have padded correctly."
|
||||
);
|
||||
}
|
||||
|
||||
++itParams;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "display/shader/SimpleTexturedShader.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void SimpleTexturedShader::getStages(
|
||||
const enum ShaderOpenGLVariant variant,
|
||||
const struct SimpleTexturedShaderData *rel,
|
||||
std::vector<std::shared_ptr<ShaderStage>> &stages,
|
||||
std::vector<struct ShaderParameter> ¶meters,
|
||||
std::vector<struct IShaderStructure> &structures
|
||||
) {
|
||||
// Stages
|
||||
std::shared_ptr<ShaderStage> vertex;
|
||||
std::shared_ptr<ShaderStage> fragment;
|
||||
|
||||
switch(variant) {
|
||||
case ShaderOpenGLVariant::GLSL_330_CORE:
|
||||
vertex = std::make_shared<ShaderStage>(
|
||||
ShaderStageType::VERTEX,
|
||||
"#version 330 core\n"
|
||||
"layout (location = 0) in vec3 aPos;\n"
|
||||
"layout (location = 1) in vec2 aTexCoord;\n"
|
||||
"uniform mat4 u_Projection;\n"
|
||||
"uniform mat4 u_View;\n"
|
||||
"uniform mat4 u_Model;\n"
|
||||
"out vec2 o_TextCoord;\n"
|
||||
"void main() {\n"
|
||||
"gl_Position = u_Projection * u_View * u_Model * vec4(aPos, 1.0);\n"
|
||||
"o_TextCoord = vec2(aTexCoord.x, aTexCoord.y);\n"
|
||||
"}"
|
||||
);
|
||||
|
||||
fragment = std::make_shared<ShaderStage>(
|
||||
ShaderStageType::FRAGMENT,
|
||||
"#version 330 core\n"
|
||||
"in vec2 o_TextCoord;\n"
|
||||
"out vec4 o_Color;\n"
|
||||
"uniform vec4 u_Color;\n"
|
||||
"uniform bool u_HasTexture;\n"
|
||||
"uniform sampler2D u_Texture;\n"
|
||||
"void main() {\n"
|
||||
"if(u_HasTexture) {\n"
|
||||
"o_Color = texture(u_Texture, o_TextCoord) * u_Color;\n"
|
||||
"} else {\n"
|
||||
"o_Color = u_Color;"
|
||||
"}\n"
|
||||
"}\n"
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unsupported ShaderOpenGLVariant");
|
||||
}
|
||||
|
||||
// Add stages
|
||||
stages.push_back(vertex);
|
||||
stages.push_back(fragment);
|
||||
|
||||
// Parameters
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_Projection",
|
||||
&rel->projection,
|
||||
ShaderParameterType::MAT4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_View",
|
||||
&rel->view,
|
||||
ShaderParameterType::MAT4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_Model",
|
||||
&rel->model,
|
||||
ShaderParameterType::MAT4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_Color",
|
||||
&rel->color,
|
||||
ShaderParameterType::COLOR
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_HasTexture",
|
||||
&rel->hasTexture,
|
||||
ShaderParameterType::BOOLEAN
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_Texture",
|
||||
&rel->texture,
|
||||
ShaderParameterType::TEXTURE
|
||||
));
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
// 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 {
|
||||
struct SimpleTexturedShaderData {
|
||||
glm::mat4 projection;
|
||||
glm::mat4 view;
|
||||
glm::mat4 model;
|
||||
struct Color color = COLOR_WHITE;
|
||||
bool hasTexture = false;
|
||||
shadertexturebinding_t texture = 0;
|
||||
};
|
||||
|
||||
class SimpleTexturedShader : public Shader<SimpleTexturedShaderData> {
|
||||
protected:
|
||||
void getStages(
|
||||
const enum ShaderOpenGLVariant variant,
|
||||
const struct SimpleTexturedShaderData *rel,
|
||||
std::vector<std::shared_ptr<ShaderStage>> &stages,
|
||||
std::vector<struct ShaderParameter> ¶meters,
|
||||
std::vector<struct IShaderStructure> &structures
|
||||
) override;
|
||||
};
|
||||
}
|
@ -1,194 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "display/shader/UIShader.hpp"
|
||||
#include "util/Macro.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void UIShader::getStages(
|
||||
const enum ShaderOpenGLVariant variant,
|
||||
const struct UIShaderData *rel,
|
||||
std::vector<std::shared_ptr<ShaderStage>> &stages,
|
||||
std::vector<struct ShaderParameter> ¶meters,
|
||||
std::vector<struct IShaderStructure> &structures
|
||||
) {
|
||||
// Stages
|
||||
std::shared_ptr<ShaderStage> vertex;
|
||||
std::shared_ptr<ShaderStage> fragment;
|
||||
|
||||
switch(variant) {
|
||||
case ShaderOpenGLVariant::GLSL_330_CORE:
|
||||
vertex = std::make_shared<ShaderStage>(
|
||||
ShaderStageType::VERTEX,
|
||||
"#version 330 core\n"
|
||||
"layout (location = 0) in vec3 aPos;\n"
|
||||
"layout (location = 1) in vec2 aTexCoord;\n"
|
||||
"uniform mat4 u_Projection;\n"
|
||||
"uniform mat4 u_View;\n"
|
||||
"uniform mat4 u_Model;\n"
|
||||
"struct UIShaderQuad {\n"
|
||||
"vec4 quad;\n"
|
||||
"vec4 uv;\n"
|
||||
"vec4 color;\n"
|
||||
"vec4 style;\n"
|
||||
"};\n"
|
||||
"layout (std140) uniform ub_Quad {\n"
|
||||
"UIShaderQuad quads[" MACRO_STRINGIFY(UI_SHADER_QUAD_COUNT) "];\n"
|
||||
"};\n"
|
||||
"out vec2 v_TextCoord;\n"
|
||||
"out vec4 v_Color;\n"
|
||||
"out vec4 v_Style;\n"
|
||||
"void main() {\n"
|
||||
"vec4 pos;\n"
|
||||
"vec2 coord;\n"
|
||||
"int index = int(aPos.z);\n"
|
||||
"int quadIndex = index / 4;\n"
|
||||
"int vertexIndex = index % 4;\n"
|
||||
"UIShaderQuad quad = quads[quadIndex];\n"
|
||||
"if(vertexIndex == 0) {\n"
|
||||
"pos.x = quad.quad.x;\n"
|
||||
"pos.y = quad.quad.y;\n"
|
||||
"coord.x = quad.uv.x;\n"
|
||||
"coord.y = quad.uv.y;\n"
|
||||
"} else if(vertexIndex == 1) {\n"
|
||||
"pos.x = quad.quad.z;\n"
|
||||
"pos.y = quad.quad.y;\n"
|
||||
"coord.x = quad.uv.z;\n"
|
||||
"coord.y = quad.uv.y;\n"
|
||||
"} else if(vertexIndex == 2) {\n"
|
||||
"pos.y = quad.quad.w;\n"
|
||||
"pos.x = quad.quad.x;\n"
|
||||
"coord.x = quad.uv.x;\n"
|
||||
"coord.y = quad.uv.w;\n"
|
||||
"} else if(vertexIndex == 3) {\n"
|
||||
"pos.x = quad.quad.z;\n"
|
||||
"pos.y = quad.quad.w;\n"
|
||||
"coord.x = quad.uv.z;\n"
|
||||
"coord.y = quad.uv.w;\n"
|
||||
"}\n"
|
||||
"pos.z = 0;\n"
|
||||
"pos.w = 1;\n"
|
||||
"gl_Position = u_Projection * u_View * u_Model * pos;\n"
|
||||
"v_TextCoord = coord;\n"
|
||||
"v_Color = quad.color;\n"
|
||||
"v_Style = quad.style;\n"
|
||||
"}"
|
||||
);
|
||||
|
||||
fragment = std::make_shared<ShaderStage>(
|
||||
ShaderStageType::FRAGMENT,
|
||||
"#version 330 core\n"
|
||||
"in vec2 v_TextCoord;\n"
|
||||
"in vec4 v_Color;\n"
|
||||
"in vec4 v_Style;\n"
|
||||
"uniform sampler2D u_Texture[" MACRO_STRINGIFY(UI_SHADER_TEXTURE_COUNT) "];\n"
|
||||
"out vec4 o_Color;\n"
|
||||
"void main() {\n"
|
||||
"vec4 texColor = vec4(1, 1, 1, 1);\n"
|
||||
"int vStyle = int(round(v_Style[0]));\n"
|
||||
"int vTextInd = int(round(v_Style[1]));\n"
|
||||
"switch(vTextInd) {\n"
|
||||
"case -1:\n"
|
||||
"texColor = vec4(1, 1, 1, 1);\n"
|
||||
"break;\n"
|
||||
"case 0:\n"
|
||||
"texColor = texture(u_Texture[0], v_TextCoord);\n"
|
||||
"break;\n"
|
||||
"case 1:\n"
|
||||
"texColor = texture(u_Texture[1], v_TextCoord);\n"
|
||||
"break;\n"
|
||||
"case 2:\n"
|
||||
"texColor = texture(u_Texture[2], v_TextCoord);\n"
|
||||
"break;\n"
|
||||
"case 3:\n"
|
||||
"texColor = texture(u_Texture[3], v_TextCoord);\n"
|
||||
"break;\n"
|
||||
"case 4:\n"
|
||||
"texColor = texture(u_Texture[4], v_TextCoord);\n"
|
||||
"break;\n"
|
||||
"case 5:\n"
|
||||
"texColor = texture(u_Texture[5], v_TextCoord);\n"
|
||||
"break;\n"
|
||||
"}\n"
|
||||
"switch(vStyle) {\n"
|
||||
"case 0:\n"
|
||||
"o_Color = texColor * v_Color;\n"
|
||||
"break;\n"
|
||||
"case 1:\n"
|
||||
"o_Color.rgb = v_Color.rgb;\n"
|
||||
"o_Color.a = texColor.r * v_Color.a;\n"
|
||||
"break;\n"
|
||||
"}\n"
|
||||
"}\n"
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unsupported ShaderOpenGLVariant");
|
||||
}
|
||||
|
||||
// Add stages
|
||||
stages.push_back(vertex);
|
||||
stages.push_back(fragment);
|
||||
|
||||
// Parameters
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_Projection",
|
||||
&rel->projection,
|
||||
ShaderParameterType::MAT4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_View",
|
||||
&rel->view,
|
||||
ShaderParameterType::MAT4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_Model",
|
||||
&rel->model,
|
||||
ShaderParameterType::MAT4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_Texture",
|
||||
&rel->textures,
|
||||
ShaderParameterType::TEXTURE,
|
||||
UI_SHADER_TEXTURE_COUNT
|
||||
));
|
||||
|
||||
structures.push_back(ShaderStructure<struct UIShaderQuad>(
|
||||
"ub_Quad",
|
||||
&rel->quads,
|
||||
ShaderOpenGLStructureType::STD140,
|
||||
[&](const struct UIShaderQuad &rel, std::vector<struct ShaderParameter> ¶meters) {
|
||||
parameters.push_back(ShaderParameter(
|
||||
"quad",
|
||||
&rel.quad,
|
||||
ShaderParameterType::VEC4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"uv",
|
||||
&rel.uv,
|
||||
ShaderParameterType::VEC4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"color",
|
||||
&rel.color,
|
||||
ShaderParameterType::COLOR
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"style",
|
||||
&rel.style,
|
||||
ShaderParameterType::VEC4
|
||||
));
|
||||
},
|
||||
UI_SHADER_QUAD_COUNT
|
||||
));
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
// 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 {
|
||||
#define UI_SHADER_QUAD_COUNT 1024
|
||||
#define UI_SHADER_TEXTURE_COUNT 16
|
||||
|
||||
enum class UIShaderQuadStyle {
|
||||
TEXTURED = 0,
|
||||
FONT = 1
|
||||
};
|
||||
|
||||
struct UIShaderQuad {
|
||||
glm::vec4 quad;
|
||||
glm::vec4 uv;
|
||||
struct Color color;
|
||||
glm::vec4 style;
|
||||
};
|
||||
|
||||
struct UIShaderData {
|
||||
glm::mat4 projection;
|
||||
glm::mat4 view;
|
||||
glm::mat4 model;
|
||||
shadertexturebinding_t textures[UI_SHADER_TEXTURE_COUNT];
|
||||
struct UIShaderQuad quads[UI_SHADER_QUAD_COUNT];
|
||||
};
|
||||
|
||||
class UIShader : public Shader<UIShaderData> {
|
||||
protected:
|
||||
void getStages(
|
||||
const enum ShaderOpenGLVariant variant,
|
||||
const struct UIShaderData *rel,
|
||||
std::vector<std::shared_ptr<ShaderStage>> &stages,
|
||||
std::vector<struct ShaderParameter> ¶meters,
|
||||
std::vector<struct IShaderStructure> &structures
|
||||
) override;
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user