8 : m_isCompiled(false), m_vertexOutput(vertexOutput)
12 PixelShader::~PixelShader() {}
14 bool PixelShader::compileFromSource(
const std::string& userCode)
16 std::string finalUserCode = userCode.empty() ? generateDefaultCode() : userCode;
17 m_source = combineCode(finalUserCode);
21 std::string PixelShader::generateDefaultCode()
const
24 ss <<
"PixelOutput main(PixelInput ps_input) {\n";
25 ss <<
" PixelOutput ps_output;\n";
27 bool hasColorAttribute =
false;
28 for (
const auto& output : m_vertexOutput.getOutputs()) {
29 if (output.type == PipelineAttributeType::Color4f) {
30 hasColorAttribute =
true;
32 ss <<
" ps_output." << output.name <<
" = ps_input." << output.name <<
";\n";
35 if (!hasColorAttribute) {
36 ss <<
" ps_output.color = vec4(1.0, 0.647, 0.0, 1.0);\n";
39 ss <<
" return ps_output;\n";
44 std::string PixelShader::combineCode(
const std::string& userCode)
const
47 ss <<
"#version 320 es\n\n";
48 ss <<
"precision highp float;\n";
49 ss <<
"precision highp int;\n";
50 ss <<
"precision highp sampler2D;\n";
51 ss <<
"precision highp sampler2DArray;\n";
53 bool hasColorAttribute =
false;
54 bool hasTexCoordAttribute =
false;
55 bool hasTextureId =
false;
56 for (
const auto& output : m_vertexOutput.getOutputs()) {
57 if (output.type == PipelineAttributeType::Color4f) {
58 hasColorAttribute =
true;
60 if (output.type == PipelineAttributeType::TexCoord2f) {
61 hasTexCoordAttribute =
true;
63 if (output.type == PipelineAttributeType::TextureId) {
69 ss <<
"layout(binding = 3) uniform sampler2DArray mainTexture;\n\n";
72 ss <<
"layout(binding = 3) uniform sampler2D mainTexture;\n\n";
75 ss <<
"struct PixelInput {\n";
76 for (
const auto& output : m_vertexOutput.getOutputs()) {
77 ss <<
" " <<
GetDataTypeName(output.dataType) <<
" " << output.name <<
";\n";
81 ss <<
"struct PixelOutput {\n";
82 for (
const auto& output : m_vertexOutput.getOutputs()) {
83 ss <<
" " <<
GetDataTypeName(output.dataType) <<
" " << output.name <<
";\n";
85 if (!hasColorAttribute) {
86 ss <<
" vec4 color;\n";
90 int locationCounter = 0;
91 for (
const auto& output : m_vertexOutput.getOutputs()) {
92 ss <<
"layout (location = " << locationCounter + 1 <<
") " << (output.flat ?
"flat" :
"\0") <<
" in " <<
GetDataTypeName(output.dataType) <<
" vs2fs_" << output.name <<
";\n";
95 ss <<
"\nlayout (location = 0)out vec4 FragColor;\n\n";
96 ss <<
"PixelOutput fct_user_main(PixelInput);\n\n";
98 ss <<
"void main() {\n";
99 ss <<
" PixelInput ps_input;\n";
100 for (
const auto& output : m_vertexOutput.getOutputs()) {
101 ss <<
" ps_input." << output.name <<
" = vs2fs_" << output.name <<
";\n";
103 if (hasTexCoordAttribute) {
104 if (hasColorAttribute) {
106 ss <<
"ps_input." << getColorName() <<
" *= texture(mainTexture, vec3(ps_input." << getTexCoordName() <<
",ps_input." << getTextureIdName() <<
")); \n";
109 ss <<
"ps_input." << getColorName() <<
" *= texture(mainTexture, ps_input." << getTexCoordName() <<
"); \n";
114 ss <<
"ps_input." << getColorName() <<
" = texture(mainTexture, vec3(ps_input." << getTexCoordName() <<
",ps_input." << getTextureIdName() <<
")); \n";
117 ss <<
"ps_input." << getColorName() <<
" = texture(mainTexture, ps_input." << getTexCoordName() <<
"); \n";
121 ss <<
" PixelOutput ps_output = fct_user_main(ps_input);\n";
122 if (hasColorAttribute) {
123 for (
const auto& output : m_vertexOutput.getOutputs()) {
124 if (output.type == PipelineAttributeType::Color4f) {
125 ss <<
" FragColor = ps_output." << output.name <<
";\n";
131 ss <<
" FragColor = ps_output.color;\n";
134 std::string modifiedUserCode = userCode;
135 size_t mainPos = modifiedUserCode.find(
"main");
136 if (mainPos != std::string::npos) {
137 modifiedUserCode.replace(mainPos, 4,
"fct_user_main");
140 ss << modifiedUserCode;
146 return PipelineResourceType::PixelShader;
148 std::string PixelShader::getCompileError()
const {
149 return m_compileError;
152 const std::string& PixelShader::getSource()
const {
156 bool PixelShader::isCompiled()
const {
160 std::string PixelShader::getTexCoordName()
const {
161 for (
const auto& output : m_vertexOutput.getOutputs()) {
162 if (output.type == PipelineAttributeType::TexCoord2f) {
168 std::string PixelShader::getTextureIdName()
const {
169 for (
const auto& output : m_vertexOutput.getOutputs()) {
170 if (output.type == PipelineAttributeType::TextureId) {
176 std::string PixelShader::getColorName()
const {
177 for (
const auto& output : m_vertexOutput.getOutputs()) {
178 if (output.type == PipelineAttributeType::Color4f) {
PixelShader(Context *ctx)
const char * GetDataTypeName(DataType type)