find . -type f -exec chmod -x {} +
| ... | ... |
@@ -15,6 +15,8 @@ |
| 15 | 15 |
// 200405: Added a few typecasts that were missing. |
| 16 | 16 |
// 210219: Shader errors are now visible on new VS19. |
| 17 | 17 |
// 210324: Compiling without fragment shader is now allowed |
| 18 |
+// 220113: Removed the last remains of VS support. Use a system that |
|
| 19 |
+// can handle printf! From now on, I will use CodeBlocks on Windows. |
|
| 18 | 20 |
|
| 19 | 21 |
//#define GL3_PROTOTYPES |
| 20 | 22 |
#ifdef WIN32 |
| ... | ... |
@@ -84,29 +86,24 @@ void printProgramInfoLog(GLuint obj, const char *vfn, const char *ffn, |
| 84 | 86 |
GLint infologLength = 0; |
| 85 | 87 |
GLint charsWritten = 0; |
| 86 | 88 |
char *infoLog; |
| 87 |
- char msg[2048] = "\n"; |
|
| 88 | 89 |
|
| 89 | 90 |
glGetProgramiv(obj, GL_INFO_LOG_LENGTH,&infologLength); |
| 90 | 91 |
|
| 91 | 92 |
if (infologLength > 2) |
| 92 | 93 |
{
|
| 93 | 94 |
if (ffn == NULL) |
| 94 |
- sprintf(msg, "[From %s:]\n", vfn); |
|
| 95 |
+ fprintf(stderr, "[From %s:]\n", vfn); |
|
| 95 | 96 |
else |
| 96 | 97 |
if (gfn == NULL) |
| 97 |
- sprintf(msg, "[From %s+%s:]\n", vfn, ffn); |
|
| 98 |
+ fprintf(stderr, "[From %s+%s:]\n", vfn, ffn); |
|
| 98 | 99 |
else |
| 99 | 100 |
if (tcfn == NULL || tefn == NULL) |
| 100 |
- sprintf(msg, "[From %s+%s+%s:]\n", vfn, ffn, gfn); |
|
| 101 |
+ fprintf(stderr, "[From %s+%s+%s:]\n", vfn, ffn, gfn); |
|
| 101 | 102 |
else |
| 102 |
- sprintf(msg, "[From %s+%s+%s+%s+%s:]\n", vfn, ffn, gfn, tcfn, tefn); |
|
| 103 |
- if (strlen(msg) > 1) |
|
| 104 |
- |
|
| 105 |
- fputs(msg, stderr); |
|
| 103 |
+ fprintf(stderr, "[From %s+%s+%s+%s+%s:]\n", vfn, ffn, gfn, tcfn, tefn); |
|
| 106 | 104 |
infoLog = (char *)malloc(infologLength); |
| 107 | 105 |
glGetProgramInfoLog(obj, infologLength, &charsWritten, infoLog); |
| 108 |
- fputs(infoLog, stderr); |
|
| 109 |
- fputs("\n", stderr);
|
|
| 106 |
+ fprintf(stderr, "%s\n",infoLog); |
|
| 110 | 107 |
free(infoLog); |
| 111 | 108 |
} |
| 112 | 109 |
} |
| ... | ... |
@@ -244,40 +241,6 @@ void printError(const char *functionName) |
| 244 | 241 |
} |
| 245 | 242 |
|
| 246 | 243 |
|
| 247 |
-/* |
|
| 248 |
- |
|
| 249 |
-// Keymap mini manager |
|
| 250 |
-// Important! Uses glutKeyboardFunc/glutKeyboardUpFunc so you can't use them |
|
| 251 |
-// elsewhere or they will conflict. |
|
| 252 |
-// (This functionality is built-in in MicroGlut, as "glutKeyIsDown" where this conflict should not exist.) |
|
| 253 |
- |
|
| 254 |
-char keymap[256]; |
|
| 255 |
- |
|
| 256 |
-char keyIsDown(unsigned char c) |
|
| 257 |
-{
|
|
| 258 |
- return keymap[(unsigned int)c]; |
|
| 259 |
-} |
|
| 260 |
- |
|
| 261 |
-void keyUp(unsigned char key, int x, int y) |
|
| 262 |
-{
|
|
| 263 |
- keymap[(unsigned int)key] = 0; |
|
| 264 |
-} |
|
| 265 |
- |
|
| 266 |
-void keyDown(unsigned char key, int x, int y) |
|
| 267 |
-{
|
|
| 268 |
- keymap[(unsigned int)key] = 1; |
|
| 269 |
-} |
|
| 270 |
- |
|
| 271 |
-void initKeymapManager() |
|
| 272 |
-{
|
|
| 273 |
- int i; |
|
| 274 |
- for (i = 0; i < 256; i++) keymap[i] = 0; |
|
| 275 |
- |
|
| 276 |
- glutKeyboardFunc(keyDown); |
|
| 277 |
- glutKeyboardUpFunc(keyUp); |
|
| 278 |
-} |
|
| 279 |
-*/ |
|
| 280 |
- |
|
| 281 | 244 |
// FBO |
| 282 | 245 |
|
| 283 | 246 |
//----------------------------------FBO functions----------------------------------- |
| 1 | 1 |
new file mode 100755 |
| ... | ... |
@@ -0,0 +1,445 @@ |
| 1 |
+// GL utilities, bare essentials |
|
| 2 |
+// By Ingemar Ragnemalm |
|
| 3 |
+ |
|
| 4 |
+// August 2012: |
|
| 5 |
+// FBO creation/usage routines. |
|
| 6 |
+// Geometry shader support synched with preliminary version. |
|
| 7 |
+// September 2012: Improved infolog printouts with file names. |
|
| 8 |
+// 120910: Clarified error messages from shader loader. |
|
| 9 |
+// 120913: Re-activated automatic framebuffer checks for UseFBO(). |
|
| 10 |
+// Fixed FUBAR in InitFBO(). |
|
| 11 |
+// 130228: Changed most printf's to stderr. |
|
| 12 |
+// 131014: Added tesselation shader support |
|
| 13 |
+// 150812: Added a NULL check on file names in readFile, makes Visual Studio happier. |
|
| 14 |
+// 160302: Uses fopen_s on Windows, as suggested by Jesper Post. Should reduce warnings a bit. |
|
| 15 |
+// 200405: Added a few typecasts that were missing. |
|
| 16 |
+// 210219: Shader errors are now visible on new VS19. |
|
| 17 |
+// 210324: Compiling without fragment shader is now allowed |
|
| 18 |
+ |
|
| 19 |
+//#define GL3_PROTOTYPES |
|
| 20 |
+#ifdef WIN32 |
|
| 21 |
+#include <Windows.h> |
|
| 22 |
+#endif |
|
| 23 |
+#include <stdlib.h> |
|
| 24 |
+#include <stdio.h> |
|
| 25 |
+#include <stddef.h> |
|
| 26 |
+#include <string.h> |
|
| 27 |
+ |
|
| 28 |
+#include "GL_utilities.h" |
|
| 29 |
+ |
|
| 30 |
+// Shader loader |
|
| 31 |
+ |
|
| 32 |
+char* readFile(char *file) |
|
| 33 |
+{
|
|
| 34 |
+ FILE *fptr; |
|
| 35 |
+ long length; |
|
| 36 |
+ char *buf; |
|
| 37 |
+ |
|
| 38 |
+ if (file == NULL) |
|
| 39 |
+ return NULL; |
|
| 40 |
+ |
|
| 41 |
+ // It seems Windows/VS doesn't like fopen any more, but fopen_s is not on the others. |
|
| 42 |
+ #if defined(_WIN32) |
|
| 43 |
+ fopen_s(&fptr, file, "r"); |
|
| 44 |
+ #else |
|
| 45 |
+ fptr = fopen(file, "rb"); // rw works everywhere except Windows? |
|
| 46 |
+ #endif |
|
| 47 |
+// fptr = fopen(file, "rb"); /* Open file for reading */ |
|
| 48 |
+ if (!fptr) /* Return NULL on failure */ |
|
| 49 |
+ return NULL; |
|
| 50 |
+ fseek(fptr, 0, SEEK_END); /* Seek to the end of the file */ |
|
| 51 |
+ length = ftell(fptr); /* Find out how many bytes into the file we are */ |
|
| 52 |
+ buf = (char*)malloc(length+1); /* Allocate a buffer for the entire length of the file and a null terminator */ |
|
| 53 |
+ memset(buf, 0, sizeof(char)*(length + 1)); /* Clean the buffer - suggested for safety by Mateusz 2016 */ |
|
| 54 |
+ fseek(fptr, 0, SEEK_SET); /* Go back to the beginning of the file */ |
|
| 55 |
+ fread(buf, length, 1, fptr); /* Read the contents of the file in to the buffer */ |
|
| 56 |
+ fclose(fptr); /* Close the file */ |
|
| 57 |
+ buf[length] = 0; /* Null terminator */ |
|
| 58 |
+ |
|
| 59 |
+ return buf; /* Return the buffer */ |
|
| 60 |
+} |
|
| 61 |
+ |
|
| 62 |
+// Infolog: Show result of shader compilation |
|
| 63 |
+void printShaderInfoLog(GLuint obj, const char *fn) |
|
| 64 |
+{
|
|
| 65 |
+ GLint infologLength = 0; |
|
| 66 |
+ GLint charsWritten = 0; |
|
| 67 |
+ char *infoLog; |
|
| 68 |
+ |
|
| 69 |
+ glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &infologLength); |
|
| 70 |
+ |
|
| 71 |
+ if (infologLength > 2) |
|
| 72 |
+ {
|
|
| 73 |
+ fprintf(stderr, "[From %s:]\n", fn); |
|
| 74 |
+ infoLog = (char *)malloc(infologLength); |
|
| 75 |
+ glGetShaderInfoLog(obj, infologLength, &charsWritten, infoLog); |
|
| 76 |
+ fprintf(stderr, "[From %s:]\n", infoLog); |
|
| 77 |
+ free(infoLog); |
|
| 78 |
+ } |
|
| 79 |
+} |
|
| 80 |
+ |
|
| 81 |
+void printProgramInfoLog(GLuint obj, const char *vfn, const char *ffn, |
|
| 82 |
+ const char *gfn, const char *tcfn, const char *tefn) |
|
| 83 |
+{
|
|
| 84 |
+ GLint infologLength = 0; |
|
| 85 |
+ GLint charsWritten = 0; |
|
| 86 |
+ char *infoLog; |
|
| 87 |
+ char msg[2048] = "\n"; |
|
| 88 |
+ |
|
| 89 |
+ glGetProgramiv(obj, GL_INFO_LOG_LENGTH,&infologLength); |
|
| 90 |
+ |
|
| 91 |
+ if (infologLength > 2) |
|
| 92 |
+ {
|
|
| 93 |
+ if (ffn == NULL) |
|
| 94 |
+ sprintf(msg, "[From %s:]\n", vfn); |
|
| 95 |
+ else |
|
| 96 |
+ if (gfn == NULL) |
|
| 97 |
+ sprintf(msg, "[From %s+%s:]\n", vfn, ffn); |
|
| 98 |
+ else |
|
| 99 |
+ if (tcfn == NULL || tefn == NULL) |
|
| 100 |
+ sprintf(msg, "[From %s+%s+%s:]\n", vfn, ffn, gfn); |
|
| 101 |
+ else |
|
| 102 |
+ sprintf(msg, "[From %s+%s+%s+%s+%s:]\n", vfn, ffn, gfn, tcfn, tefn); |
|
| 103 |
+ if (strlen(msg) > 1) |
|
| 104 |
+ |
|
| 105 |
+ fputs(msg, stderr); |
|
| 106 |
+ infoLog = (char *)malloc(infologLength); |
|
| 107 |
+ glGetProgramInfoLog(obj, infologLength, &charsWritten, infoLog); |
|
| 108 |
+ fputs(infoLog, stderr); |
|
| 109 |
+ fputs("\n", stderr);
|
|
| 110 |
+ free(infoLog); |
|
| 111 |
+ } |
|
| 112 |
+} |
|
| 113 |
+ |
|
| 114 |
+// Compile a shader, return reference to it |
|
| 115 |
+GLuint compileShaders(const char *vs, const char *fs, const char *gs, const char *tcs, const char *tes, |
|
| 116 |
+ const char *vfn, const char *ffn, const char *gfn, const char *tcfn, const char *tefn) |
|
| 117 |
+{
|
|
| 118 |
+ GLuint v,f,g,tc,te,p; |
|
| 119 |
+ |
|
| 120 |
+ v = glCreateShader(GL_VERTEX_SHADER); |
|
| 121 |
+ glShaderSource(v, 1, &vs, NULL); |
|
| 122 |
+ glCompileShader(v); |
|
| 123 |
+ if (fs != NULL) |
|
| 124 |
+ {
|
|
| 125 |
+ f = glCreateShader(GL_FRAGMENT_SHADER); |
|
| 126 |
+ glShaderSource(f, 1, &fs, NULL); |
|
| 127 |
+ glCompileShader(f); |
|
| 128 |
+ } |
|
| 129 |
+ if (gs != NULL) |
|
| 130 |
+ {
|
|
| 131 |
+ g = glCreateShader(GL_GEOMETRY_SHADER); |
|
| 132 |
+ glShaderSource(g, 1, &gs, NULL); |
|
| 133 |
+ glCompileShader(g); |
|
| 134 |
+ } |
|
| 135 |
+#ifdef GL_TESS_CONTROL_SHADER |
|
| 136 |
+ if (tcs != NULL) |
|
| 137 |
+ {
|
|
| 138 |
+ tc = glCreateShader(GL_TESS_CONTROL_SHADER); |
|
| 139 |
+ glShaderSource(tc, 1, &tcs, NULL); |
|
| 140 |
+ glCompileShader(tc); |
|
| 141 |
+ } |
|
| 142 |
+ if (tes != NULL) |
|
| 143 |
+ {
|
|
| 144 |
+ te = glCreateShader(GL_TESS_EVALUATION_SHADER); |
|
| 145 |
+ glShaderSource(te, 1, &tes, NULL); |
|
| 146 |
+ glCompileShader(te); |
|
| 147 |
+ } |
|
| 148 |
+#endif |
|
| 149 |
+ p = glCreateProgram(); |
|
| 150 |
+ if (vs != NULL) |
|
| 151 |
+ glAttachShader(p,v); |
|
| 152 |
+ if (fs != NULL) |
|
| 153 |
+ glAttachShader(p,f); |
|
| 154 |
+ if (gs != NULL) |
|
| 155 |
+ glAttachShader(p,g); |
|
| 156 |
+ if (tcs != NULL) |
|
| 157 |
+ glAttachShader(p,tc); |
|
| 158 |
+ if (tes != NULL) |
|
| 159 |
+ glAttachShader(p,te); |
|
| 160 |
+ glLinkProgram(p); |
|
| 161 |
+ glUseProgram(p); |
|
| 162 |
+ |
|
| 163 |
+ if (vs != NULL) printShaderInfoLog(v, vfn); |
|
| 164 |
+ if (fs != NULL) printShaderInfoLog(f, ffn); |
|
| 165 |
+ if (gs != NULL) printShaderInfoLog(g, gfn); |
|
| 166 |
+ if (tcs != NULL) printShaderInfoLog(tc, tcfn); |
|
| 167 |
+ if (tes != NULL) printShaderInfoLog(te, tefn); |
|
| 168 |
+ |
|
| 169 |
+ printProgramInfoLog(p, vfn, ffn, gfn, tcfn, tefn); |
|
| 170 |
+ |
|
| 171 |
+ return p; |
|
| 172 |
+} |
|
| 173 |
+ |
|
| 174 |
+GLuint loadShaders(const char *vertFileName, const char *fragFileName) |
|
| 175 |
+{
|
|
| 176 |
+ return loadShadersGT(vertFileName, fragFileName, NULL, NULL, NULL); |
|
| 177 |
+} |
|
| 178 |
+ |
|
| 179 |
+GLuint loadShadersG(const char *vertFileName, const char *fragFileName, const char *geomFileName) |
|
| 180 |
+// With geometry shader support |
|
| 181 |
+{
|
|
| 182 |
+ return loadShadersGT(vertFileName, fragFileName, geomFileName, NULL, NULL); |
|
| 183 |
+} |
|
| 184 |
+ |
|
| 185 |
+GLuint loadShadersGT(const char *vertFileName, const char *fragFileName, const char *geomFileName, |
|
| 186 |
+ const char *tcFileName, const char *teFileName) |
|
| 187 |
+// With tesselation shader support |
|
| 188 |
+{
|
|
| 189 |
+ char *vs, *fs, *gs, *tcs, *tes; |
|
| 190 |
+ GLuint p = 0; |
|
| 191 |
+ |
|
| 192 |
+ vs = readFile((char *)vertFileName); |
|
| 193 |
+ fs = readFile((char *)fragFileName); |
|
| 194 |
+ gs = readFile((char *)geomFileName); |
|
| 195 |
+ tcs = readFile((char *)tcFileName); |
|
| 196 |
+ tes = readFile((char *)teFileName); |
|
| 197 |
+ if (vs==NULL) |
|
| 198 |
+ fprintf(stderr, "Failed to read %s from disk.\n", vertFileName); |
|
| 199 |
+ if (fs==NULL && (fragFileName != NULL)) |
|
| 200 |
+ fprintf(stderr, "Failed to read %s from disk.\n", fragFileName); |
|
| 201 |
+ if ((gs==NULL) && (geomFileName != NULL)) |
|
| 202 |
+ fprintf(stderr, "Failed to read %s from disk.\n", geomFileName); |
|
| 203 |
+ if ((tcs==NULL) && (tcFileName != NULL)) |
|
| 204 |
+ fprintf(stderr, "Failed to read %s from disk.\n", tcFileName); |
|
| 205 |
+ if ((tes==NULL) && (teFileName != NULL)) |
|
| 206 |
+ fprintf(stderr, "Failed to read %s from disk.\n", teFileName); |
|
| 207 |
+ if ((vs!=NULL)&&(fs!=NULL)) |
|
| 208 |
+ p = compileShaders(vs, fs, gs, tcs, tes, vertFileName, fragFileName, geomFileName, tcFileName, teFileName); |
|
| 209 |
+ if (vs != NULL) free(vs); |
|
| 210 |
+ if (fs != NULL) free(fs); |
|
| 211 |
+ if (gs != NULL) free(gs); |
|
| 212 |
+ if (tcs != NULL) free(tcs); |
|
| 213 |
+ if (tes != NULL) free(tes); |
|
| 214 |
+ return p; |
|
| 215 |
+} |
|
| 216 |
+ |
|
| 217 |
+// End of Shader loader |
|
| 218 |
+ |
|
| 219 |
+void dumpInfo(void) |
|
| 220 |
+{
|
|
| 221 |
+ printf ("Vendor: %s\n", glGetString (GL_VENDOR));
|
|
| 222 |
+ printf ("Renderer: %s\n", glGetString (GL_RENDERER));
|
|
| 223 |
+ printf ("Version: %s\n", glGetString (GL_VERSION));
|
|
| 224 |
+ printf ("GLSL: %s\n", glGetString (GL_SHADING_LANGUAGE_VERSION));
|
|
| 225 |
+ printError ("dumpInfo");
|
|
| 226 |
+} |
|
| 227 |
+ |
|
| 228 |
+static GLenum lastError = 0; |
|
| 229 |
+static char lastErrorFunction[1024] = ""; |
|
| 230 |
+ |
|
| 231 |
+/* report GL errors, if any, to stderr */ |
|
| 232 |
+void printError(const char *functionName) |
|
| 233 |
+{
|
|
| 234 |
+ GLenum error; |
|
| 235 |
+ while (( error = glGetError() ) != GL_NO_ERROR) |
|
| 236 |
+ {
|
|
| 237 |
+ if ((lastError != error) || (strcmp(functionName, lastErrorFunction))) |
|
| 238 |
+ {
|
|
| 239 |
+ fprintf (stderr, "GL error 0x%X detected in %s\n", error, functionName); |
|
| 240 |
+ strcpy(lastErrorFunction, functionName); |
|
| 241 |
+ lastError = error; |
|
| 242 |
+ } |
|
| 243 |
+ } |
|
| 244 |
+} |
|
| 245 |
+ |
|
| 246 |
+ |
|
| 247 |
+/* |
|
| 248 |
+ |
|
| 249 |
+// Keymap mini manager |
|
| 250 |
+// Important! Uses glutKeyboardFunc/glutKeyboardUpFunc so you can't use them |
|
| 251 |
+// elsewhere or they will conflict. |
|
| 252 |
+// (This functionality is built-in in MicroGlut, as "glutKeyIsDown" where this conflict should not exist.) |
|
| 253 |
+ |
|
| 254 |
+char keymap[256]; |
|
| 255 |
+ |
|
| 256 |
+char keyIsDown(unsigned char c) |
|
| 257 |
+{
|
|
| 258 |
+ return keymap[(unsigned int)c]; |
|
| 259 |
+} |
|
| 260 |
+ |
|
| 261 |
+void keyUp(unsigned char key, int x, int y) |
|
| 262 |
+{
|
|
| 263 |
+ keymap[(unsigned int)key] = 0; |
|
| 264 |
+} |
|
| 265 |
+ |
|
| 266 |
+void keyDown(unsigned char key, int x, int y) |
|
| 267 |
+{
|
|
| 268 |
+ keymap[(unsigned int)key] = 1; |
|
| 269 |
+} |
|
| 270 |
+ |
|
| 271 |
+void initKeymapManager() |
|
| 272 |
+{
|
|
| 273 |
+ int i; |
|
| 274 |
+ for (i = 0; i < 256; i++) keymap[i] = 0; |
|
| 275 |
+ |
|
| 276 |
+ glutKeyboardFunc(keyDown); |
|
| 277 |
+ glutKeyboardUpFunc(keyUp); |
|
| 278 |
+} |
|
| 279 |
+*/ |
|
| 280 |
+ |
|
| 281 |
+// FBO |
|
| 282 |
+ |
|
| 283 |
+//----------------------------------FBO functions----------------------------------- |
|
| 284 |
+void CHECK_FRAMEBUFFER_STATUS() |
|
| 285 |
+{
|
|
| 286 |
+ GLenum status; |
|
| 287 |
+ status = glCheckFramebufferStatus(GL_FRAMEBUFFER); |
|
| 288 |
+ if (status != GL_FRAMEBUFFER_COMPLETE) |
|
| 289 |
+ fprintf(stderr, "Framebuffer not complete\n"); |
|
| 290 |
+} |
|
| 291 |
+ |
|
| 292 |
+// create FBO |
|
| 293 |
+// FP buffer, suitable for HDR |
|
| 294 |
+FBOstruct *initFBO(int width, int height, int int_method) |
|
| 295 |
+{
|
|
| 296 |
+ FBOstruct *fbo = (FBOstruct *) malloc(sizeof(FBOstruct)); |
|
| 297 |
+ |
|
| 298 |
+ fbo->width = width; |
|
| 299 |
+ fbo->height = height; |
|
| 300 |
+ |
|
| 301 |
+ // create objects |
|
| 302 |
+ glGenFramebuffers(1, &fbo->fb); // frame buffer id |
|
| 303 |
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb); |
|
| 304 |
+ glGenTextures(1, &fbo->texid); |
|
| 305 |
+ fprintf(stderr, "%i \n",fbo->texid); |
|
| 306 |
+ glBindTexture(GL_TEXTURE_2D, fbo->texid); |
|
| 307 |
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); |
|
| 308 |
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); |
|
| 309 |
+ if (int_method == 0) |
|
| 310 |
+ {
|
|
| 311 |
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
|
| 312 |
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
|
| 313 |
+ } |
|
| 314 |
+ else |
|
| 315 |
+ {
|
|
| 316 |
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
|
| 317 |
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
|
| 318 |
+ } |
|
| 319 |
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); |
|
| 320 |
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->texid, 0); |
|
| 321 |
+ |
|
| 322 |
+ // Renderbuffer |
|
| 323 |
+ // initialize depth renderbuffer |
|
| 324 |
+ glGenRenderbuffers(1, &fbo->rb); |
|
| 325 |
+ glBindRenderbuffer(GL_RENDERBUFFER, fbo->rb); |
|
| 326 |
+ glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, fbo->width, fbo->height ); |
|
| 327 |
+ glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo->rb ); |
|
| 328 |
+ CHECK_FRAMEBUFFER_STATUS(); |
|
| 329 |
+ |
|
| 330 |
+ fprintf(stderr, "Framebuffer object %d\n", fbo->fb); |
|
| 331 |
+ glBindFramebuffer(GL_FRAMEBUFFER, 0); |
|
| 332 |
+ return fbo; |
|
| 333 |
+} |
|
| 334 |
+ |
|
| 335 |
+// create FBO, optionally with depth |
|
| 336 |
+// Integer buffer, not suitable for HDR! |
|
| 337 |
+FBOstruct *initFBO2(int width, int height, int int_method, int create_depthimage) |
|
| 338 |
+{
|
|
| 339 |
+ FBOstruct *fbo = (FBOstruct *)malloc(sizeof(FBOstruct)); |
|
| 340 |
+ |
|
| 341 |
+ fbo->width = width; |
|
| 342 |
+ fbo->height = height; |
|
| 343 |
+ |
|
| 344 |
+ // create objects |
|
| 345 |
+ glGenRenderbuffers(1, &fbo->rb); |
|
| 346 |
+ glGenFramebuffers(1, &fbo->fb); // frame buffer id |
|
| 347 |
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb); |
|
| 348 |
+ glGenTextures(1, &fbo->texid); |
|
| 349 |
+ fprintf(stderr, "%i \n",fbo->texid); |
|
| 350 |
+ glBindTexture(GL_TEXTURE_2D, fbo->texid); |
|
| 351 |
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); |
|
| 352 |
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); |
|
| 353 |
+ if (int_method == 0) |
|
| 354 |
+ {
|
|
| 355 |
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
|
| 356 |
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
|
| 357 |
+ } |
|
| 358 |
+ else |
|
| 359 |
+ {
|
|
| 360 |
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
|
| 361 |
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
|
| 362 |
+ } |
|
| 363 |
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); |
|
| 364 |
+ |
|
| 365 |
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->texid, 0); |
|
| 366 |
+ if (create_depthimage!=0) |
|
| 367 |
+ {
|
|
| 368 |
+ glGenTextures(1, &fbo->depth); |
|
| 369 |
+ glBindTexture(GL_TEXTURE_2D, fbo->depth); |
|
| 370 |
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0L); |
|
| 371 |
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
|
| 372 |
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
|
| 373 |
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
|
| 374 |
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
|
| 375 |
+ glBindTexture(GL_TEXTURE_2D, 0); |
|
| 376 |
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, fbo->depth, 0); |
|
| 377 |
+ fprintf(stderr, "depthtexture: %i\n",fbo->depth); |
|
| 378 |
+ } |
|
| 379 |
+ |
|
| 380 |
+ // Renderbuffer |
|
| 381 |
+ // initialize depth renderbuffer |
|
| 382 |
+ glBindRenderbuffer(GL_RENDERBUFFER, fbo->rb); |
|
| 383 |
+ CHECK_FRAMEBUFFER_STATUS(); |
|
| 384 |
+ |
|
| 385 |
+ fprintf(stderr, "Framebuffer object %d\n", fbo->fb); |
|
| 386 |
+ glBindFramebuffer(GL_FRAMEBUFFER, 0); |
|
| 387 |
+ return fbo; |
|
| 388 |
+} |
|
| 389 |
+ |
|
| 390 |
+static int lastw = 0; |
|
| 391 |
+static int lasth = 0; |
|
| 392 |
+ |
|
| 393 |
+// Obsolete |
|
| 394 |
+void updateScreenSizeForFBOHandler(int w, int h) |
|
| 395 |
+{
|
|
| 396 |
+ lastw = w; |
|
| 397 |
+ lasth = h; |
|
| 398 |
+} |
|
| 399 |
+ |
|
| 400 |
+// choose input (textures) and output (FBO) |
|
| 401 |
+void useFBO(FBOstruct *out, FBOstruct *in1, FBOstruct *in2) |
|
| 402 |
+{
|
|
| 403 |
+ GLint curfbo; |
|
| 404 |
+ |
|
| 405 |
+// This was supposed to catch changes in viewport size and update lastw/lasth. |
|
| 406 |
+// It worked for me in the past, but now it causes problems to I have to |
|
| 407 |
+// fall back to manual updating. |
|
| 408 |
+ glGetIntegerv(GL_FRAMEBUFFER_BINDING, &curfbo); |
|
| 409 |
+ if (curfbo == 0) |
|
| 410 |
+ {
|
|
| 411 |
+ GLint viewport[4] = {0,0,0,0};
|
|
| 412 |
+ GLint w, h; |
|
| 413 |
+ glGetIntegerv(GL_VIEWPORT, viewport); |
|
| 414 |
+ w = viewport[2] - viewport[0]; |
|
| 415 |
+ h = viewport[3] - viewport[1]; |
|
| 416 |
+ if ((w > 0) && (h > 0) && (w < 65536) && (h < 65536)) // I don't believe in 64k pixel wide frame buffers for quite some time |
|
| 417 |
+ {
|
|
| 418 |
+ lastw = viewport[2] - viewport[0]; |
|
| 419 |
+ lasth = viewport[3] - viewport[1]; |
|
| 420 |
+ } |
|
| 421 |
+ } |
|
| 422 |
+ |
|
| 423 |
+ if (out != 0L) |
|
| 424 |
+ glViewport(0, 0, out->width, out->height); |
|
| 425 |
+ else |
|
| 426 |
+ glViewport(0, 0, lastw, lasth); |
|
| 427 |
+ |
|
| 428 |
+ if (out != 0L) |
|
| 429 |
+ {
|
|
| 430 |
+ glBindFramebuffer(GL_FRAMEBUFFER, out->fb); |
|
| 431 |
+ glViewport(0, 0, out->width, out->height); |
|
| 432 |
+ } |
|
| 433 |
+ else |
|
| 434 |
+ glBindFramebuffer(GL_FRAMEBUFFER, 0); |
|
| 435 |
+ glActiveTexture(GL_TEXTURE1); |
|
| 436 |
+ if (in2 != 0L) |
|
| 437 |
+ glBindTexture(GL_TEXTURE_2D, in2->texid); |
|
| 438 |
+ else |
|
| 439 |
+ glBindTexture(GL_TEXTURE_2D, 0); |
|
| 440 |
+ glActiveTexture(GL_TEXTURE0); |
|
| 441 |
+ if (in1 != 0L) |
|
| 442 |
+ glBindTexture(GL_TEXTURE_2D, in1->texid); |
|
| 443 |
+ else |
|
| 444 |
+ glBindTexture(GL_TEXTURE_2D, 0); |
|
| 445 |
+} |