Stripped back old shader code for now.
This commit is contained in:
@ -6,10 +6,6 @@
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
Shader.cpp
|
||||
ShaderProgram.cpp
|
||||
ShaderStage.cpp
|
||||
SimpleTexturedShader.cpp
|
||||
UIShader.cpp
|
||||
ShaderParameter.cpp
|
||||
ShaderProgram2.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,259 +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.");
|
||||
|
||||
std::vector<std::string> uniformNames;
|
||||
GLint numUniforms = 0;
|
||||
|
||||
// Get the number of active uniforms
|
||||
glGetProgramiv(shaderProgram, GL_ACTIVE_UNIFORMS, &numUniforms);
|
||||
assertNoGLError();
|
||||
|
||||
// Iterate through each uniform
|
||||
// for (GLint i = 0; i < numUniforms; ++i) {
|
||||
// char name[256];
|
||||
// GLsizei length;
|
||||
// GLint size;
|
||||
// GLenum type;
|
||||
|
||||
// // Get the uniform name
|
||||
// glGetActiveUniform(shaderProgram, i, sizeof(name), &length, &size, &type, name);
|
||||
// assertNoGLError();
|
||||
// std::cout << "Uniform: " << i << ":" << name << std::endl;
|
||||
// // uniformNames.push_back(std::string(name));
|
||||
// }
|
||||
|
||||
// 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
|
||||
);
|
||||
};
|
||||
}
|
17
src/dawnopengl/display/shader/ShaderProgram.cpp
Normal file
17
src/dawnopengl/display/shader/ShaderProgram.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "ShaderProgram.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void ShaderProgram::init(
|
||||
const std::vector<std::shared_ptr<ShaderStage>> &stages
|
||||
) {
|
||||
IShaderProgram::init(stages);
|
||||
}
|
||||
|
||||
ShaderProgram::~ShaderProgram() {
|
||||
}
|
17
src/dawnopengl/display/shader/ShaderProgram.hpp
Normal file
17
src/dawnopengl/display/shader/ShaderProgram.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/shader/IShaderProgram.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class ShaderProgram : public IShaderProgram {
|
||||
public:
|
||||
void init(
|
||||
const std::vector<std::shared_ptr<ShaderStage>> &stages
|
||||
) override;
|
||||
~ShaderProgram();
|
||||
};
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "ShaderProgram2.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void ShaderEntry::init(
|
||||
const SlangStage &stage,
|
||||
const std::string &code
|
||||
) {
|
||||
}
|
||||
|
||||
ShaderEntry::~ShaderEntry() {
|
||||
}
|
||||
|
||||
// // //
|
||||
|
||||
void ShaderProgram2::init(
|
||||
const std::vector<std::shared_ptr<ShaderEntry>> &entries
|
||||
) {
|
||||
IShaderProgram2::init(entries);
|
||||
}
|
||||
|
||||
ShaderProgram2::~ShaderProgram2() {
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/shader/IShaderProgram2.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class ShaderEntry {
|
||||
protected:
|
||||
|
||||
public:
|
||||
void init(
|
||||
const SlangStage &stage,
|
||||
const std::string &code
|
||||
);
|
||||
~ShaderEntry();
|
||||
};
|
||||
|
||||
class ShaderProgram2 : public IShaderProgram2 {
|
||||
public:
|
||||
void init(
|
||||
const std::vector<std::shared_ptr<ShaderEntry>> &entries
|
||||
) override;
|
||||
~ShaderProgram2();
|
||||
};
|
||||
}
|
@ -1,74 +1,17 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
// Copyright (c) 2024 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();
|
||||
|
||||
// glShaderBinary(1, &this->id, GL_SHADER_BINARY_FORMAT_SPIR_V, source.data(), source.size());
|
||||
// assertNoGLError();
|
||||
// glSpecializeShader(this->id, "main", 0, NULL, NULL);
|
||||
// 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);
|
||||
}
|
||||
void ShaderStage::init(
|
||||
const SlangStage &stage,
|
||||
const std::string &code
|
||||
) {
|
||||
}
|
||||
|
||||
ShaderStage::~ShaderStage() {
|
||||
if(this->id != -1) {
|
||||
glDeleteShader(this->id);
|
||||
assertNoGLError();
|
||||
}
|
||||
}
|
@ -1,28 +1,18 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
// Copyright (c) 2024 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.
|
||||
*/
|
||||
void init(
|
||||
const SlangStage &stage,
|
||||
const std::string &code
|
||||
) override;
|
||||
~ShaderStage();
|
||||
};
|
||||
}
|
@ -1,96 +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.
|
||||
* @param count The number of structures to create.
|
||||
*/
|
||||
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,230 +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"
|
||||
|
||||
#include <fstream>
|
||||
#include "slang.h"
|
||||
#include "slang-gfx.h"
|
||||
using namespace slang;
|
||||
|
||||
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;
|
||||
|
||||
std::string shader = R"(
|
||||
cbuffer Uniforms {
|
||||
float4x4 u_Projection;
|
||||
float4x4 u_View;
|
||||
float4x4 u_Model;
|
||||
float4 u_Color;
|
||||
bool u_HasTexture;
|
||||
uniform Sampler2D u_Texture;
|
||||
};
|
||||
|
||||
struct AssembledVertex {
|
||||
float3 position : POSITION;
|
||||
float2 texcoord : TEXCOORD;
|
||||
};
|
||||
|
||||
struct Fragment {
|
||||
float4 color;
|
||||
};
|
||||
|
||||
struct VertexStageOutput {
|
||||
float2 uv : UV;
|
||||
float4 sv_position : SV_Position;
|
||||
};
|
||||
|
||||
[shader("vertex")]
|
||||
VertexStageOutput vertexMain(
|
||||
AssembledVertex assembledVertex
|
||||
) {
|
||||
VertexStageOutput output;
|
||||
|
||||
float3 position = assembledVertex.position;
|
||||
|
||||
output.uv = assembledVertex.texcoord;
|
||||
|
||||
output.sv_position = mul(
|
||||
float4(position, 1.0),
|
||||
mul(u_Model, mul(u_View, u_Projection))
|
||||
);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
[shader("fragment")]
|
||||
Fragment fragmentMain(
|
||||
float2 uv: UV
|
||||
) : SV_Target {
|
||||
Fragment output;
|
||||
if(u_HasTexture) {
|
||||
output.color = u_Texture.Sample(uv) * u_Color;
|
||||
} else {
|
||||
output.color = u_Color;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
)";
|
||||
Slang::ComPtr<IGlobalSession> globalSession;
|
||||
createGlobalSession(globalSession.writeRef());
|
||||
|
||||
SessionDesc sessionDesc;
|
||||
|
||||
TargetDesc targetDesc;
|
||||
targetDesc.format = SLANG_GLSL;
|
||||
targetDesc.profile = globalSession->findProfile("glsl_330");
|
||||
sessionDesc.targets = &targetDesc;
|
||||
sessionDesc.targetCount = 1;
|
||||
|
||||
Slang::ComPtr<IBlob> diagnostics;
|
||||
const char* searchPaths[] = { "/home/yourwishes/htdocs/Dawn/assets/shaders/" };
|
||||
sessionDesc.searchPaths = searchPaths;
|
||||
sessionDesc.searchPathCount = 1;
|
||||
|
||||
Slang::ComPtr<ISession> session;
|
||||
globalSession->createSession(sessionDesc, session.writeRef());
|
||||
auto module = session->loadModuleFromSourceString(
|
||||
"hello-world.slang",
|
||||
"hello-world.slang",
|
||||
shader.c_str(),
|
||||
diagnostics.writeRef()
|
||||
);
|
||||
if(diagnostics) {
|
||||
assertUnreachable("Failed to load module %s", (const char*) diagnostics->getBufferPointer());
|
||||
return;
|
||||
}
|
||||
|
||||
Slang::ComPtr<IEntryPoint> vertexEntryPoint;
|
||||
Slang::ComPtr<IEntryPoint> fragEntryPoint;
|
||||
module->findEntryPointByName("vertexMain", vertexEntryPoint.writeRef());
|
||||
module->findEntryPointByName("fragmentMain", fragEntryPoint.writeRef());
|
||||
|
||||
IComponentType* components[] = { module, vertexEntryPoint, fragEntryPoint };
|
||||
Slang::ComPtr<IComponentType> program;
|
||||
session->createCompositeComponentType(
|
||||
components,
|
||||
sizeof(components) / sizeof(components[0]),
|
||||
program.writeRef()
|
||||
);
|
||||
|
||||
Slang::ComPtr<IComponentType> linkedProgram;
|
||||
auto result = program->link(linkedProgram.writeRef(), diagnostics.writeRef());
|
||||
std::cout << "Result: " << result << std::endl;
|
||||
if(diagnostics) {
|
||||
assertUnreachable("%s\n", (const char*) diagnostics->getBufferPointer());
|
||||
return;
|
||||
}
|
||||
|
||||
int entryPointIndex = 0;
|
||||
int targetIndex = 0; // only one target
|
||||
Slang::ComPtr<IBlob> vertexBlob;
|
||||
result = linkedProgram->getEntryPointCode(
|
||||
entryPointIndex,
|
||||
targetIndex,
|
||||
vertexBlob.writeRef(),
|
||||
diagnostics.writeRef()
|
||||
);
|
||||
if(diagnostics) {
|
||||
assertUnreachable("%s\n", (const char*) diagnostics->getBufferPointer());
|
||||
return;
|
||||
}
|
||||
|
||||
slang::ProgramLayout* layout = program->getLayout();
|
||||
unsigned parameterCount = layout->getParameterCount();
|
||||
for(unsigned pp = 0; pp < parameterCount; pp++) {
|
||||
slang::VariableLayoutReflection* parameter = layout->getParameterByIndex(pp);
|
||||
std::cout << "Parameter: " << parameter->getName() << std::endl;
|
||||
|
||||
auto layout = parameter->getTypeLayout();
|
||||
auto fields = layout->getFieldCount();
|
||||
for(unsigned ff = 0; ff < fields; ff++) {
|
||||
slang::VariableLayoutReflection* field = layout->getFieldByIndex(ff);
|
||||
std::string fieldName = field->getName();
|
||||
std::cout << "Field: " << fieldName << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::string vertexString = (const char*)vertexBlob->getBufferPointer();
|
||||
|
||||
entryPointIndex = 1;
|
||||
Slang::ComPtr<IBlob> fragmentBlob;
|
||||
result = linkedProgram->getEntryPointCode(
|
||||
entryPointIndex,
|
||||
targetIndex,
|
||||
fragmentBlob.writeRef(),
|
||||
diagnostics.writeRef()
|
||||
);
|
||||
if(diagnostics) {
|
||||
assertUnreachable("%s\n", (const char*) diagnostics->getBufferPointer());
|
||||
return;
|
||||
}
|
||||
|
||||
std::string fragmentString = (const char*)fragmentBlob->getBufferPointer();
|
||||
|
||||
vertex = std::make_shared<ShaderStage>(
|
||||
ShaderStageType::VERTEX, vertexString
|
||||
);
|
||||
stages.push_back(vertex);
|
||||
|
||||
fragment = std::make_shared<ShaderStage>(
|
||||
ShaderStageType::FRAGMENT, fragmentString
|
||||
);
|
||||
stages.push_back(fragment);
|
||||
|
||||
structures.push_back(ShaderStructure<struct SimpleTexturedShaderDataSub>(
|
||||
"block_SLANG_ParameterGroup_Uniforms_std140_0",
|
||||
&rel->data,
|
||||
ShaderOpenGLStructureType::STD140,
|
||||
[](const SimpleTexturedShaderDataSub &data, std::vector<struct ShaderParameter> ¶meters) {
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_Projection_0",
|
||||
&data.projection,
|
||||
ShaderParameterType::MAT4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_View_0",
|
||||
&data.view,
|
||||
ShaderParameterType::MAT4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_Model_0",
|
||||
&data.model,
|
||||
ShaderParameterType::MAT4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_Color_0",
|
||||
&data.color,
|
||||
ShaderParameterType::COLOR
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_HasTexture_0",
|
||||
&data.hasTexture,
|
||||
ShaderParameterType::BOOLEAN
|
||||
));
|
||||
}
|
||||
));
|
||||
|
||||
// Parameters
|
||||
parameters.push_back(ShaderParameter(
|
||||
"Uniforms_u_Texture_0",
|
||||
&rel->texture,
|
||||
ShaderParameterType::TEXTURE
|
||||
));
|
||||
}
|
@ -1,34 +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 SimpleTexturedShaderDataSub {
|
||||
glm::mat4 projection;
|
||||
glm::mat4 view;
|
||||
glm::mat4 model;
|
||||
struct Color color = COLOR_WHITE;
|
||||
|
||||
bool hasTexture = false;
|
||||
};
|
||||
|
||||
struct SimpleTexturedShaderData {
|
||||
struct SimpleTexturedShaderDataSub data;
|
||||
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