1 /*
2  * Copyright (c) 2011 VMware, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * on the rights to use, copy, modify, merge, publish, distribute, sub
8  * license, and/or sell copies of the Software, and to permit persons to whom
9  * the Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NON-INFRINGEMENT.  IN NO EVENT SHALL VMWARE AND/OR THEIR SUPPLIERS
19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 
25 
26 /**
27  * @file getteximage-formats.c
28  *
29  * Test glGetTexImage with a variety of formats.
30  * Brian Paul
31  * Sep 2011
32  */
33 
34 
35 #include "piglit-util-gl.h"
36 #include "../fbo/fbo-formats.h"
37 
38 PIGLIT_GL_TEST_CONFIG_BEGIN
39 
40 	config.supports_gl_compat_version = 10;
41 
42 	config.window_width = 600;
43 	config.window_height = 200;
44 	config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
45 	config.khr_no_error_support = PIGLIT_NO_ERRORS;
46 
47 PIGLIT_GL_TEST_CONFIG_END
48 
49 static const char *TestName = "getteximage-formats";
50 
51 static const GLfloat clearColor[4] = { 0.4, 0.4, 0.4, 0.0 };
52 static GLuint texture_id;
53 static GLboolean init_by_rendering;
54 static GLboolean init_by_clearing_first;
55 
56 #define TEX_SIZE 128
57 
58 #define DO_BLEND 1
59 
60 
61 /**
62  * Make a simple texture image where red increases from left to right,
63  * green increases from bottom to top, blue stays constant (50%) and
64  * the alpha channel is a checkerboard pattern.
65  * \return GL_TRUE for success, GL_FALSE if unsupported format
66  */
67 static GLboolean
make_texture_image(GLenum intFormat,GLubyte upperRightTexel[4])68 make_texture_image(GLenum intFormat, GLubyte upperRightTexel[4])
69 {
70 	GLubyte tex[TEX_SIZE][TEX_SIZE][4];
71 	int i, j;
72 	GLuint fb, status;
73 
74 	for (i = 0; i < TEX_SIZE; i++) {
75 		for (j = 0; j < TEX_SIZE; j++) {
76 			tex[i][j][0] = j * 255 / TEX_SIZE;
77 			tex[i][j][1] = i * 255 / TEX_SIZE;
78 			tex[i][j][2] = 128;
79 			if (((i >> 4) ^ (j >> 4)) & 1)
80 				tex[i][j][3] = 255;  /* opaque */
81 			else
82 				tex[i][j][3] = 125;	/* transparent */
83 		}
84 	}
85 
86 	memcpy(upperRightTexel, tex[TEX_SIZE-1][TEX_SIZE-1], 4);
87 
88 	if (init_by_rendering || init_by_clearing_first) {
89 		/* Initialize the mipmap levels. */
90 		for (i = TEX_SIZE, j = 0; i; i >>= 1, j++) {
91 			glTexImage2D(GL_TEXTURE_2D, j, intFormat, i, i, 0,
92 				     GL_RGBA, GL_UNSIGNED_BYTE, NULL);
93 		}
94 
95 		/* Initialize the texture with glDrawPixels. */
96 		glGenFramebuffers(1, &fb);
97 		glBindFramebuffer(GL_FRAMEBUFFER, fb);
98 		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
99 				       GL_TEXTURE_2D, texture_id, 0);
100 		status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
101 		if (status != GL_FRAMEBUFFER_COMPLETE) {
102 			glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo);
103 			glDeleteFramebuffers(1, &fb);
104 			return GL_FALSE;
105 		}
106 
107 		if (init_by_clearing_first) {
108 			glClearColor(1, 0, 0, 1);
109 			glClear(GL_COLOR_BUFFER_BIT);
110 		}
111 
112 		glViewport(0, 0, TEX_SIZE, TEX_SIZE);
113 
114 		/* Disable dithering during glDrawPixels to prevent
115 		 * disagreement with glGenerateMipmap.  The spec requires
116 		 * glDrawPixels to respect the dither state, but the spec
117 		 * strongly implies that glGenerateMipmap should not dither.
118 		 *
119 		 * On dithering and glDrawPixels, see the OpenGL 4.5
120 		 * Compatibility Specification, Section 18.1 Drawing Pixels,
121 		 * p620:
122 		 *
123 		 *   Once pixels are transferred, DrawPixels performs final
124 		 *   conversion on pixel values [...] which are processed in
125 		 *   the same fashion as fragments generated by rasterization
126 		 *   (see chapters 15 and 16).
127 		 *
128 		 * On dithering and glGenerateMipmap, see the Mesa commit
129 		 * message in:
130 		 *
131 		 *   commit c4b87f129eb036c9615df3adcc1cebd9df10fc84
132 		 *   Author: Chad Versace <chadversary@chromium.org>
133 		 *   Date:   Thu Dec 29 13:05:27 2016 -0800
134 		 *   Subject: meta: Disable dithering during glGenerateMipmap
135 		 */
136 		glDisable(GL_DITHER);
137 		glWindowPos2iARB(0, 0);
138 		glDrawPixels(TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, tex);
139 		glEnable(GL_DITHER);
140 
141 		glGenerateMipmap(GL_TEXTURE_2D);
142 
143 		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo);
144 		glDeleteFramebuffers(1, &fb);
145 		glViewport(0, 0, piglit_width, piglit_height);
146 	}
147 	else {
148 		glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
149 		glTexImage2D(GL_TEXTURE_2D, 0, intFormat, TEX_SIZE, TEX_SIZE, 0,
150 			     GL_RGBA, GL_UNSIGNED_BYTE, tex);
151 	}
152 
153 	return glGetError() == GL_NO_ERROR;
154 }
155 
156 static GLfloat
ubyte_to_float(GLubyte b,GLint bits)157 ubyte_to_float(GLubyte b, GLint bits)
158 {
159 	if (bits <= 8) {
160 		GLint b2 = b >> (8 - bits);
161 		GLint max = 255 >> (8 - bits);
162 		return b2 / (float) max;
163 	}
164 	else {
165 		return b / 255.0;
166 	}
167 }
168 
169 
170 
171 static GLfloat
bits_to_tolerance(GLint bits,GLboolean compressed)172 bits_to_tolerance(GLint bits, GLboolean compressed)
173 {
174 	GLfloat t;
175 
176 	if (bits == 0) {
177 		return 0.25;
178 	}
179 	else if (bits == 1) {
180 		return 0.5;
181 	}
182 	else if (bits > 8) {
183 		/* The original texture was specified as GLubyte and we
184 		 * assume that the window/surface is 8-bits/channel.
185 		 */
186 		t = 4.0 / 255;
187 	}
188 	else {
189 		t = 4.0 / (1 << (bits - 1));
190 	}
191 
192 	if (compressed) {
193 		/* Use a fudge factor.  The queries for GL_TEXTURE_RED/
194 		 * GREEN/BLUE/ALPHA_SIZE don't return well-defined values for
195 		 * compressed formats so using them is unreliable.  This is
196 		 * pretty loose, but good enough to catch some Mesa bugs during
197 		 * development.
198 		 */
199 		t = 0.3;
200 	}
201 	return t;
202 }
203 
204 
205 static void
compute_expected_color(const struct format_desc * fmt,const GLubyte upperRightTexel[4],GLfloat expected[4],GLfloat tolerance[4])206 compute_expected_color(const struct format_desc *fmt,
207 		       const GLubyte upperRightTexel[4],
208 		       GLfloat expected[4], GLfloat tolerance[4])
209 {
210 	GLfloat texel[4];
211 	GLint compressed;
212 	int bits[4];
213 
214 	bits[0] = bits[1] = bits[2] = bits[3] = 0;
215 
216 	/* Handle special cases first */
217 	if (fmt->internalformat == GL_R11F_G11F_B10F_EXT) {
218 		bits[0] = bits[1] = bits[2] = 8;
219 		bits[3] = 0;
220 		texel[0] = ubyte_to_float(upperRightTexel[0], bits[0]);
221 		texel[1] = ubyte_to_float(upperRightTexel[1], bits[1]);
222 		texel[2] = ubyte_to_float(upperRightTexel[2], bits[2]);
223 		texel[3] = 1.0;
224 		compressed = GL_FALSE;
225 	}
226 	else {
227 		GLint r, g, b, a, l, i;
228 		GLenum baseFormat = 0;
229 
230 		glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &r);
231 		glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_SIZE, &g);
232 		glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BLUE_SIZE, &b);
233 		glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &a);
234 		glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_LUMINANCE_SIZE, &l);
235 		glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTENSITY_SIZE, &i);
236 		glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, &compressed);
237 
238 		if (0)
239 			printf("r=%d g=%d b=%d a=%d l=%d i=%d\n", r, g, b, a, l, i);
240 
241 		if (i > 0) {
242 			baseFormat = GL_INTENSITY;
243 			bits[0] = i;
244 			bits[1] = 0;
245 			bits[2] = 0;
246 			bits[3] = i;
247 			texel[0] = ubyte_to_float(upperRightTexel[0], bits[0]);
248 			texel[1] = 0.0;
249 			texel[2] = 0.0;
250 			texel[3] = ubyte_to_float(upperRightTexel[0], bits[3]);
251 		}
252 		else if (a > 0) {
253 			if (l > 0) {
254 				baseFormat = GL_LUMINANCE_ALPHA;
255 				bits[0] = l;
256 				bits[1] = 0;
257 				bits[2] = 0;
258 				bits[3] = a;
259 				texel[0] = ubyte_to_float(upperRightTexel[0], bits[0]);
260 				texel[1] = 0.0;
261 				texel[2] = 0.0;
262 				texel[3] = ubyte_to_float(upperRightTexel[3], bits[3]);
263 			}
264 			else if (r > 0 && g > 0 && b > 0) {
265 				baseFormat = GL_RGBA;
266 				bits[0] = r;
267 				bits[1] = g;
268 				bits[2] = b;
269 				bits[3] = a;
270 				texel[0] = ubyte_to_float(upperRightTexel[0], bits[0]);
271 				texel[1] = ubyte_to_float(upperRightTexel[1], bits[1]);
272 				texel[2] = ubyte_to_float(upperRightTexel[2], bits[2]);
273 				texel[3] = ubyte_to_float(upperRightTexel[3], bits[3]);
274 			}
275 			else if (r == 0 && g == 0 && b == 0) {
276 				baseFormat = GL_ALPHA;
277 				bits[0] = 0;
278 				bits[1] = 0;
279 				bits[2] = 0;
280 				bits[3] = a;
281 				texel[0] = 0.0;
282 				texel[1] = 0.0;
283 				texel[2] = 0.0;
284 				texel[3] = ubyte_to_float(upperRightTexel[3], bits[3]);
285 			}
286 			else {
287 				baseFormat = 0;  /* ??? */
288 				texel[0] = 0.0;
289 				texel[1] = 0.0;
290 				texel[2] = 0.0;
291 				texel[3] = 0.0;
292 			}
293 		}
294 		else if (l > 0) {
295 			baseFormat = GL_LUMINANCE;
296 			bits[0] = l;
297 			bits[1] = 0;
298 			bits[2] = 0;
299 			bits[3] = 0;
300 			texel[0] = ubyte_to_float(upperRightTexel[0], bits[0]);
301 			texel[1] = 0.0;
302 			texel[2] = 0.0;
303 			texel[3] = 1.0;
304 		}
305 		else if (r > 0) {
306 			if (g > 0) {
307 				if (b > 0) {
308 					baseFormat = GL_RGB;
309 					bits[0] = r;
310 					bits[1] = g;
311 					bits[2] = b;
312 					bits[3] = 0;
313 					texel[0] = ubyte_to_float(upperRightTexel[0], bits[0]);
314 					texel[1] = ubyte_to_float(upperRightTexel[1], bits[1]);
315 					texel[2] = ubyte_to_float(upperRightTexel[2], bits[2]);
316 					texel[3] = 1.0;
317 				}
318 				else {
319 					baseFormat = GL_RG;
320 					bits[0] = r;
321 					bits[1] = g;
322 					bits[2] = 0;
323 					bits[3] = 0;
324 					texel[0] = ubyte_to_float(upperRightTexel[0], bits[0]);
325 					texel[1] = ubyte_to_float(upperRightTexel[1], bits[1]);
326 					texel[2] = 0.0;
327 					texel[3] = 1.0;
328 				}
329 			}
330 			else {
331 				baseFormat = GL_RED;
332 				bits[0] = r;
333 				bits[1] = 0;
334 				bits[2] = 0;
335 				bits[3] = 0;
336 				texel[0] = ubyte_to_float(upperRightTexel[0], bits[0]);
337 				texel[1] = 0.0;
338 				texel[2] = 0.0;
339 				texel[3] = 1.0;
340 			}
341 		} else {
342 			assert(!"Unexpected texture component sizes");
343 			texel[0] = 0.0;
344 			texel[1] = 0.0;
345 			texel[2] = 0.0;
346 			texel[3] = 0.0;
347 		}
348 
349 		(void) baseFormat;  /* not used, at this time */
350 	}
351 
352 	/* compute texel color blended with background color */
353 #if DO_BLEND
354 	expected[0] = texel[0] * texel[3] + clearColor[0] * (1.0 - texel[3]);
355 	expected[1] = texel[1] * texel[3] + clearColor[1] * (1.0 - texel[3]);
356 	expected[2] = texel[2] * texel[3] + clearColor[2] * (1.0 - texel[3]);
357 	expected[3] = texel[3] * texel[3] + clearColor[3] * (1.0 - texel[3]);
358 #else
359         expected[0] = texel[0];
360         expected[1] = texel[1];
361         expected[2] = texel[2];
362         expected[3] = texel[3];
363 #endif
364 
365 	assert(expected[0] == expected[0]);
366 
367 	tolerance[0] = bits_to_tolerance(bits[0], compressed);
368 	tolerance[1] = bits_to_tolerance(bits[1], compressed);
369 	tolerance[2] = bits_to_tolerance(bits[2], compressed);
370 	tolerance[3] = bits_to_tolerance(bits[3], compressed);
371 }
372 
373 
374 static GLboolean
colors_equal(const GLfloat expected[4],const GLfloat pix[4],GLfloat tolerance[4])375 colors_equal(const GLfloat expected[4], const GLfloat pix[4],
376 	     GLfloat tolerance[4])
377 {
378 	if (fabsf(expected[0] - pix[0]) > tolerance[0] ||
379 		 fabsf(expected[1] - pix[1]) > tolerance[1] ||
380 		 fabsf(expected[2] - pix[2]) > tolerance[2] ||
381 		 fabsf(expected[3] - pix[3]) > tolerance[3]) {
382 		return GL_FALSE;
383 	}
384 	return GL_TRUE;
385 }
386 
387 
388 static GLboolean
test_format(const struct test_desc * test,const struct format_desc * fmt)389 test_format(const struct test_desc *test,
390 	    const struct format_desc *fmt)
391 {
392 	int x, y;
393 	int w = TEX_SIZE, h = TEX_SIZE;
394 	GLfloat readback[TEX_SIZE][TEX_SIZE][4];
395 	GLubyte upperRightTexel[4];
396 	int level;
397 	GLfloat expected[4], pix[4], tolerance[4];
398 	GLboolean pass = GL_TRUE;
399 
400 	glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
401 	glClear(GL_COLOR_BUFFER_BIT);
402 
403 	/* The RGBA_DXT1 formats seem to expose a Mesa/libtxc_dxtn bug.
404 	 * Just skip them for now.  Testing the other compressed formats
405 	 * is good enough.
406 	 */
407 	if (fmt->internalformat != GL_COMPRESSED_RGBA_S3TC_DXT1_EXT &&
408 	    fmt->internalformat != GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT) {
409 		/* init texture image */
410 		if (!make_texture_image(fmt->internalformat, upperRightTexel))
411 			return GL_TRUE; /* unsupported = OK */
412 
413 		x = 10;
414 		y = 40;
415 
416 		compute_expected_color(fmt, upperRightTexel, expected, tolerance);
417 
418 		/* Draw with the texture */
419 		glEnable(GL_TEXTURE_2D);
420 #if DO_BLEND
421 		glEnable(GL_BLEND);
422 #endif
423 		piglit_draw_rect_tex(x, y, w, h,  0.0, 0.0, 1.0, 1.0);
424 		glDisable(GL_TEXTURE_2D);
425 		glDisable(GL_BLEND);
426 
427 		x += TEX_SIZE + 20;
428 
429 		level = 0;
430 		while (w > 0) {
431 			/* Get the texture image */
432 			assert(!glIsEnabled(GL_TEXTURE_2D));
433 			glGetTexImage(GL_TEXTURE_2D, level, GL_RGBA, GL_FLOAT, readback);
434 
435 			assert(!glIsEnabled(GL_TEXTURE_2D));
436 			/* Draw the texture image */
437 			glWindowPos2iARB(x, y);
438 #if DO_BLEND
439 			glEnable(GL_BLEND);
440 #endif
441 			assert(!glIsEnabled(GL_TEXTURE_2D));
442 			glDrawPixels(w, h, GL_RGBA, GL_FLOAT, readback);
443 			glDisable(GL_BLEND);
444 
445 			assert(!glIsEnabled(GL_TEXTURE_2D));
446 
447 			if (level <= 2) {
448 				GLint rx = x + w-1;
449 				GLint ry = y + h-1;
450 				glReadPixels(rx, ry, 1, 1, GL_RGBA, GL_FLOAT, pix);
451 				if (!colors_equal(expected, pix, tolerance)) {
452 					printf("%s failure: format: %s, level %d at pixel(%d, %d)\n",
453 					       TestName,
454 					       get_format_name(
455 						       fmt->internalformat),
456 					       level, rx, ry);
457 					printf(" Expected (%f, %f, %f, %f)\n",
458 							 expected[0], expected[1], expected[2], expected[3]);
459 					printf("	 Found (%f, %f, %f, %f)\n",
460 							 pix[0], pix[1], pix[2], pix[3]);
461 					printf("Tolerance (%f, %f, %f, %f)\n",
462 							 tolerance[0], tolerance[1], tolerance[2], tolerance[3]);
463 					pass = GL_FALSE;
464 				}
465 			}
466 
467 			x += w + 20;
468 			w /= 2;
469 			h /= 2;
470 			level++;
471 		}
472 
473 	}
474 
475 	piglit_present_results();
476 
477 	return pass;
478 }
479 
480 
481 /**
482  * Is the given set of formats supported?
483  * This checks if required extensions are present and if this piglit test
484  * can actually grok the formats.
485  */
486 static GLboolean
supported_format_set(const struct test_desc * set)487 supported_format_set(const struct test_desc *set)
488 {
489 	if (!supported(set))
490 		return GL_FALSE;
491 
492 	if (set->format == ext_texture_integer ||
493 		 set->format == ext_packed_depth_stencil ||
494 		 set->format == arb_texture_stencil8 ||
495 		 set->format == arb_texture_rg_int ||
496 		 set->format == arb_depth_texture ||
497 		 set->format == arb_depth_buffer_float) {
498 		/*
499 		 * texture_integer requires a fragment shader, different
500 		 * glTexImage calls.  Depth/stencil formats not implemented.
501 		 */
502 		return GL_FALSE;
503 	}
504 
505 	return GL_TRUE;
506 }
507 
508 
509 static GLboolean
test_all_formats(void)510 test_all_formats(void)
511 {
512 	GLboolean pass = GL_TRUE;
513 	int i, j;
514 
515 	for (i = 0; i < ARRAY_SIZE(test_sets); i++) {
516 		const struct test_desc *set = &test_sets[i];
517 		if (supported_format_set(set)) {
518 			for (j = 0; j < set->num_formats; j++) {
519 				if (!test_format(set, &set->format[j])) {
520 					pass = GL_FALSE;
521 				}
522 			}
523 		}
524 	}
525 
526 	return pass;
527 }
528 
529 
530 enum piglit_result
piglit_display(void)531 piglit_display(void)
532 {
533 	GLboolean pass;
534 
535 	piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
536 
537 	if (piglit_automatic) {
538 		pass = test_all_formats();
539 	}
540 	else {
541 		const struct test_desc *set = &test_sets[test_index];
542 		if (supported_format_set(set)) {
543 			pass = test_format(set, &set->format[format_index]);
544 		}
545 		else {
546 			/* unsupported format - not a failure */
547 			pass = GL_TRUE;
548 			glClear(GL_COLOR_BUFFER_BIT);
549 			piglit_present_results();
550 		}
551 	}
552 
553 	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
554 }
555 
556 void
piglit_init(int argc,char ** argv)557 piglit_init(int argc, char **argv)
558 {
559 	bool found_test_set = false;
560 	int i;
561 
562 	if ((piglit_get_gl_version() < 14) && !piglit_is_extension_supported("GL_ARB_window_pos")) {
563 		printf("Requires GL 1.4 or GL_ARB_window_pos");
564 		piglit_report_result(PIGLIT_SKIP);
565 	}
566 
567 	(void) fbo_formats_display;
568 
569 	for (i = 1; i < argc; i++) {
570 		if (strcmp(argv[i], "init-by-rendering") == 0) {
571 			init_by_rendering = GL_TRUE;
572 			puts("The textures will be initialized by rendering "
573 			     "to them using glDrawPixels.");
574 			break;
575 		} else if (strcmp(argv[i], "init-by-clear-and-render") == 0) {
576 			init_by_clearing_first = GL_TRUE;
577 			puts("The textures will be initialized by rendering "
578 			     "to them using glClear and glDrawPixels.");
579 			break;
580 		} else if (!found_test_set) {
581 			found_test_set = fbo_use_test_set(argv[i], true);
582 			if (!found_test_set) {
583 				printf("Bad test set name: %s\n", argv[i]);
584 			}
585 		}
586 	}
587 
588 	glGenTextures(1, &texture_id);
589 	glBindTexture(GL_TEXTURE_2D, texture_id);
590 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
591 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
592 
593 	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
594 
595 	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
596 }
597