-
Notifications
You must be signed in to change notification settings - Fork 4
/
video-shader-translate-cgc.cpp
231 lines (197 loc) · 6.26 KB
/
video-shader-translate-cgc.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
#include "io.h"
#include "os.h"
#include "containers.h"
#include "string.h"
#ifdef HAVE_CG_SHADERS
#error "Doesn't work. Won't be fixed until I understand the shader system better, and figure out why libCg doesn't support gles[vf]."
//TODO: This file will be translated to C once it's finished. Don't do anything too scary.
//http://http.developer.nvidia.com/Cg/cgSetCompilerIncludeString.html
//McGreen.glsl uses
//#pragma parameter MCGREEN_COLOR "McGreen Color" 256.0 0.0 256.0 1.0
//uniform float MCGREEN_COLOR;
//
//in vec4 VertexCoord;
//in vec4 COLOR;
//in vec4 TexCoord;
//
//uniform mat4 MVPMatrix;
//(!) uniform int FrameDirection;
//(!) uniform int FrameCount;
//(!) uniform COMPAT_PRECISION vec2 OutputSize;
//(!) uniform COMPAT_PRECISION vec2 TextureSize;
//(!) uniform COMPAT_PRECISION vec2 InputSize;
//uniform sampler2D Texture;
//
//out vec4 FragColor;
//The Cg output uses
//in vec4 COLOR;
//in vec4 TEXCOORD0;
//in vec4 cg_Vertex;
//
//uniform vec4 _modelViewProj1[4];
//uniform sampler2D _s_p1;
//uniform float _MCGREEN_COLOR;
//
//out vec4 cg_FragColor;
//Defines used (may be renamed):
//// GLSL shader autogenerated by cg2glsl.py.
//#if defined(VERTEX)
//#if __VERSION__ >= 130
//#define COMPAT_VARYING out
//#define COMPAT_ATTRIBUTE in
//#define COMPAT_TEXTURE texture
//#else
//#define COMPAT_VARYING varying
//#define COMPAT_ATTRIBUTE attribute
//#define COMPAT_TEXTURE texture2D
//#endif
//
//#ifdef GL_ES
//#define COMPAT_PRECISION mediump
//#else
//#define COMPAT_PRECISION
//#endif
//
//** VERTEX CODE **
//
//#elif defined(FRAGMENT)
//#if __VERSION__ >= 130
//#define COMPAT_VARYING in
//#define COMPAT_TEXTURE texture
//out vec4 FragColor;
//#else
//#define COMPAT_VARYING varying
//#define FragColor gl_FragColor
//#define COMPAT_TEXTURE texture2D
//#endif
//
//#ifdef GL_ES
//#ifdef GL_FRAGMENT_PRECISION_HIGH
//precision highp float;
//#else
//precision mediump float;
//#endif
//#define COMPAT_PRECISION mediump
//#else
//#define COMPAT_PRECISION
//#endif
//
//** FRAGMENT CODE **
//
//#endif
#define CG_EXPLICIT // disable prototypes so I don't use them by accident
#include <Cg/cg.h>
namespace {
#define CG_SYMS() \
CG_SYM(CGcontext, CreateContext, (void)) \
CG_SYM(CGprogram, CreateProgram, (CGcontext context, CGenum program_type, const char * program, \
CGprofile profile, const char * entry, const char ** args)) \
CG_SYM(void, SetCompilerIncludeCallback, (CGcontext context, CGIncludeCallbackFunc func)) \
CG_SYM(void, SetCompilerIncludeString, (CGcontext context, const char * name, const char * source)) \
CG_SYM(CGbool, IsProgramCompiled, (CGprogram program)) \
CG_SYM(const char *, GetProgramString, (CGprogram program, CGenum pname)) \
CG_SYM(void, DestroyContext, (CGcontext context)) \
\
CG_SYM(const char *, GetLastListing, (CGcontext context)) \
#define CG_SYM(ret, name, args) ret (CGENTRY * name) args;
struct cglib { CG_SYMS() ndylib* lib; };
#undef CG_SYM
#define CG_SYM(ret, name, args) "cg"#name,
static const char * const cg_names[]={ CG_SYMS() };
#undef CG_SYM
class cg_translator;
static ptrmap<CGcontext, cg_translator*> cgc_translators;//TODO: this object is not thread safe.
class cg_translator {
public:
struct cglib cg;
CGcontext context;
function<char*(const char * filename)> get_include;
//TODO: shader parameters
cg_translator()
{
context=NULL;
cg.lib=NULL;
}
bool load_functions()
{
cg.lib=dylib_create(DYLIB_MAKE_NAME("Cg"));
if (!cg.lib) return false;
funcptr* functions=(funcptr*)&cg;
for (unsigned int i=0;i<sizeof(cg_names)/sizeof(*cg_names);i++)
{
functions[i]=dylib_sym_func(cg.lib, cg_names[i]);
if (!functions[i]) return false;
}
return true;
}
string preprocess(cstring text)
{
stringlist lines=text.split('\n');
for (size_t i=0;i<lines.len();i++)
{
//TODO: inspect whether fixed4x4 is relevant
if (lines[i].contains("uniform") && (lines[i].contains("float4x4") || lines[i].contains("half4x4")))
{
lines[i]=(S"#pragma pack_matrix(column_major)\n"+lines[i]+"\n#pragma pack_matrix(row_major)");
}
}
return lines.join('\n');
}
void cgc_include_cb(const char * filename)
{
while (*filename=='/') filename++; // what the hell
char* text_tmp=this->get_include(filename);
string text=text_tmp;
free(text_tmp);
if (text)
{
cg.SetCompilerIncludeString(context, filename, preprocess(text));
}
else
{
cg.SetCompilerIncludeString(context, filename, "#error \"File not available.\"");
}
}
static void cgc_include_cb_s(CGcontext context, const char * filename)
{
cgc_translators.get(context)->cgc_include_cb(filename);
}
char* translate(video::shader::lang_t from, video::shader::lang_t to, const char * text,
function<char*(const char * filename)> get_include)
{
if (from!=video::shader::la_cg) return NULL;
if (to!=video::shader::la_glsl) return NULL;
if (!load_functions()) return NULL;
this->context = cg.CreateContext();
this->get_include = get_include;
//printf("f=%i v=%i\n",cg.GetProfile("glesf"),cg.GetProfile("glesv"));exit(0);
#define e printf("e=%s\n",cg.GetLastListing(this->context));
cgc_translators.set(this->context, this);
cg.SetCompilerIncludeCallback(this->context, cgc_include_cb_s);
string text_p=preprocess(text);
static const char * args[]={ "version=130"/*GL 3.0*/, /*"-O3",*/ "-DPARAMETER_UNIFORM", NULL };
CGprogram vertex_p = cg.CreateProgram(this->context, CG_SOURCE, text_p, CG_PROFILE_GLSLV, "main_vertex", args);
CGprogram fragment_p = cg.CreateProgram(this->context, CG_SOURCE, text_p, CG_PROFILE_GLSLF, "main_fragment", args);
if (!cg.IsProgramCompiled(vertex_p) || !cg.IsProgramCompiled(fragment_p)) return NULL;
string vertex=cg.GetProgramString(vertex_p, CG_COMPILED_PROGRAM);
string fragment=cg.GetProgramString(fragment_p, CG_COMPILED_PROGRAM);
//TODO: do this properly, start at cg2glsl.py:584
puts(vertex);
puts(fragment);
puts("ALL OK");
return NULL;
}
~cg_translator()
{
if (context) cgc_translators.remove(context);
if (cg.DestroyContext && context) cg.DestroyContext(context);
if (cg.lib) dylib_free(cg.lib);
}
};
}
char * video::shader::translate_cgc(lang_t from, lang_t to, const char * text, function<char*(const char * filename)> get_include)
{
cg_translator tr;
return tr.translate(from, to, text, get_include);
}
#endif