Newer
Older
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "geometry.h"
#include "partiviewc.h" // for msg()
int shader_parse_args( struct stuff **, int argc, char *argv[], char *fromfname, void * )
{
if(argc>0 && !strcmp(argv[0], "shader"))
msg("Must recompile partiview with GLEW library to use shaders");
return 0;
}
void initShaderStuff( bool GLready )
{
}
#else /* HAVE_LIBGLEW */
#define GL_GLEXT_PROTOTYPES 1 /* yes, of course we want glUseProgram etc. declared. */
# ifdef _WIN32
# define GLEW_STATIC 1
# endif
#if 0 /* better HAVE_LIBGLEW */
# include <GL/gl.h>
# include <GL/glext.h>
# include <GL/glu.h>
#endif
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
#include "glshader.h"
#include "geometry.h"
#include "partiviewc.h"
ShaderStuff shaderstuff;
int shader_parse_args( struct stuff **, int argc, char *argv[], char *fromfname, void * )
{
if(argc>0 && !strcmp(argv[0], "shader")) {
if(shaderstuff.supported == ShaderStuff::UNKNOWN)
initShaderStuff( false );
msg("%s", useShader(argv[1]));
return 1;
} else {
return 0;
}
}
void initShaderStuff( bool GLready )
{
if(!shaderstuff.started) {
shaderstuff.started = true;
parti_add_commands( shader_parse_args, "shader", (void *)&shaderstuff );
}
#ifdef HAVE_LIBGLEW
if(shaderstuff.supported == ShaderStuff::UNKNOWN && GLready) {
GLenum ini;
if( (ini = glewInit()) != GLEW_OK ) {
fprintf(stderr, "initShaderStuff: glewInit(): %s\n", glewGetErrorString(ini));
return;
}
shaderstuff.supported = (GLEW_ARB_vertex_shader) ? ShaderStuff::SUPPORTED : ShaderStuff::UNSUPPORTED;
if(shaderstuff.shadername != 0 && shaderstuff.supported == ShaderStuff::SUPPORTED) {
/* if a shader was requested before we had a chance to initialize, try installing it now,
* and complain if there's trouble.
*/
msg( "%s", useShader( shaderstuff.shadername ) );
}
}
#else
shaderstuff.supported = ShaderStuff::UNSUPPORTED;
#endif
}
char *inhalefile(const char *fname, const char *forwhat)
{
FILE *f;
long flen;
char *s;
if(fname == 0 || 0==strcmp(fname,"none"))
return 0;
f = fopen(fname, "r");
if(f == 0) {
if(forwhat) {
fprintf(stderr, "partiview: can't open %s %s\n", fname, forwhat);
return 0;
}
}
fseek(f, 0, SEEK_END);
flen = ftell(f);
if(flen < 0) {
fclose(f);
fprintf(stderr, "partiview: can't measure length of file %s: %s\n", fname, strerror(errno));
return 0;
}
fseek(f, 0, SEEK_SET);
s = (char *)malloc(flen+1);
if(s==0 || fread(s, flen, 1, f) <= 0) {
perror(fname);
free(s);
fclose(f);
return 0;
}
s[flen] = '\0';
return s;
}
static const char default_vertshader[] = "\
#version 110\n\
\n\
main() {\n\
gl_Position = ftransform();\n\
}\n\
";
const char *reportShader(void)
{
static char *oom = 0;
if(shaderstuff.supported == ShaderStuff::UNKNOWN) {
return "shaders not initialized (initShaderStuff() never called)";
} else if(shaderstuff.supported == ShaderStuff::UNSUPPORTED) {
#ifdef HAVE_LIBGLEW
return "GLSL vertex shaders not supported";
#else
return "GLSL vertex shaders not available (not configured with GLEW library)";
#endif
} else if(shaderstuff.shadername) {
char rpt[200];
Stuart Levy
committed
snprintf(rpt, sizeof(rpt), "vertex shader %.175s loaded%s", shaderstuff.shadername, shaderstuff.enabled ? "" : "(disabled)");
if(oom) free(oom);
oom = strdup(rpt);
return oom;
} else {
return "No GLSL vertex shader loaded";
}
}
const char *useShader( const char *fname )
{
GLenum e;
GLint plogroom, slogroom;
GLchar *plog, *slog;
GLint logbytes;
GLint vsok;
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
if(fname == 0)
return reportShader();
if(0==strcmp(fname, "on")) {
shaderstuff.enabled = 1;
if(shaderstuff.prog == 0)
return "No shader loaded yet";
glUseProgram( shaderstuff.prog );
return reportShader();
} else if(0==strcmp(fname, "off")) {
shaderstuff.enabled = 0;
glUseProgram(0);
return reportShader();
}
const char *oldshader = shaderstuff.shadername;
shaderstuff.shadername = strdup(fname);
if(oldshader)
free((void *)oldshader);
if(shaderstuff.supported == ShaderStuff::UNKNOWN) {
return "shaders not yet initialized, will try later";
}
if(shaderstuff.supported != ShaderStuff::SUPPORTED) {
return reportShader();
}
if(shaderstuff.prog != 0) {
glUseProgram(0);
glDeleteProgram(shaderstuff.prog);
}
if(shaderstuff.vshad != 0) {
glDeleteShader(shaderstuff.vshad);
}
shaderstuff.vshad = glCreateShader(GL_VERTEX_SHADER);
const char *vf = inhalefile( shaderstuff.shadername, "partiview vertex shader" );
const char *vsrc = vf ? vf : default_vertshader;
glShaderSource( shaderstuff.vshad, 1, &vsrc, NULL );
if(vf) free((void *)vf);
glCompileShader( shaderstuff.vshad );
while((e = glGetError()) != 0) {
fprintf(stderr, "GLSL Vertex shader: %s (0x%x)\n", gluErrorString(e), e);
}
glGetShaderiv( shaderstuff.vshad, GL_INFO_LOG_LENGTH, &slogroom );
slog = (GLchar *)malloc( slogroom+1 );
glGetShaderInfoLog( shaderstuff.vshad, slogroom+1, &logbytes, slog );
fprintf(stderr, "Vertex shader log:\n%s\n", slog);
glGetShaderiv( shaderstuff.vshad, GL_COMPILE_STATUS, &vsok );
if(vsok == GL_TRUE) {
shaderstuff.prog = glCreateProgram();
glAttachShader(shaderstuff.prog, shaderstuff.vshad);
glLinkProgram( shaderstuff.prog );
while((e = glGetError()) != 0) {
fprintf(stderr, "GLSL shader program: %s (0x%x)\n", gluErrorString(e), e);
}
glGetProgramiv( shaderstuff.prog, GL_INFO_LOG_LENGTH, &plogroom );
plog = (GLchar *)malloc( plogroom+1 );
glGetProgramInfoLog( shaderstuff.prog, logbytes+1, &plogroom, plog );
fprintf(stderr, "Shader program log:\n%s\n", plog);
free(plog);
} else {
shaderstuff.vshad = 0;
shaderstuff.prog = 0;
if(shaderstuff.enabled && shaderstuff.prog != 0)
glUseProgram( shaderstuff.prog );
return reportShader();
}
#endif /* HAVE_LIBGLEW */