find . -type f -exec chmod -x {} +
Robert Cranston authored on 27/02/2024 02:27:27... | ... |
@@ -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 |
+} |