1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     Gas.cpp
4 
5   Copyright (C)2009-2012 Nintendo Co., Ltd.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Rev: 46365 $
14  *---------------------------------------------------------------------------*/
15 
16 /*
17  *------------------------------------------------------------
18  * Copyright(c) 2009-2010 by Digital Media Professionals Inc.
19  * All rights reserved.
20  *------------------------------------------------------------
21  * This source code is the confidential and proprietary
22  * of Digital Media Professionals Inc.
23  *------------------------------------------------------------
24  */
25 
26 #include <math.h>
27 #include "Gas.h"
28 #include "Util.h"
29 
30 #include <assert.h>
31 
32 extern GLuint pAccId;
33 extern GLuint pPostId;
34 extern struct gas_data gas;
35 
36 /*
37  * Local function declaration
38  */
39 
40 /*
41  * Local definition
42  */
43 #define SHADING_WIDTH       GAS_TEX_WIDTH
44 #define SHADING_HEIGHT      GAS_TEX_HEIGHT
45 
46 /* buffer id */
47 static struct tagBufID
48 {
49     GLuint  acc;        /* frame buffer for accumulation */
50     GLuint  shading;    /* frame buffer for shading */
51     GLuint  accZ;       /* Z buffer for accumulation */
52 } gasbuf;
53 
54 /* texture id */
55 GLuint gasacctex;       /* gas texture to accumulation */
56 GLuint gastex;          /* gas texture for shading pass */
57 
58 /* particle pattern file names */
59 static char* particle_files[PARTICLE_PATTERNS] = {PARTICLE_FILES};
60 
61 /*=======================================================*/
62 /* buffer initialization                                 */
63 /*=======================================================*/
GasInitialize(void)64 void GasInitialize(void)
65 {
66     /*
67      * Generate framebuffers and texture for gas rendering
68     */
69 
70     /* generation */
71     glGenFramebuffers(1, (GLuint*)&gasbuf.acc);
72     glGenFramebuffers(1, (GLuint*)&gasbuf.shading);
73     glGenTextures(1, (GLuint*)&gasacctex);
74     glGenTextures(1, (GLuint*)&gastex);
75     glGenRenderbuffers(1, (GLuint*)&gasbuf.accZ);
76 
77     /*
78      * Initialize accumulation buffer (destination of gas accumulation rendering)
79      * (this buffer is reused as a destination of shading)
80     */
81 
82     /* initialize gas accumulation texture */
83     glBindTexture(GL_TEXTURE_2D, gasacctex);
84     glTexImage2D(GL_TEXTURE_2D, 0, GL_GAS_DMP, GAS_ACC_WIDTH, GAS_ACC_HEIGHT, 0, GL_GAS_DMP, GL_UNSIGNED_SHORT, 0);
85     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
86     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
87 
88     /* Attach texture to framebuffer */
89     glBindFramebuffer(GL_FRAMEBUFFER, gasbuf.acc);
90     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gasacctex, 0);
91 
92     /* default z buffer is defferent size from this buffer, so it is
93      * necessary to prepare same size z buffer. */
94     glBindRenderbuffer(GL_RENDERBUFFER, gasbuf.accZ) ;
95     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, GAS_ACC_WIDTH, GAS_ACC_HEIGHT);
96     glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, gasbuf.accZ);
97 
98     /*
99      * Initialize accumulation pow2 texture area (copy destination of accumulation result or shading result)
100     */
101     glBindTexture(GL_TEXTURE_2D, gastex);
102     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GAS_TEX_WIDTH, GAS_TEX_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
103     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
104     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
105 
106     glBindFramebuffer(GL_FRAMEBUFFER, gasbuf.shading);
107     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gastex, 0);
108 }
109 
110 /*=======================================================*/
111 /* Setup of default gasesous object data structure       */
112 /*=======================================================*/
DefaultGasObject(struct gas_data * gas,float * gasColorTable)113 void DefaultGasObject(struct gas_data *gas, float *gasColorTable)
114 {
115     gas->_dela_z = 200.0f;
116     gas->_autoAcc = GL_FALSE;
117     gas->_densMax = 1.0f;
118     gas->_lightDirX = 0.0f;
119     gas->_lightDirY = 0.0f;
120 
121     gas->_LightXY[0] = 0.0f;
122     gas->_LightXY[1] = 0.0f;
123     gas->_LightXY[2] = 0.0f;
124     gas->_LightXY[3] = 0.0f;    /* unsused */
125 
126     gas->_LightZ[0] = 1.0f;
127     gas->_LightZ[1] = 0.0f;
128     gas->_LightZ[2] = 1.0f;
129     gas->_LightZ[3] = 1.0f;
130 
131     gas->shadingDensitySrc = GL_GAS_PLAIN_DENSITY_DMP;
132     gas->colorLutInput = GL_GAS_DENSITY_DMP;
133 
134     float dxt = 1.0f / 127.0f;
135     float xt = 0;
136     for (int i = 0; i < 128; i++)
137     {
138         gas->fogTable[i]= 1.0f - exp(-15.0f * xt);
139         xt += dxt;
140     }
141 
142     for (int i = 0; i < 128; i++)
143     {
144         gas->fogTable[128 + i] = gas->fogTable[i + 1] - gas->fogTable[i];
145     }
146 
147     gas->fogTable[255] = 0;
148     glGenTextures(1, &gas->CollectionLUT_ID);
149     glGenTextures(1, &gas->FogLut_ID);
150 
151     glBindTexture(GL_TEXTURE_COLLECTION_DMP, gas->CollectionLUT_ID);
152     glBindTexture(GL_LUT_TEXTURE0_DMP, gas->FogLut_ID);
153     glTexImage1D(GL_LUT_TEXTURE0_DMP, 0, GL_LUMINANCEF_DMP, 256, 0, GL_LUMINANCEF_DMP, GL_FLOAT, gas->fogTable);
154 
155     glGenTextures(3,&gas->gasTransfert_ID[0]);
156 
157     for(int i = 0; i < 8; i++)
158     {
159         gas->RR[i] = gasColorTable[3 * i + 0];
160         gas->GG[i] = gasColorTable[3 * i + 1];
161         gas->BB[i] = gasColorTable[3 * i + 2];
162 
163         gas->RR[8 + i] = gasColorTable[3 * (i + 1) + 0] - gasColorTable[3 * i + 0];
164         gas->GG[8 + i] = gasColorTable[3 * (i + 1) + 1] - gasColorTable[3 * i + 1];
165         gas->BB[8 + i] = gasColorTable[3 * (i + 1) + 2] - gasColorTable[3 * i + 2];
166     }
167     gas->RR[15] = 0.0f;
168     gas->GG[15] = 0.0f;
169     gas->BB[15] = 0.0f;
170 
171     glBindTexture(GL_LUT_TEXTURE1_DMP, gas->gasTransfert_ID[0]);
172     glTexImage1D(GL_LUT_TEXTURE1_DMP, 0, GL_LUMINANCEF_DMP, 16, 0, GL_LUMINANCEF_DMP, GL_FLOAT, gas->RR);
173 
174     glBindTexture(GL_LUT_TEXTURE2_DMP, gas->gasTransfert_ID[1]);
175     glTexImage1D(GL_LUT_TEXTURE2_DMP, 0, GL_LUMINANCEF_DMP, 16, 0, GL_LUMINANCEF_DMP, GL_FLOAT, gas->GG);
176 
177     glBindTexture(GL_LUT_TEXTURE3_DMP, gas->gasTransfert_ID[2]);
178     glTexImage1D(GL_LUT_TEXTURE3_DMP, 0, GL_LUMINANCEF_DMP, 16, 0, GL_LUMINANCEF_DMP, GL_FLOAT, gas->BB);
179 
180     float u0 = 0.0f;
181     float v0 = 0.0f;
182 
183     float u1 =  (GAS_ACC_WIDTH * 1.0f) / (GAS_TEX_WIDTH * 1.0f);
184     float v1 =  (GAS_ACC_HEIGHT * 1.0f) / (GAS_TEX_HEIGHT * 1.0f);
185 
186     GLfloat tex_unit[8]= {u0, v0, u0, v1, u1, v1, u1, v0};
187 
188     GLfloat LX0, LY0, LX1, LY1;
189     LX0 = 0.0f;
190     LY0 = 0.0f;
191     LX1 = gas->_lightDirX;
192     LY1 = gas->_lightDirY;
193     GLfloat vertex_color[16] =
194     {
195         LX0, 0.0f, 0.0f, LY0,
196         LX0, 0.0f, 0.0f, LY1,
197         LX1, 0.0f, 0.0f, LY1,
198         LX1, 0.0f, 0.0f, LY0
199     };
200 
201     GLushort _quadIndex[6] = {0, 1, 2, 0, 2, 3};
202     GLfloat vertex_unit[16] =
203     {
204         -1.0f, -1.0f, 0.0f, 1.0f,
205         -1.0f,  1.0f, 0.0f, 1.0f,
206          1.0f,  1.0f, 0.0f, 1.0f,
207          1.0f, -1.0f, 0.0f, 1.0f
208     };
209 
210     glGenBuffers(1, &gas->quad_index_ID);
211     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gas->quad_index_ID);
212     glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6*sizeof(GLushort), &_quadIndex, GL_STATIC_DRAW);
213 
214     glGenBuffers(1, &gas->quad_vertBuf_ID);
215     glBindBuffer(GL_ARRAY_BUFFER,gas->quad_vertBuf_ID);
216     glBufferData(GL_ARRAY_BUFFER, 16*sizeof(GLfloat), &vertex_unit, GL_STATIC_DRAW);
217 
218     glGenBuffers(1, &gas->quad_texBuf_ID);
219     glBindBuffer(GL_ARRAY_BUFFER,gas->quad_texBuf_ID);
220     glBufferData(GL_ARRAY_BUFFER, 8*sizeof(GLfloat), &tex_unit, GL_STATIC_DRAW);
221 
222     glGenBuffers(1, &gas->quad_colBuf_ID);
223     glBindBuffer(GL_ARRAY_BUFFER,gas->quad_colBuf_ID);
224     glBufferData(GL_ARRAY_BUFFER, 16*sizeof(GLfloat), &vertex_color, GL_STATIC_DRAW);
225 
226     /*
227      * Load particle patterns
228     */
229     glGenTextures(PARTICLE_PATTERNS, &gas->pattern[0]);
230     for (int i = 0; i < PARTICLE_PATTERNS; i++)
231     {
232         bool alpha;
233         glBindTexture(GL_TEXTURE_2D, gas->pattern[i]);
234         glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
235         glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
236         loadTexture(particle_files[i], GL_TEXTURE_2D, 0, alpha);
237     }
238 }
239 
240 /*=======================================================*/
241 /* accumulation pass                                     */
242 /*=======================================================*/
GasAccumulation()243 void GasAccumulation()
244 {
245     /*
246      * In accumulation pass, particles are accumulated into gas accumulation buffer as
247      * density information. This buffer is 'gasbuf.acc' in this sample.
248     */
249 
250     /* Bind accumulation buffer as a rendering target */
251     glBindFramebuffer(GL_FRAMEBUFFER, gasbuf.acc);
252     /* Set viewport */
253     glViewport(0, 0, GAS_ACC_WIDTH, GAS_ACC_HEIGHT);
254     /* Clear the buffer content (only color!) */
255     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
256     glClear(GL_COLOR_BUFFER_BIT);
257 
258     /* use gas accumulation related program */
259     glUseProgram(pAccId);
260 
261     /* misc state */
262     glEnable(GL_DEPTH_TEST);
263     glDepthFunc(GL_LESS);
264 
265     glDisable(GL_CULL_FACE);
266     glFrontFace(GL_CCW);
267     glCullFace(GL_BACK);
268 
269     /* texture pattern binding */
270     /* assuming only 1 pattern  */
271     glActiveTexture(GL_TEXTURE0);
272     glBindTexture(GL_TEXTURE_2D, gas.pattern[0]);
273 
274     /* setup uniforms */
275     /* note that the program is shared with standard geometry to uniforms need to be reapply for each drawing call */
276     glUniform1i(glGetUniformLocation(pAccId, "dmp_Texture[0].samplerType"), GL_TEXTURE_2D);
277     glUniform1i(glGetUniformLocation(pAccId, "dmp_TexEnv[0].combineRgb"), GL_MODULATE);
278     glUniform1i(glGetUniformLocation(pAccId, "dmp_TexEnv[0].combineAlpha"), GL_REPLACE);
279     glUniform3i(glGetUniformLocation(pAccId, "dmp_TexEnv[0].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
280     glUniform3i(glGetUniformLocation(pAccId, "dmp_TexEnv[0].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
281     glUniform3i(glGetUniformLocation(pAccId, "dmp_TexEnv[0].srcRgb"), GL_TEXTURE0, GL_PRIMARY_COLOR, GL_PRIMARY_COLOR);
282     glUniform3i(glGetUniformLocation(pAccId, "dmp_TexEnv[0].srcAlpha"), GL_TEXTURE0, GL_PRIMARY_COLOR, GL_PRIMARY_COLOR);
283 
284     /* Set the mode for the per fragment operation (gas accumulation mode) */
285     glUniform1i(glGetUniformLocation(pAccId, "dmp_FragOperation.mode"), GL_FRAGOP_MODE_GAS_ACC_DMP);
286 
287     /* Set this value to control the accuracy of z intersection of surface and gaseous objects */
288     glUniform1f(glGetUniformLocation(pAccId, "dmp_Gas.deltaZ"),gas._dela_z);
289 
290     glUniform1i(glGetUniformLocation(pAccId, "dmp_Fog.mode"), GL_FALSE);
291 
292     /*
293      * Setup buffer
294     */
295     glEnableVertexAttribArray(0);
296     glEnableVertexAttribArray(1);
297     glEnableVertexAttribArray(2);
298 
299     glBindBuffer(GL_ARRAY_BUFFER, gas.gasgeo_center_ID);
300     glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
301 
302     glBindBuffer(GL_ARRAY_BUFFER, gas.gasgeo_tx0_ID);
303     glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
304 
305     glBindBuffer(GL_ARRAY_BUFFER, gas.gasgeo_density_ID);
306     glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 0, 0);
307 
308     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gas.gasgeo_tri_ID);
309     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
310 
311     glFinish();
312 }
313 
314 /*=======================================================*/
315 /* shading pass                                          */
316 /*=======================================================*/
GasShading(void)317 void GasShading(void)
318 {
319     /*
320      * In shading pass, shaded gaseous image is blended to DISPLAY_BUFFER.
321      * Accumulated density information is used as a gas texture.
322      * Note that DISPLAY_BUFFER is defferent size
323      * from gas texture and PICA does not support filter for gas format texture.
324      * So gaseous shaded image is rendered to another buffer and then blend to
325      * DIPLAY_BUFFER.
326     */
327 
328     /* Bind shading buffer and set viewport */
329     glBindFramebuffer(GL_FRAMEBUFFER, gasbuf.shading);
330     glViewport(0, 0, SHADING_WIDTH, SHADING_HEIGHT);
331 
332     /* use gas accumulation related program */
333     glUseProgram(pPostId);
334 
335     /* Bind gas texture (accumulation result) */
336     glActiveTexture(GL_TEXTURE0);
337     glBindTexture(GL_TEXTURE_2D, gasacctex);
338 
339     /* Setup blending unit #0
340      * r component of primary color has the influence of LIGHT_X and LIGHT_Y
341      * this output is transfered to FOG unit when FOG_MODE is set to GAS_DMP */
342     glUniform1i(glGetUniformLocation(pPostId, "dmp_Texture[0].samplerType"), GL_TEXTURE_2D);
343     glUniform1i(glGetUniformLocation(pPostId, "dmp_TexEnv[0].combineRgb"), GL_ADD);
344     glUniform1i(glGetUniformLocation(pPostId, "dmp_TexEnv[0].combineAlpha"), GL_ADD);
345     glUniform3i(glGetUniformLocation(pPostId, "dmp_TexEnv[0].operandRgb"), GL_SRC_COLOR, GL_SRC_ALPHA, GL_SRC_COLOR);
346     glUniform3i(glGetUniformLocation(pPostId, "dmp_TexEnv[0].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
347     glUniform3i(glGetUniformLocation(pPostId, "dmp_TexEnv[0].srcRgb"), GL_PRIMARY_COLOR, GL_PRIMARY_COLOR, GL_PRIMARY_COLOR);
348     glUniform3i(glGetUniformLocation(pPostId, "dmp_TexEnv[0].srcAlpha"), GL_PRIMARY_COLOR, GL_PRIMARY_COLOR, GL_PRIMARY_COLOR);
349 
350     /* Setup blending unit #5
351      * This is HW requirement. See specification document for more details
352     */
353     glUniform3i(glGetUniformLocation(pPostId, "dmp_TexEnv[5].srcRgb"), GL_PREVIOUS, GL_PREVIOUS, GL_TEXTURE0);
354     glUniform3i(glGetUniformLocation(pPostId, "dmp_TexEnv[5].srcAlpha"), GL_PREVIOUS, GL_PREVIOUS, GL_TEXTURE0);
355 
356     /* setup of gas shading */
357     glUniform1i(glGetUniformLocation(pPostId, "dmp_Fog.sampler"), 0);
358     glUniform1i(glGetUniformLocation(pPostId, "dmp_Fog.mode"), GL_GAS_DMP);
359     glUniform1i(glGetUniformLocation(pPostId, "dmp_Gas.autoAcc"), gas._autoAcc);
360     glUniform1i(glGetUniformLocation(pPostId, "dmp_Gas.samplerTR"), 1);
361     glUniform1i(glGetUniformLocation(pPostId, "dmp_Gas.samplerTG"), 2);
362     glUniform1i(glGetUniformLocation(pPostId, "dmp_Gas.samplerTB"), 3);
363     glUniform1i(glGetUniformLocation(pPostId, "dmp_Gas.shadingDensitySrc"), gas.shadingDensitySrc);
364     glUniform1i(glGetUniformLocation(pPostId, "dmp_Gas.colorLutInput"), gas.colorLutInput);
365     glUniform1f(glGetUniformLocation(pPostId, "dmp_Gas.accMax"), gas._densMax);
366     glUniform4fv(glGetUniformLocation(pPostId, "dmp_Gas.lightZ"), 1, gas._LightZ);
367     glUniform3fv(glGetUniformLocation(pPostId, "dmp_Gas.lightXY"), 1, gas._LightXY);
368 
369     glUniform1i(glGetUniformLocation(pPostId, "dmp_FragOperation.mode"), GL_FRAGOP_MODE_GL_DMP);
370 
371     /*
372      * misc settings
373     */
374     /* In this configuration shading result is once rendered
375      * without blending. */
376     glDisable(GL_BLEND);
377     glDisable(GL_DEPTH_TEST);
378     glDepthMask(0);
379 
380     glBindTexture(GL_TEXTURE_COLLECTION_DMP, gas.CollectionLUT_ID);
381     glBindTexture(GL_TEXTURE_2D, gasacctex);
382 
383     glEnableVertexAttribArray(0);
384     glEnableVertexAttribArray(1);
385     glEnableVertexAttribArray(2);
386 
387     glBindBuffer(GL_ARRAY_BUFFER, gas.quad_vertBuf_ID);
388     glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
389 
390     glBindBuffer(GL_ARRAY_BUFFER, gas.quad_texBuf_ID);
391     glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
392 
393     glBindBuffer(GL_ARRAY_BUFFER, gas.quad_colBuf_ID);
394     glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 0, 0);
395 
396     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gas.quad_index_ID);
397     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
398 
399     glDisableVertexAttribArray(0);
400     glDisableVertexAttribArray(1);
401     glDisableVertexAttribArray(2);
402 
403     glDisable(GL_BLEND);
404     glEnable(GL_DEPTH_TEST);
405     glDepthFunc(GL_LESS);
406 
407     glDisable(GL_CULL_FACE);
408     glFrontFace(GL_CCW);
409     glCullFace(GL_BACK);
410 }
411 
412 /*=======================================================*/
413 /* blend shading result to color buffer                  */
414 /*=======================================================*/
GasBlendShadingResult(void)415 void GasBlendShadingResult(void)
416 {
417     /* In this function, shading result is blended to DISPLAY_BUFFER. */
418 
419     /* Bind shading buffer and set viewport */
420 //    glBindFramebuffer(GL_FRAMEBUFFER, DISPLAY_BUFFER);
421 //    glViewport(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT);
422     /* use gas accumulation related program */
423     glUseProgram(pPostId);
424 
425     /* Set fragment operation mode to GL_FRAGOP_MODE_GL_DMP */
426     glUniform1i(glGetUniformLocation(pPostId, "dmp_FragOperation.mode"), GL_FRAGOP_MODE_GL_DMP);
427 
428     /* Disable Fog Mode */
429     glUniform1i(glGetUniformLocation(pPostId, "dmp_Fog.mode"), GL_FALSE);
430 
431     /*
432      * Setup texture and blending unit
433     */
434 
435     /* Bind gas texture (accumulation result) */
436     glActiveTexture(GL_TEXTURE0);
437     glBindTexture(GL_TEXTURE_2D, gastex);
438 
439     glUniform1i(glGetUniformLocation(pPostId, "dmp_Texture[0].samplerType"), GL_TEXTURE_2D);
440     glUniform1i(glGetUniformLocation(pPostId, "dmp_TexEnv[0].combineRgb"), GL_REPLACE);
441     glUniform1i(glGetUniformLocation(pPostId, "dmp_TexEnv[0].combineAlpha"), GL_REPLACE);
442     glUniform3i(glGetUniformLocation(pPostId, "dmp_TexEnv[0].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
443     glUniform3i(glGetUniformLocation(pPostId, "dmp_TexEnv[0].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
444     glUniform3i(glGetUniformLocation(pPostId, "dmp_TexEnv[0].srcRgb"), GL_TEXTURE0, GL_PRIMARY_COLOR, GL_PRIMARY_COLOR);
445     glUniform3i(glGetUniformLocation(pPostId, "dmp_TexEnv[0].srcAlpha"), GL_TEXTURE0, GL_PRIMARY_COLOR, GL_PRIMARY_COLOR);
446 
447     glUniform1i(glGetUniformLocation(pPostId, "dmp_TexEnv[1].combineRgb"), GL_REPLACE);
448     glUniform1i(glGetUniformLocation(pPostId, "dmp_TexEnv[1].combineAlpha"), GL_REPLACE);
449     glUniform3i(glGetUniformLocation(pPostId, "dmp_TexEnv[1].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
450     glUniform3i(glGetUniformLocation(pPostId, "dmp_TexEnv[1].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
451     glUniform3i(glGetUniformLocation(pPostId, "dmp_TexEnv[1].srcRgb"), GL_PREVIOUS, GL_PREVIOUS, GL_PREVIOUS);
452     glUniform3i(glGetUniformLocation(pPostId, "dmp_TexEnv[1].srcAlpha"), GL_PREVIOUS, GL_PREVIOUS, GL_PREVIOUS);
453 
454     /* misc settings */
455     glEnable(GL_BLEND);
456     glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
457     glDisable(GL_DEPTH_TEST);
458     glDepthMask(0);
459 
460     glEnableVertexAttribArray(0);
461     glEnableVertexAttribArray(1);
462     glDisableVertexAttribArray(2);
463 
464     glBindBuffer(GL_ARRAY_BUFFER, gas.quad_vertBuf_ID);
465     glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
466 
467     glBindBuffer(GL_ARRAY_BUFFER, gas.quad_texBuf_ID);
468     glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
469 
470     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gas.quad_index_ID);
471     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
472 
473     glDisableVertexAttribArray(0);
474     glDisableVertexAttribArray(1);
475 }
476 
477 /*=======================================================*/
478 /* render accumulation Z buffer                          */
479 /*=======================================================*/
GasRenderAccumulationZBuffer(void (* drawfunc)(void))480 void GasRenderAccumulationZBuffer(void (*drawfunc)(void))
481 {
482     /* Bind accumulation buffer as a rendering target. */
483     glBindFramebuffer(GL_FRAMEBUFFER, gasbuf.acc);
484     /* use shared / gas accumulation related program */
485     glUseProgram(pAccId);
486 
487     /* Clear z buffer */
488     glClearDepthf(1.f);
489     glClear(GL_DEPTH_BUFFER_BIT);
490     /* Set viewport */
491     glViewport(0, 0, GAS_ACC_WIDTH, GAS_ACC_HEIGHT);
492     /* Disable color write */
493     glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
494 
495     /* draw object */
496     drawfunc();
497 
498     /* Recover color mask */
499     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
500 }
501