First render.
This commit is contained in:
@ -43,17 +43,15 @@ void BackBufferRenderTarget::setClearColor(const struct Color color) {
|
||||
this->clearColor = color;
|
||||
}
|
||||
|
||||
void BackBufferRenderTarget::clear(
|
||||
const enum RenderTargetClearFlag clearFlags
|
||||
) {
|
||||
void BackBufferRenderTarget::clear(const int32_t clearFlags) {
|
||||
glClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a);
|
||||
assertNoGLError();
|
||||
|
||||
GLbitfield mask = 0;
|
||||
if(Flag::isOn(clearFlags, RenderTargetClearFlag::COLOR)) {
|
||||
if(Flag::isOn(clearFlags, RENDER_TARGET_CLEAR_COLOR)) {
|
||||
mask |= GL_COLOR_BUFFER_BIT;
|
||||
}
|
||||
if(Flag::isOn(clearFlags, RenderTargetClearFlag::DEPTH)) {
|
||||
if(Flag::isOn(clearFlags, RENDER_TARGET_CLEAR_DEPTH)) {
|
||||
mask |= GL_DEPTH_BUFFER_BIT;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ namespace Dawn {
|
||||
float_t getWidth() override;
|
||||
float_t getHeight() override;
|
||||
void setClearColor(const struct Color color) override;
|
||||
void clear(const enum RenderTargetClearFlag) override;
|
||||
void clear(const int32_t) override;
|
||||
void bind() override;
|
||||
|
||||
/**
|
||||
|
@ -8,4 +8,5 @@ target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
Shader.cpp
|
||||
ShaderStage.cpp
|
||||
SimpleTexturedShader.cpp
|
||||
)
|
@ -3,4 +3,6 @@
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "Shader.hpp"
|
||||
#include "Shader.hpp"
|
||||
|
||||
using namespace Dawn;
|
@ -4,13 +4,168 @@
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/ShaderStage.hpp"
|
||||
#include "display/IShader.hpp"
|
||||
#include "display/shader/ShaderStage.hpp"
|
||||
#include "display/shader/IShader.hpp"
|
||||
#include "assert/assert.hpp"
|
||||
#include "assert/assertgl.hpp"
|
||||
#include "display/Color.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
template<struct T>
|
||||
enum ShaderOpenGLVariant {
|
||||
GLSL_330_CORE
|
||||
};
|
||||
|
||||
struct ShaderOpenGLParameter {
|
||||
std::string name;
|
||||
size_t offset;
|
||||
enum ShaderParameterType type;
|
||||
|
||||
GLint location = -1;
|
||||
|
||||
ShaderOpenGLParameter(
|
||||
const std::string &name,
|
||||
const void *offset,
|
||||
const enum ShaderParameterType type
|
||||
) {
|
||||
this->name = name;
|
||||
this->offset = (size_t)offset;
|
||||
this->type = type;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class Shader : public IShader<T> {
|
||||
private:
|
||||
std::vector<std::shared_ptr<ShaderStage>> stages;
|
||||
std::vector<struct ShaderOpenGLParameter> parameters;
|
||||
enum ShaderOpenGLVariant variant;
|
||||
|
||||
GLuint shaderProgram = -1;
|
||||
|
||||
protected:
|
||||
virtual void getStages(
|
||||
const enum ShaderOpenGLVariant variant,
|
||||
const T *rel,
|
||||
std::vector<std::shared_ptr<ShaderStage>> &stages,
|
||||
std::vector<struct ShaderOpenGLParameter> ¶meters
|
||||
) = 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 = GLSL_330_CORE;
|
||||
|
||||
// Now get the stages
|
||||
T dummy;
|
||||
this->getStages(
|
||||
variant,
|
||||
&dummy,
|
||||
stages,
|
||||
parameters
|
||||
);
|
||||
|
||||
// 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 ShaderOpenGLParameter ¶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()
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
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;
|
||||
glUniformMatrix4fv(
|
||||
param.location, 1, GL_FALSE, glm::value_ptr(*matrix)
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShaderParameterType::COLOR: {
|
||||
auto color = (Color *)value;
|
||||
glUniform4f(
|
||||
param.location,
|
||||
color->r,
|
||||
color->g,
|
||||
color->b,
|
||||
color->a
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
assertUnreachable("Unsupported ShaderParameterType");
|
||||
}
|
||||
}
|
||||
|
||||
assertNoGLError();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unsupported ShaderOpenGLVariant");
|
||||
}
|
||||
}
|
||||
|
||||
~Shader() {
|
||||
}
|
||||
};
|
||||
}
|
@ -3,15 +3,67 @@
|
||||
// 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 ShaderType type) : type(type) {
|
||||
}
|
||||
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;
|
||||
|
||||
void ShaderStage::compile(const std::string source) {
|
||||
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:\n%s", log);
|
||||
}
|
||||
}
|
||||
|
||||
ShaderStage::~ShaderStage() {
|
||||
if(this->id != -1) {
|
||||
glDeleteShader(this->id);
|
||||
assertNoGLError();
|
||||
}
|
||||
}
|
@ -5,32 +5,24 @@
|
||||
|
||||
#pragma once
|
||||
#include "dawnopengl.hpp"
|
||||
#include "dawnlibs.hpp"
|
||||
#include "display/shader/IShaderStage.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class ShaderStage {
|
||||
class ShaderStage : public IShaderStage {
|
||||
public:
|
||||
GLuint id = -1;
|
||||
const enum ShaderType type;
|
||||
|
||||
/**
|
||||
* Constructs a new ShaderStage.
|
||||
*
|
||||
* @param type The type of shader this is.
|
||||
*/
|
||||
ShaderStage(const enum ShaderType type);
|
||||
|
||||
/**
|
||||
* Compiles the shader stage.
|
||||
*
|
||||
* @param source The source code to compile.
|
||||
*/
|
||||
void compile(const std::string source);
|
||||
ShaderStage(const enum ShaderStageType type, const std::string source);
|
||||
|
||||
/**
|
||||
* Disposes of the shader stage.
|
||||
*/
|
||||
virtual ~ShaderStage();
|
||||
~ShaderStage();
|
||||
};
|
||||
}
|
78
src/dawnopengl/display/shader/SimpleTexturedShader.cpp
Normal file
78
src/dawnopengl/display/shader/SimpleTexturedShader.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
// 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 ShaderOpenGLParameter> ¶meters
|
||||
) {
|
||||
// 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"
|
||||
"uniform mat4 u_Projection;\n"
|
||||
"uniform mat4 u_View;\n"
|
||||
"uniform mat4 u_Model;\n"
|
||||
"void main() {\n"
|
||||
"gl_Position = u_Projection * u_View * u_Model * vec4(aPos, 1.0);\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"
|
||||
"void main() {\n"
|
||||
"o_Color = u_Color;"
|
||||
"}\n"
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unsupported ShaderOpenGLVariant");
|
||||
}
|
||||
|
||||
// Add stages
|
||||
stages.push_back(vertex);
|
||||
stages.push_back(fragment);
|
||||
|
||||
// Parameters
|
||||
parameters.push_back(ShaderOpenGLParameter(
|
||||
"u_Projection",
|
||||
&rel->projection,
|
||||
ShaderParameterType::MAT4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderOpenGLParameter(
|
||||
"u_View",
|
||||
&rel->view,
|
||||
ShaderParameterType::MAT4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderOpenGLParameter(
|
||||
"u_Model",
|
||||
&rel->model,
|
||||
ShaderParameterType::MAT4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderOpenGLParameter(
|
||||
"u_Color",
|
||||
&rel->color,
|
||||
ShaderParameterType::COLOR
|
||||
));
|
||||
}
|
26
src/dawnopengl/display/shader/SimpleTexturedShader.hpp
Normal file
26
src/dawnopengl/display/shader/SimpleTexturedShader.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
// 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;
|
||||
};
|
||||
|
||||
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 ShaderOpenGLParameter> ¶meters
|
||||
) override;
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user