FCT
载入中...
搜索中...
未找到
PixelShader.cpp
浏览该文件的文档.
1#include "../headers.h"
2#include <sstream>
3
4namespace FCT {
5
6#ifdef FCT_DEPRECATED
7 PixelShader::PixelShader(const ShaderOutput& vertexOutput)
8 : m_isCompiled(false), m_vertexOutput(vertexOutput)
9 {
10 }
11
12 PixelShader::~PixelShader() {}
13
14 bool PixelShader::compileFromSource(const std::string& userCode)
15 {
16 std::string finalUserCode = userCode.empty() ? generateDefaultCode() : userCode;
17 m_source = combineCode(finalUserCode);
18 return compile();
19 }
20
21 std::string PixelShader::generateDefaultCode() const
22 {
23 std::stringstream ss;
24 ss << "PixelOutput main(PixelInput ps_input) {\n";
25 ss << " PixelOutput ps_output;\n";
26
27 bool hasColorAttribute = false;
28 for (const auto& output : m_vertexOutput.getOutputs()) {
29 if (output.type == PipelineAttributeType::Color4f) {
30 hasColorAttribute = true;
31 }
32 ss << " ps_output." << output.name << " = ps_input." << output.name << ";\n";
33 }
34
35 if (!hasColorAttribute) {
36 ss << " ps_output.color = vec4(1.0, 0.647, 0.0, 1.0);\n";
37 }
38
39 ss << " return ps_output;\n";
40 ss << "}\n";
41 return ss.str();
42 }
43
44 std::string PixelShader::combineCode(const std::string& userCode) const
45 {
46 std::stringstream ss;
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";
52
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;
59 }
60 if (output.type == PipelineAttributeType::TexCoord2f) {
61 hasTexCoordAttribute = true;
62 }
63 if (output.type == PipelineAttributeType::TextureId) {
64 hasTextureId = true;
65 }
66 }
67 //ss << "#extension GL_ARB_shading_language_420pack : enable\n";
68 if (hasTextureId) {
69 ss << "layout(binding = 3) uniform sampler2DArray mainTexture;\n\n";
70 }
71 else {
72 ss << "layout(binding = 3) uniform sampler2D mainTexture;\n\n";
73 }
74
75 ss << "struct PixelInput {\n";
76 for (const auto& output : m_vertexOutput.getOutputs()) {
77 ss << " " << GetDataTypeName(output.dataType) << " " << output.name << ";\n";
78 }
79 ss << "};\n\n";
80
81 ss << "struct PixelOutput {\n";
82 for (const auto& output : m_vertexOutput.getOutputs()) {
83 ss << " " << GetDataTypeName(output.dataType) << " " << output.name << ";\n";
84 }
85 if (!hasColorAttribute) {
86 ss << " vec4 color;\n";
87 }
88 ss << "};\n\n";
89
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";
93 locationCounter++;
94 }
95 ss << "\nlayout (location = 0)out vec4 FragColor;\n\n";
96 ss << "PixelOutput fct_user_main(PixelInput);\n\n";
97
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";
102 }
103 if (hasTexCoordAttribute) {
104 if (hasColorAttribute) {
105 if (hasTextureId) {
106 ss << "ps_input." << getColorName() << " *= texture(mainTexture, vec3(ps_input." << getTexCoordName() << ",ps_input." << getTextureIdName() << ")); \n";
107 }
108 else {
109 ss << "ps_input." << getColorName() << " *= texture(mainTexture, ps_input." << getTexCoordName() << "); \n";
110 }
111 }
112 else {
113 if (hasTextureId) {
114 ss << "ps_input." << getColorName() << " = texture(mainTexture, vec3(ps_input." << getTexCoordName() << ",ps_input." << getTextureIdName() << ")); \n";
115 }
116 else {
117 ss << "ps_input." << getColorName() << " = texture(mainTexture, ps_input." << getTexCoordName() << "); \n";
118 }
119 }
120 }
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";
126 break;
127 }
128 }
129 }
130 else {
131 ss << " FragColor = ps_output.color;\n";
132 }
133 ss << "}\n\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");
138 }
139
140 ss << modifiedUserCode;
141
142 return ss.str();
143 }
144 PipelineResourceType PixelShader::getType() const
145 {
146 return PipelineResourceType::PixelShader;
147 }
148 std::string PixelShader::getCompileError() const {
149 return m_compileError;
150 }
151
152 const std::string& PixelShader::getSource() const {
153 return m_source;
154 }
155
156 bool PixelShader::isCompiled() const {
157 return m_isCompiled;
158 }
159
160 std::string PixelShader::getTexCoordName() const {
161 for (const auto& output : m_vertexOutput.getOutputs()) {
162 if (output.type == PipelineAttributeType::TexCoord2f) {
163 return output.name;
164 }
165 }
166 return "";
167 }
168 std::string PixelShader::getTextureIdName() const {
169 for (const auto& output : m_vertexOutput.getOutputs()) {
170 if (output.type == PipelineAttributeType::TextureId) {
171 return output.name;
172 }
173 }
174 }
175
176 std::string PixelShader::getColorName() const {
177 for (const auto& output : m_vertexOutput.getOutputs()) {
178 if (output.type == PipelineAttributeType::Color4f) {
179 return output.name;
180 }
181 }
182 return "color";
183 }
184#endif
185} // namespace FCT
PixelShader(Context *ctx)
const char * GetDataTypeName(DataType type)