b23636c9 |
free(infoLog);
}
}
// Compile a shader, return reference to it
GLuint compileShaders(const char *vs, const char *fs, const char *gs, const char *tcs, const char *tes,
const char *vfn, const char *ffn, const char *gfn, const char *tcfn, const char *tefn)
{
GLuint v,f,g,tc,te,p;
v = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(v, 1, &vs, NULL);
glCompileShader(v);
if (fs != NULL)
{
f = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(f, 1, &fs, NULL);
glCompileShader(f);
}
if (gs != NULL)
{
g = glCreateShader(GL_GEOMETRY_SHADER);
glShaderSource(g, 1, &gs, NULL);
glCompileShader(g);
}
#ifdef GL_TESS_CONTROL_SHADER
if (tcs != NULL)
{
tc = glCreateShader(GL_TESS_CONTROL_SHADER);
glShaderSource(tc, 1, &tcs, NULL);
glCompileShader(tc);
}
if (tes != NULL)
{
te = glCreateShader(GL_TESS_EVALUATION_SHADER);
glShaderSource(te, 1, &tes, NULL);
glCompileShader(te);
}
#endif
p = glCreateProgram();
if (vs != NULL)
glAttachShader(p,v);
if (fs != NULL)
glAttachShader(p,f);
if (gs != NULL)
glAttachShader(p,g);
if (tcs != NULL)
glAttachShader(p,tc);
if (tes != NULL)
glAttachShader(p,te);
glLinkProgram(p);
glUseProgram(p);
if (vs != NULL) printShaderInfoLog(v, vfn);
if (fs != NULL) printShaderInfoLog(f, ffn);
if (gs != NULL) printShaderInfoLog(g, gfn);
if (tcs != NULL) printShaderInfoLog(tc, tcfn);
if (tes != NULL) printShaderInfoLog(te, tefn);
printProgramInfoLog(p, vfn, ffn, gfn, tcfn, tefn);
return p;
}
GLuint loadShaders(const char *vertFileName, const char *fragFileName)
{
return loadShadersGT(vertFileName, fragFileName, NULL, NULL, NULL);
}
GLuint loadShadersG(const char *vertFileName, const char *fragFileName, const char *geomFileName)
// With geometry shader support
{
return loadShadersGT(vertFileName, fragFileName, geomFileName, NULL, NULL);
}
GLuint loadShadersGT(const char *vertFileName, const char *fragFileName, const char *geomFileName,
const char *tcFileName, const char *teFileName)
// With tesselation shader support
{
char *vs, *fs, *gs, *tcs, *tes;
GLuint p = 0;
vs = readFile((char *)vertFileName);
fs = readFile((char *)fragFileName);
gs = readFile((char *)geomFileName);
tcs = readFile((char *)tcFileName);
tes = readFile((char *)teFileName);
if (vs==NULL)
fprintf(stderr, "Failed to read %s from disk.\n", vertFileName);
if (fs==NULL && (fragFileName != NULL))
fprintf(stderr, "Failed to read %s from disk.\n", fragFileName);
if ((gs==NULL) && (geomFileName != NULL))
fprintf(stderr, "Failed to read %s from disk.\n", geomFileName);
if ((tcs==NULL) && (tcFileName != NULL))
fprintf(stderr, "Failed to read %s from disk.\n", tcFileName);
if ((tes==NULL) && (teFileName != NULL))
fprintf(stderr, "Failed to read %s from disk.\n", teFileName);
if ((vs!=NULL)&&(fs!=NULL))
p = compileShaders(vs, fs, gs, tcs, tes, vertFileName, fragFileName, geomFileName, tcFileName, teFileName);
if (vs != NULL) free(vs);
if (fs != NULL) free(fs);
if (gs != NULL) free(gs);
if (tcs != NULL) free(tcs);
if (tes != NULL) free(tes);
return p;
}
// End of Shader loader
void dumpInfo(void)
{
printf ("Vendor: %s\n", glGetString (GL_VENDOR));
printf ("Renderer: %s\n", glGetString (GL_RENDERER));
printf ("Version: %s\n", glGetString (GL_VERSION));
printf ("GLSL: %s\n", glGetString (GL_SHADING_LANGUAGE_VERSION));
printError ("dumpInfo");
}
static GLenum lastError = 0;
static char lastErrorFunction[1024] = "";
/* report GL errors, if any, to stderr */
void printError(const char *functionName)
{
GLenum error;
while (( error = glGetError() ) != GL_NO_ERROR)
{
if ((lastError != error) || (strcmp(functionName, lastErrorFunction)))
{
fprintf (stderr, "GL error 0x%X detected in %s\n", error, functionName);
strcpy(lastErrorFunction, functionName);
lastError = error;
}
}
}
// FBO
//----------------------------------FBO functions-----------------------------------
void CHECK_FRAMEBUFFER_STATUS()
{
GLenum status;
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
fprintf(stderr, "Framebuffer not complete\n");
}
// create FBO
// FP buffer, suitable for HDR
FBOstruct *initFBO(int width, int height, int int_method)
{
FBOstruct *fbo = (FBOstruct *) malloc(sizeof(FBOstruct));
fbo->width = width;
fbo->height = height;
// create objects
glGenFramebuffers(1, &fbo->fb); // frame buffer id
glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
glGenTextures(1, &fbo->texid);
fprintf(stderr, "%i \n",fbo->texid);
glBindTexture(GL_TEXTURE_2D, fbo->texid);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
if (int_method == 0)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
else
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->texid, 0);
// Renderbuffer
// initialize depth renderbuffer
glGenRenderbuffers(1, &fbo->rb);
glBindRenderbuffer(GL_RENDERBUFFER, fbo->rb);
glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, fbo->width, fbo->height );
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo->rb );
CHECK_FRAMEBUFFER_STATUS();
fprintf(stderr, "Framebuffer object %d\n", fbo->fb);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return fbo;
}
// create FBO, optionally with depth
// Integer buffer, not suitable for HDR!
FBOstruct *initFBO2(int width, int height, int int_method, int create_depthimage)
{
FBOstruct *fbo = (FBOstruct *)malloc(sizeof(FBOstruct));
fbo->width = width;
fbo->height = height;
// create objects
glGenRenderbuffers(1, &fbo->rb);
glGenFramebuffers(1, &fbo->fb); // frame buffer id
glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
glGenTextures(1, &fbo->texid);
fprintf(stderr, "%i \n",fbo->texid);
glBindTexture(GL_TEXTURE_2D, fbo->texid);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
if (int_method == 0)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
else
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->texid, 0);
if (create_depthimage!=0)
{
glGenTextures(1, &fbo->depth);
glBindTexture(GL_TEXTURE_2D, fbo->depth);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0L);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, fbo->depth, 0);
fprintf(stderr, "depthtexture: %i\n",fbo->depth);
}
// Renderbuffer
// initialize depth renderbuffer
glBindRenderbuffer(GL_RENDERBUFFER, fbo->rb);
CHECK_FRAMEBUFFER_STATUS();
fprintf(stderr, "Framebuffer object %d\n", fbo->fb);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return fbo;
}
static int lastw = 0;
static int lasth = 0;
// Obsolete
void updateScreenSizeForFBOHandler(int w, int h)
{
lastw = w;
lasth = h;
}
// choose input (textures) and output (FBO)
void useFBO(FBOstruct *out, FBOstruct *in1, FBOstruct *in2)
{
GLint curfbo;
// This was supposed to catch changes in viewport size and update lastw/lasth.
// It worked for me in the past, but now it causes problems to I have to
// fall back to manual updating.
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &curfbo);
if (curfbo == 0)
{
GLint viewport[4] = {0,0,0,0};
GLint w, h;
glGetIntegerv(GL_VIEWPORT, viewport);
w = viewport[2] - viewport[0];
h = viewport[3] - viewport[1];
if ((w > 0) && (h > 0) && (w < 65536) && (h < 65536)) // I don't believe in 64k pixel wide frame buffers for quite some time
{
lastw = viewport[2] - viewport[0];
lasth = viewport[3] - viewport[1];
}
}
if (out != 0L)
glViewport(0, 0, out->width, out->height);
else
glViewport(0, 0, lastw, lasth);
if (out != 0L)
{
glBindFramebuffer(GL_FRAMEBUFFER, out->fb);
glViewport(0, 0, out->width, out->height);
}
else
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glActiveTexture(GL_TEXTURE1);
if (in2 != 0L)
glBindTexture(GL_TEXTURE_2D, in2->texid);
else
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0);
if (in1 != 0L)
glBindTexture(GL_TEXTURE_2D, in1->texid);
else
glBindTexture(GL_TEXTURE_2D, 0);
}
|