Browse code

Remove executable bit on files

find . -type f -exec chmod -x {} +

Robert Cranston authored on 27/02/2024 02:27:27
Showing 1 changed files
1 1
old mode 100755
2 2
new mode 100644
Browse code

Add cpp-v2

Ingemar Ragnemalm authored on 21/02/2024 20:24:29 • Robert Cranston committed on 21/02/2024 20:24:29
Showing 1 changed files
... ...
@@ -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-----------------------------------
Browse code

Add cpp-v1

Ingemar Ragnemalm authored on 21/02/2024 20:24:28 • Robert Cranston committed on 21/02/2024 20:24:28
Showing 1 changed files
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
+}