zenilib: zenilib/jni/external/zenilib/zeni_graphics/Shader.cpp Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Shader.cpp
Go to the documentation of this file.
1 /* This file is part of the Zenipex Library (zenilib).
2 * Copyright (C) 2011 Mitchell Keith Bloch (bazald).
3 *
4 * zenilib is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * zenilib is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with zenilib. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include <zeni_graphics.h>
19
20 #ifndef DISABLE_DX9
21 #include <d3dx9shader.h>
22 #endif
23
24 #include <iostream>
25
26 namespace Zeni {
27
28 #ifndef DISABLE_GL_FIXED
29 Shader_GL_Fixed::Shader_GL_Fixed(const String &shader_src, const Type &type)
30 : m_shader(glCreateShaderObjectARB(type == VERTEX ? GL_VERTEX_SHADER_ARB : GL_FRAGMENT_SHADER_ARB))
31 {
32 const char * src_ptr = shader_src.c_str();
33 glShaderSourceARB(m_shader, 1, reinterpret_cast<const GLchar **>(&src_ptr), 0);
34 if(!m_shader)
35 throw Shader_Init_Failure();
36 glCompileShaderARB(m_shader);
37 }
38
39 Shader_GL_Fixed::~Shader_GL_Fixed() {
40 glDeleteShader(m_shader);
41 }
42
43 Program_GL_Fixed::Program_GL_Fixed()
44 : m_program(glCreateProgram())
45 {
46 }
47
48 Program_GL_Fixed::~Program_GL_Fixed() {
49 for(std::list<Shader_GL_Fixed *>::iterator it = m_shaders.begin(), iend = m_shaders.end(); it != iend; ++it)
50 glDetachShader(m_program, (*it)->get());
51 m_shaders.clear();
52
53 glDeleteProgram(m_program);
54 }
55
56 void Program_GL_Fixed::attach(Shader &shader) {
57 Shader_GL_Fixed &shader_gl_fixed = dynamic_cast< Shader_GL_Fixed &>(shader);
58 m_shaders.push_back(&shader_gl_fixed);
59 glAttachShader(m_program, shader_gl_fixed.get());
60 }
61
62 void Program_GL_Fixed::link() {
63 glLinkProgramARB(m_program);
64
65 GLint rv = GL_TRUE;
66 glGetProgramivARB(m_program, GL_LINK_STATUS, &rv);
67 if(rv != GL_TRUE)
68 throw Shader_Link_Failure();
69 }
70 #endif
71
72 #ifndef DISABLE_GL_SHADER
73 Shader_GL_Shader::Shader_GL_Shader(const String &shader_src, const Type &type)
74 : m_shader(glCreateShader(type == VERTEX ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER))
75 {
76 const char * src_ptr = shader_src.c_str();
77 glShaderSource(m_shader, 1, reinterpret_cast<const GLchar **>(&src_ptr), 0);
78 if(!m_shader)
79 throw Shader_Init_Failure();
80 glCompileShader(m_shader);
81
82 // Check vertex shader
83 GLint rv = GL_TRUE, len;
84 glGetShaderiv(m_shader, GL_COMPILE_STATUS, &rv);
85 if(rv != GL_TRUE) {
86 glGetShaderiv(m_shader, GL_INFO_LOG_LENGTH, &len);
87 Zeni::String log(len > 0 ? len - 1 : 0, '\0');
88 glGetShaderInfoLog(m_shader, len, 0, reinterpret_cast<GLchar *>(const_cast<char *>(log.c_str())));
89 std::cerr << "Shader initialization failure: " << log << std::endl;
90 throw Shader_Init_Failure();
91 }
92 }
93
94 Shader_GL_Shader::~Shader_GL_Shader() {
95 glDeleteShader(m_shader);
96 }
97
98 Program_GL_Shader::Program_GL_Shader()
99 : m_program(glCreateProgram())
100 {
101 }
102
103 Program_GL_Shader::~Program_GL_Shader() {
104 for(std::list<Shader_GL_Shader *>::iterator it = m_shaders.begin(), iend = m_shaders.end(); it != iend; ++it)
105 glDetachShader(m_program, (*it)->get());
106 m_shaders.clear();
107
108 glDeleteProgram(m_program);
109 }
110
111 void Program_GL_Shader::attach(Shader &shader) {
112 Shader_GL_Shader &shader_gl_shader = dynamic_cast< Shader_GL_Shader &>(shader);
113 m_shaders.push_back(&shader_gl_shader);
114 glAttachShader(m_program, shader_gl_shader.get());
115 }
116
117 void Program_GL_Shader::link() {
118 glLinkProgram(m_program);
119
120 GLint rv = GL_TRUE, len;
121 glGetProgramiv(m_program, GL_LINK_STATUS, &rv);
122 if(rv != GL_TRUE) {
123 glGetProgramiv(m_program, GL_INFO_LOG_LENGTH, &len);
124 Zeni::String log(len > 0 ? len - 1 : 0, '\0');
125 glGetProgramInfoLog(m_program, len, 0, reinterpret_cast<GLchar *>(const_cast<char *>(log.c_str())));
126 std::cerr << "Shader link failure: " << log << std::endl;
127 throw Shader_Link_Failure();
128 }
129 }
130 #endif
131
132 #ifndef DISABLE_DX9
133 Shader_DX9::Shader_DX9(const String &shader_src, const Type &type, Video_DX9 &vdx)
134 : m_constant_table(0),
135 m_vertex_shader(0)
136 {
137 String shader_src_full = shader_src;
138 if(type == VERTEX) {
139 String uniforms;
140 int pos, pos2;
141
142 pos = shader_src_full.find("// Attributes");
143 shader_src_full = shader_src_full.substr(0, pos) + "struct VS_INPUT {" + shader_src_full.substr(pos + 13);
144 pos = shader_src_full.find("// Varyings");
145 shader_src_full = shader_src_full.substr(0, pos) + "};\nstruct VS_OUTPUT {\nfloat4 gl_Position : POSITION;" + shader_src_full.substr(pos + 11);
146 pos = shader_src_full.rfind("static");
147 pos = shader_src_full.find(';', pos);
148 shader_src_full = shader_src_full.substr(0, pos + 1) + "\n}; " + shader_src_full.substr(pos + 1);
149 pos = shader_src_full.find("static float4 gl_Position");
150 pos2 = shader_src_full.find(';', pos);
151 shader_src_full = shader_src_full.substr(0, pos) + shader_src_full.substr(pos2 + 1);
152
153 std::set<String> ins;
154 std::set<String> outs;
155 outs.insert("gl_Position");
156
157 for(pos2 = shader_src_full.find("uniform ");; pos2 = pos) {
158 pos = shader_src_full.rfind(" = ", pos2);
159 if(pos == String::npos)
160 break;
161 pos2 = shader_src_full.find(';', pos);
162 shader_src_full = shader_src_full.substr(0, pos) + shader_src_full.substr(pos2);
163 }
164 for(pos = 0;;) {
165 pos = shader_src_full.find("static ", pos);
166 if(pos == String::npos)
167 break;
168 pos = shader_src_full.find(' ', pos + 7) + 1;
169 pos2 = shader_src_full.find(';', pos);
170 if(shader_src_full.rfind("VS_OUTPUT", pos) != String::npos)
171 outs.insert(shader_src_full.substr(pos, pos2 - pos));
172 else
173 ins.insert(shader_src_full.substr(pos, pos2 - pos));
174 pos = pos2;
175 }
176 for(pos = 0;;) {
177 pos = shader_src_full.find("static ", pos);
178 if(pos == String::npos)
179 break;
180 pos2 = shader_src_full.find(';', pos);
181 String sub = shader_src_full.substr(pos + 7, pos2 - (pos + 7));
182 if(sub.find("position") != String::npos)
183 sub = " : POSITION";
184 else if(sub.find("color") != String::npos)
185 sub = " : COLOR";
186 else
187 sub.clear();
188 shader_src_full = shader_src_full.substr(0, pos) + shader_src_full.substr(pos + 7, pos2 - (pos + 7))
189 + sub + shader_src_full.substr(pos2);
190 }
191 for(pos = 0;;) {
192 pos = shader_src_full.find("uniform ", pos);
193 if(pos == String::npos)
194 break;
195 pos2 = shader_src_full.find(": register(", pos);
196 uniforms += ", " + shader_src_full.substr(pos, pos2 - pos);
197 shader_src_full = shader_src_full.substr(0, pos) + shader_src_full.substr(pos2 + 14);
198 }
199
200 pos = shader_src_full.find("void gl_main()");
201 pos2 = shader_src_full.find('{', pos) + 1;
202 for(int count = 1; count; ++pos2) {
203 if(shader_src_full[pos2] == '}')
204 --count;
205 else if(shader_src_full[pos2] == '{')
206 ++count;
207 }
208 String shader_front = shader_src_full.substr(0, pos);
209 String shader_back = shader_src_full.substr(pos2 + 1);
210 String main_body = shader_src_full.substr(pos + 14, (pos2 + 1) - (pos + 14));
211
212 for(std::set<String>::iterator it = ins.begin(), iend = ins.end(); it != iend; ++it) {
213 for(pos = main_body.size();;) {
214 pos = main_body.rfind(*it, pos);
215 if(pos == String::npos)
216 break;
217 main_body = main_body.substr(0, pos) + "v." + main_body.substr(pos);
218 }
219 }
220 for(std::set<String>::iterator it = outs.begin(), iend = outs.end(); it != iend; ++it) {
221 for(pos = main_body.size();;) {
222 pos = main_body.rfind(*it, pos);
223 if(pos == String::npos)
224 break;
225 main_body = main_body.substr(0, pos) + "o." + main_body.substr(pos);
226 }
227 }
228
229 shader_src_full = shader_front + "VS_OUTPUT vs_main(const VS_INPUT v" + uniforms + ") {VS_OUTPUT o; " + main_body + "return o;}";
230 }
231 else {
232 String uniforms;
233 int pos, pos2;
234
235 pos = shader_src_full.find("// Varyings");
236 shader_src_full = shader_src_full.substr(0, pos) + "struct PS_INPUT {\nfloat4 gl_Position : POSITION;" + shader_src_full.substr(pos + 11);
237 pos = shader_src_full.rfind("static");
238 pos = shader_src_full.find(';', pos);
239 shader_src_full = shader_src_full.substr(0, pos + 1) + "\n}; " + shader_src_full.substr(pos + 1);
240 pos = shader_src_full.find("static float4 gl_Color[1]");
241 pos2 = shader_src_full.find(';', pos);
242 shader_src_full = shader_src_full.substr(0, pos) + shader_src_full.substr(pos2 + 1);
243
244 std::set<String> ins;
245
246 for(pos2 = shader_src_full.find("#define GL_USES_FRAG_COLOR");; pos2 = pos) {
247 pos = shader_src_full.rfind(" = ", pos2);
248 if(pos == String::npos)
249 break;
250 pos2 = shader_src_full.find(';', pos);
251 shader_src_full = shader_src_full.substr(0, pos) + shader_src_full.substr(pos2);
252 }
253 for(pos = 0;;) {
254 pos = shader_src_full.find("static ", pos);
255 if(pos == String::npos)
256 break;
257 pos = shader_src_full.find(' ', pos + 7) + 1;
258 pos2 = shader_src_full.find(';', pos);
259 ins.insert(shader_src_full.substr(pos, pos2 - pos));
260 pos = pos2;
261 }
262 for(pos = 0;;) {
263 pos = shader_src_full.find("static ", pos);
264 if(pos == String::npos)
265 break;
266 pos2 = shader_src_full.find(';', pos);
267 String sub = shader_src_full.substr(pos + 7, pos2 - (pos + 7));
268 if(sub.find("position") != String::npos)
269 sub = " : POSITION";
270 else if(sub.find("color") != String::npos)
271 sub = " : COLOR";
272 else
273 sub.clear();
274 shader_src_full = shader_src_full.substr(0, pos) + shader_src_full.substr(pos + 7, pos2 - (pos + 7))
275 + sub + shader_src_full.substr(pos2);
276 }
277
278 pos = shader_src_full.find("void gl_main()");
279 pos2 = shader_src_full.find('{', pos) + 1;
280 for(int count = 1; count; ++pos2) {
281 if(shader_src_full[pos2] == '}')
282 --count;
283 else if(shader_src_full[pos2] == '{')
284 ++count;
285 }
286 String shader_front = shader_src_full.substr(0, pos);
287 String shader_back = shader_src_full.substr(pos2 + 1);
288 String main_body = shader_src_full.substr(pos + 14, (pos2 + 1) - (pos + 14));
289
290 for(std::set<String>::iterator it = ins.begin(), iend = ins.end(); it != iend; ++it) {
291 for(pos = main_body.size();;) {
292 pos = main_body.rfind(*it, pos);
293 if(pos == String::npos)
294 break;
295 main_body = main_body.substr(0, pos) + "p." + main_body.substr(pos);
296 }
297 }
298 for(pos = main_body.size();;) {
299 pos = main_body.rfind("gl_Color[0]", pos);
300 if(pos == String::npos)
301 break;
302 main_body = main_body.substr(0, pos) + "gl_Color" + main_body.substr(pos + 11);
303 }
304
305 shader_src_full = shader_front + "float4 ps_main(const PS_INPUT p" + uniforms + ") : COLOR {\nfloat4 gl_Color;" + main_body + "return gl_Color;}";
306 }
307
308 std::cerr << "Shader Source Full:" << std::endl << shader_src_full << std::endl;
309
310 LPD3DXBUFFER code;
311 LPD3DXBUFFER errors;
312
313 HRESULT result = vdx.D3DXCompileShader()(shader_src_full.c_str(),
314 shader_src_full.size(),
315 0,
316 0,
317 type == VERTEX ? "vs_main" : "ps_main",
318 type == VERTEX ? "vs_3_0" : "ps_3_0",
319 0,
320 &code,
321 &errors,
322 type == VERTEX ? &m_constant_table : 0);
323
324 if(FAILED(result)) {
325 std::cerr << "Errors:" << std::endl << reinterpret_cast<char *>(errors->GetBufferPointer());
326 errors->Release();
327 throw Shader_Init_Failure();
328 }
329
330 if(type == VERTEX)
331 vdx.get_d3d_device()->CreateVertexShader((DWORD*)code->GetBufferPointer(), &m_vertex_shader);
332 else
333 vdx.get_d3d_device()->CreatePixelShader((DWORD*)code->GetBufferPointer(), &m_pixel_shader);
334
335 code->Release();
336 }
337
338 Shader_DX9::~Shader_DX9() {
339 if(m_constant_table) {
340 m_constant_table->Release();
341 if(m_vertex_shader)
342 m_vertex_shader->Release();
343 }
344 else if(m_pixel_shader)
345 m_pixel_shader->Release();
346 }
347
348 Program_DX9::Program_DX9()
349 : m_vertex_shader(0),
350 m_fragment_shader(0)
351 {
352 }
353
354 Program_DX9::~Program_DX9() {
355 }
356
357 void Program_DX9::attach(Shader &shader) {
358 Shader_DX9 &sdx = dynamic_cast< Shader_DX9 &>(shader);
359
360 if(sdx.type() == Shader::VERTEX) {
361 if(m_vertex_shader)
362 throw Shader_Link_Failure();
363 m_vertex_shader = &sdx;
364 }
365 else {
366 if(m_fragment_shader)
367 throw Shader_Link_Failure();
368 m_fragment_shader = &sdx;
369 }
370 }
371
372 void Program_DX9::link() {
373 }
374 #endif
375
376 }
GL_TRUE
#define GL_TRUE
Definition: gl2.h:51
Zeni::Program_GL_Fixed::attach
void attach(Shader &shader)
Definition: Shader.cpp:56
glLinkProgramARB
#define glLinkProgramARB
Definition: glew.h:5677
GL_FRAGMENT_SHADER
#define GL_FRAGMENT_SHADER
Definition: gl2.h:259
GL_LINK_STATUS
#define GL_LINK_STATUS
Definition: gl2.h:270
Zeni::Video_DX9
The Direct3D9 Rendering System.
Definition: Video_DX9.h:62
Zeni::String::clear
void clear()
Definition: String.cpp:323
Zeni::Video_DX9::get_d3d_device
LPDIRECT3DDEVICE9 & get_d3d_device()
See DirectX Documentation for details.
Definition: Video_DX9.hxx:48
type
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
Definition: gl2ext.h:845
Zeni::Shader_DX9
Definition: Shader.h:203
glCreateShaderObjectARB
#define glCreateShaderObjectARB
Definition: glew.h:5664
glShaderSource
GL_APICALL void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar **string, const GLint *length)
Zeni::String::find
size_t find(const String &str, size_t pos=0) const
Definition: String.cpp:480
Zeni::Shader_Init_Failure
Definition: Shader.h:244
Zeni::Program_GL_Shader::link
void link()
Definition: Shader.cpp:117
HRESULT
typedef HRESULT(WINAPI *LPD3DXIMTSIGNALCALLBACK)(CONST D3DXVECTOR2 *uv
Zeni::Program_GL_Shader::~Program_GL_Shader
virtual ~Program_GL_Shader()
Definition: Shader.cpp:103
Zeni::Shader_DX9::~Shader_DX9
~Shader_DX9()
Definition: Shader.cpp:338
Zeni::Shader_GL_Fixed::~Shader_GL_Fixed
virtual ~Shader_GL_Fixed()
Definition: Shader.cpp:39
Zeni::Shader_DX9::type
Shader::Type type() const
Definition: Shader.hxx:49
Zeni::Shader_GL_Fixed::get
GLuint get() const
Definition: Shader.hxx:29
GL_INFO_LOG_LENGTH
#define GL_INFO_LOG_LENGTH
Definition: gl2.h:410
Zeni::String::c_str
const char * c_str() const
Definition: String.cpp:467
Zeni::Shader::VERTEX
Definition: Shader.h:102
len
GLenum GLsizei len
Definition: glew.h:7035
GL_VERTEX_SHADER
#define GL_VERTEX_SHADER
Definition: gl2.h:260
Zeni::Shader_GL_Shader
Definition: Shader.h:162
glDeleteShader
GL_APICALL void GL_APIENTRY glDeleteShader(GLuint shader)
Zeni::String::substr
String substr(size_t pos=0, size_t n=npos) const
Definition: String.cpp:510
glGetProgramInfoLog
GL_APICALL void GL_APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
Zeni::String
Definition: String.h:29
Zeni::Video_DX9::D3DXCompileShader
static D3DXCompileShader_fcn D3DXCompileShader()
Definition: Video_DX9.h:118
glCompileShaderARB
#define glCompileShaderARB
Definition: glew.h:5662
glCreateProgram
GL_APICALL GLuint GL_APIENTRY glCreateProgram(void)
Zeni::Shader::Type
Type
Definition: Shader.h:102
Zeni::Program_DX9::Program_DX9
Program_DX9()
Definition: Shader.cpp:348
d3dx9shader.h
glAttachShader
GL_APICALL void GL_APIENTRY glAttachShader(GLuint program, GLuint shader)
result
GLuint64EXT * result
Definition: glew.h:12708
shader
GLuint shader
Definition: glew.h:1799
glCreateShader
GL_APICALL GLuint GL_APIENTRY glCreateShader(GLenum type)
glLinkProgram
GL_APICALL void GL_APIENTRY glLinkProgram(GLuint program)
Zeni::Shader_DX9::m_pixel_shader
LPDIRECT3DPIXELSHADER9 m_pixel_shader
Definition: Shader.h:220
count
GLint GLsizei count
Definition: gl2ext.h:1011
glGetShaderiv
GL_APICALL void GL_APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint *params)
Zeni::Program_GL_Shader::Program_GL_Shader
Program_GL_Shader()
Definition: Shader.cpp:98
Zeni::Shader_GL_Shader::get
GLuint get() const
Definition: Shader.hxx:39
Zeni::Program_GL_Fixed::~Program_GL_Fixed
~Program_GL_Fixed()
Definition: Shader.cpp:48
Zeni::String::rfind
size_t rfind(const String &str, size_t pos=npos) const
Definition: String.cpp:485
Zeni::String::npos
static const size_type npos
Definition: String.h:37
GL_COMPILE_STATUS
#define GL_COMPILE_STATUS
Definition: gl2.h:409
glCompileShader
GL_APICALL void GL_APIENTRY glCompileShader(GLuint shader)
glShaderSourceARB
#define glShaderSourceARB
Definition: glew.h:5678
code
Definition: inftrees.h:24
Zeni::Program_GL_Fixed::link
void link()
Definition: Shader.cpp:62
glGetShaderInfoLog
GL_APICALL void GL_APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
GLint
int GLint
Definition: gl2.h:28
Zeni::Shader_DX9::m_vertex_shader
LPDIRECT3DVERTEXSHADER9 m_vertex_shader
Definition: Shader.h:219
Zeni::Shader
A base class for Vertex_Shader and Fragment_Shader.
Definition: Shader.h:97
glDeleteProgram
GL_APICALL void GL_APIENTRY glDeleteProgram(GLuint program)
DWORD
typedef DWORD(WINAPI *XInputGetState_t)(DWORD dwUserIndex
Zeni::Program_GL_Shader::attach
void attach(Shader &shader)
Definition: Shader.cpp:111
Zeni::String::size
size_t size() const
Definition: String.cpp:310
LPD3DXBUFFER
interface ID3DXBuffer * LPD3DXBUFFER
Definition: d3dx9core.h:97
Zeni::Program_DX9::attach
void attach(Shader &shader)
Definition: Shader.cpp:357
glGetProgramivARB
#define glGetProgramivARB
Definition: glew.h:7084
Zeni::Shader_GL_Fixed
Definition: Shader.h:121
GL_FRAGMENT_SHADER_ARB
#define GL_FRAGMENT_SHADER_ARB
Definition: glew.h:4005
Zeni::Program_DX9::~Program_DX9
virtual ~Program_DX9()
Definition: Shader.cpp:354
Zeni::Shader_Link_Failure
Definition: Shader.h:248
Zeni::Program_DX9::link
void link()
Definition: Shader.cpp:372
zeni_graphics.h
glGetProgramiv
GL_APICALL void GL_APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint *params)
glDetachShader
GL_APICALL void GL_APIENTRY glDetachShader(GLuint program, GLuint shader)
GL_VERTEX_SHADER_ARB
#define GL_VERTEX_SHADER_ARB
Definition: glew.h:7146
Zeni::Program_GL_Fixed::Program_GL_Fixed
Program_GL_Fixed()
Definition: Shader.cpp:43
Zeni::Shader_GL_Shader::~Shader_GL_Shader
~Shader_GL_Shader()
Definition: Shader.cpp:94