132001f49Smrg/* 232001f49Smrg * Draw the "fire" test program on the six faces of a cube using 332001f49Smrg * fbo render-to-texture. 432001f49Smrg * 532001f49Smrg * Much of the code comes from David Bucciarelli's "fire" 632001f49Smrg * test program. The rest basically from Brian Paul's "gearbox" and 732001f49Smrg * fbotexture programs. 832001f49Smrg * 932001f49Smrg * By pressing the 'q' key, you can make the driver choose different 1032001f49Smrg * internal texture RGBA formats by giving it different "format" and "type" 1132001f49Smrg * arguments to the glTexImage2D function that creates the texture 1232001f49Smrg * image being rendered to. If the driver doesn't support a texture image 1332001f49Smrg * format as a render target, it will usually fall back to software when 1432001f49Smrg * drawing the "fire" image, and frame-rate should drop considerably. 1532001f49Smrg * 1632001f49Smrg * Performance: 1732001f49Smrg * The rendering speed of this program is usually dictated by fill rate 1832001f49Smrg * and the fact that software fallbacks for glBitMap makes the driver 1932001f49Smrg * operate synchronously. Low-end UMA hardware will probably see around 2032001f49Smrg * 35 fps with the help screen disabled and 32bpp window- and user 2132001f49Smrg * frame-buffers (2008). 2232001f49Smrg * 2332001f49Smrg * This program is released under GPL, following the "fire" licensing. 2432001f49Smrg * 2532001f49Smrg * Authors: 2632001f49Smrg * David Bucciarelli ("fire") 2732001f49Smrg * Brian Paul ("gearbox", "fbotexture") 2832001f49Smrg * Thomas Hellstrom (Putting it together) 2932001f49Smrg * 3032001f49Smrg */ 3132001f49Smrg 3232001f49Smrg#include <math.h> 3332001f49Smrg#include <stdlib.h> 3432001f49Smrg#include <stdio.h> 3532001f49Smrg#include <string.h> 3632001f49Smrg#include <GL/glew.h> 3732001f49Smrg#include "glut_wrap.h" 3832001f49Smrg#include "readtex.h" 3932001f49Smrg 4032001f49Smrg 4132001f49Smrg/* 4232001f49Smrg * Format of texture we render to. 4332001f49Smrg */ 4432001f49Smrg 4532001f49Smrg#define TEXINTFORMAT GL_RGBA 4632001f49Smrg 4732001f49Smrgstatic GLuint texTypes[] = 4832001f49Smrg {GL_UNSIGNED_BYTE, 4932001f49Smrg GL_UNSIGNED_INT_8_8_8_8_REV, 5032001f49Smrg GL_UNSIGNED_SHORT_1_5_5_5_REV, 5132001f49Smrg GL_UNSIGNED_SHORT_4_4_4_4_REV, 5232001f49Smrg GL_UNSIGNED_INT_8_8_8_8, 5332001f49Smrg GL_UNSIGNED_SHORT_5_5_5_1, 5432001f49Smrg GL_UNSIGNED_SHORT_4_4_4_4, 5532001f49Smrg GL_UNSIGNED_INT_8_8_8_8_REV, 5632001f49Smrg GL_UNSIGNED_SHORT_1_5_5_5_REV, 5732001f49Smrg GL_UNSIGNED_SHORT_4_4_4_4_REV, 5832001f49Smrg GL_UNSIGNED_INT_8_8_8_8, 5932001f49Smrg GL_UNSIGNED_SHORT_5_5_5_1, 6032001f49Smrg GL_UNSIGNED_SHORT_4_4_4_4, 6132001f49Smrg GL_UNSIGNED_SHORT_5_6_5, 6232001f49Smrg GL_UNSIGNED_SHORT_5_6_5_REV, 6332001f49Smrg GL_UNSIGNED_SHORT_5_6_5, 6432001f49Smrg GL_UNSIGNED_SHORT_5_6_5_REV}; 6532001f49Smrg 6632001f49Smrgstatic GLuint texFormats[] = 6732001f49Smrg {GL_RGBA, 6832001f49Smrg GL_RGBA, 6932001f49Smrg GL_RGBA, 7032001f49Smrg GL_RGBA, 7132001f49Smrg GL_RGBA, 7232001f49Smrg GL_RGBA, 7332001f49Smrg GL_RGBA, 7432001f49Smrg GL_BGRA, 7532001f49Smrg GL_BGRA, 7632001f49Smrg GL_BGRA, 7732001f49Smrg GL_BGRA, 7832001f49Smrg GL_BGRA, 7932001f49Smrg GL_BGRA, 8032001f49Smrg GL_RGB, 8132001f49Smrg GL_RGB, 8232001f49Smrg GL_BGR, 8332001f49Smrg GL_BGR}; 8432001f49Smrg 8532001f49Smrgstatic const char *texNames[] = 8632001f49Smrg {"GL_RGBA GL_UNSIGNED_BYTE", 8732001f49Smrg "GL_RGBA GL_UNSIGNED_INT_8_8_8_8_REV", 8832001f49Smrg "GL_RGBA GL_UNSIGNED_SHORT_1_5_5_5_REV", 8932001f49Smrg "GL_RGBA GL_UNSIGNED_SHORT_4_4_4_4_REV", 9032001f49Smrg "GL_RGBA GL_UNSIGNED_INT_8_8_8_8", 9132001f49Smrg "GL_RGBA GL_UNSIGNED_INT_5_5_5_1", 9232001f49Smrg "GL_RGBA GL_UNSIGNED_INT_4_4_4_4", 9332001f49Smrg "GL_BGRA GL_UNSIGNED_INT_8_8_8_8_REV", 9432001f49Smrg "GL_BGRA GL_UNSIGNED_SHORT_1_5_5_5_REV", 9532001f49Smrg "GL_BGRA GL_UNSIGNED_SHORT_4_4_4_4_REV", 9632001f49Smrg "GL_BGRA GL_UNSIGNED_INT_8_8_8_8", 9732001f49Smrg "GL_BGRA GL_UNSIGNED_INT_5_5_5_1", 9832001f49Smrg "GL_BGRA GL_UNSIGNED_INT_4_4_4_4", 9932001f49Smrg "GL_RGB GL_UNSIGNED_INT_5_6_5", 10032001f49Smrg "GL_RGB GL_UNSIGNED_INT_5_6_5_REV", 10132001f49Smrg "GL_BGR GL_UNSIGNED_INT_5_6_5", 10232001f49Smrg "GL_BGR GL_UNSIGNED_INT_5_6_5_REV"}; 10332001f49Smrg 10432001f49Smrg 10532001f49Smrg 10632001f49Smrg 10732001f49Smrg#ifndef M_PI 10832001f49Smrg#define M_PI 3.1415926535 10932001f49Smrg#endif 11032001f49Smrg 11132001f49Smrg#define vinit(a,i,j,k) { \ 11232001f49Smrg (a)[0]=i; \ 11332001f49Smrg (a)[1]=j; \ 11432001f49Smrg (a)[2]=k; \ 11532001f49Smrg } 11632001f49Smrg 11732001f49Smrg#define vinit4(a,i,j,k,w) { \ 11832001f49Smrg (a)[0]=i; \ 11932001f49Smrg (a)[1]=j; \ 12032001f49Smrg (a)[2]=k; \ 12132001f49Smrg (a)[3]=w; \ 12232001f49Smrg } 12332001f49Smrg 12432001f49Smrg 12532001f49Smrg#define vadds(a,dt,b) { \ 12632001f49Smrg (a)[0]+=(dt)*(b)[0]; \ 12732001f49Smrg (a)[1]+=(dt)*(b)[1]; \ 12832001f49Smrg (a)[2]+=(dt)*(b)[2]; \ 12932001f49Smrg } 13032001f49Smrg 13132001f49Smrg#define vequ(a,b) { \ 13232001f49Smrg (a)[0]=(b)[0]; \ 13332001f49Smrg (a)[1]=(b)[1]; \ 13432001f49Smrg (a)[2]=(b)[2]; \ 13532001f49Smrg } 13632001f49Smrg 13732001f49Smrg#define vinter(a,dt,b,c) { \ 13832001f49Smrg (a)[0]=(dt)*(b)[0]+(1.0-dt)*(c)[0]; \ 13932001f49Smrg (a)[1]=(dt)*(b)[1]+(1.0-dt)*(c)[1]; \ 14032001f49Smrg (a)[2]=(dt)*(b)[2]+(1.0-dt)*(c)[2]; \ 14132001f49Smrg } 14232001f49Smrg 14332001f49Smrg#define clamp(a) ((a) < 0.0 ? 0.0 : ((a) < 1.0 ? (a) : 1.0)) 14432001f49Smrg 14532001f49Smrg#define vclamp(v) { \ 14632001f49Smrg (v)[0]=clamp((v)[0]); \ 14732001f49Smrg (v)[1]=clamp((v)[1]); \ 14832001f49Smrg (v)[2]=clamp((v)[2]); \ 14932001f49Smrg } 15032001f49Smrg 15132001f49Smrgstatic GLint WinWidth = 800, WinHeight = 800; 15232001f49Smrgstatic GLint TexWidth, TexHeight; 15332001f49Smrgstatic GLuint TexObj; 15432001f49Smrgstatic GLuint MyFB; 15532001f49Smrgstatic GLuint DepthRB; 15632001f49Smrgstatic GLboolean WireFrame = GL_FALSE; 15732001f49Smrgstatic GLboolean Anim = GL_TRUE; 15832001f49Smrgstatic GLint texType = 0; 15932001f49Smrg 16032001f49Smrgstatic GLint T0 = 0; 16132001f49Smrgstatic GLint Frames = 0; 16232001f49Smrgstatic GLint Win = 0; 16332001f49Smrg 16432001f49Smrgstatic GLfloat ViewRotX = 20.0, ViewRotY = 30.0, ViewRotZ = 0.0; 16532001f49Smrgstatic GLfloat CubeRot = 0.0; 16632001f49Smrg 16732001f49Smrg 16832001f49Smrgstatic void 16932001f49Smrgidle(void); 17032001f49Smrg 17132001f49Smrg 17232001f49Smrgstatic void 17332001f49SmrgCheckError(int line) 17432001f49Smrg{ 17532001f49Smrg GLenum err = glGetError(); 17632001f49Smrg if (err) { 17732001f49Smrg printf("GL Error 0x%x at line %d\n", (int) err, line); 17832001f49Smrg exit(1); 17932001f49Smrg } 18032001f49Smrg} 18132001f49Smrg 18232001f49Smrg 18332001f49Smrgstatic void 18432001f49Smrgcleanup(void) 18532001f49Smrg{ 18632001f49Smrg glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 18732001f49Smrg glDeleteFramebuffersEXT(1, &MyFB); 18832001f49Smrg glDeleteRenderbuffersEXT(1, &DepthRB); 18932001f49Smrg glDeleteTextures(1, &TexObj); 19032001f49Smrg glutDestroyWindow(Win); 19132001f49Smrg} 19232001f49Smrg 19332001f49Smrgstatic GLint NiceFog = 1; 19432001f49Smrg 19532001f49Smrg#define DIMP 20.0 19632001f49Smrg#define DIMTP 16.0 19732001f49Smrg 19832001f49Smrg#define RIDCOL 0.4 19932001f49Smrg 20032001f49Smrg#define NUMTREE 50 20132001f49Smrg#define TREEINR 2.5 20232001f49Smrg#define TREEOUTR 8.0 20332001f49Smrg 20432001f49Smrg#define AGRAV -9.8 20532001f49Smrg 20632001f49Smrgtypedef struct 20732001f49Smrg{ 20832001f49Smrg int age; 20932001f49Smrg float p[3][3]; 21032001f49Smrg float v[3]; 21132001f49Smrg float c[3][4]; 21232001f49Smrg} 21332001f49Smrg part; 21432001f49Smrg 21532001f49Smrgstatic float treepos[NUMTREE][3]; 21632001f49Smrg 21732001f49Smrgstatic float black[3] = { 0.0, 0.0, 0.0 }; 21832001f49Smrgstatic float blu[3] = { 1.0, 0.2, 0.0 }; 21932001f49Smrgstatic float blu2[3] = { 1.0, 1.0, 0.0 }; 22032001f49Smrg 22132001f49Smrgstatic float fogcolor[4] = { 1.0, 1.0, 1.0, 1.0 }; 22232001f49Smrg 22332001f49Smrgstatic float q[4][3] = { 22432001f49Smrg {-DIMP, 0.0, -DIMP}, 22532001f49Smrg {DIMP, 0.0, -DIMP}, 22632001f49Smrg {DIMP, 0.0, DIMP}, 22732001f49Smrg {-DIMP, 0.0, DIMP} 22832001f49Smrg}; 22932001f49Smrg 23032001f49Smrgstatic float qt[4][2] = { 23132001f49Smrg {-DIMTP, -DIMTP}, 23232001f49Smrg {DIMTP, -DIMTP}, 23332001f49Smrg {DIMTP, DIMTP}, 23432001f49Smrg {-DIMTP, DIMTP} 23532001f49Smrg}; 23632001f49Smrg 23732001f49Smrgstatic int np; 23832001f49Smrgstatic float eject_r, dt, maxage, eject_vy, eject_vl; 23932001f49Smrgstatic short shadows; 24032001f49Smrgstatic float ridtri; 24132001f49Smrgstatic int fog = 0; 24232001f49Smrgstatic int help = 1; 24332001f49Smrg 24432001f49Smrgstatic part *p; 24532001f49Smrg 24632001f49Smrgstatic GLuint groundid; 24732001f49Smrgstatic GLuint treeid; 24832001f49Smrg 24932001f49Smrgstatic float obs[3] = { 2.0, 1.0, 0.0 }; 25032001f49Smrgstatic float dir[3]; 25132001f49Smrgstatic float v = 0.0; 25232001f49Smrgstatic float alpha = -84.0; 25332001f49Smrgstatic float beta = 90.0; 25432001f49Smrg 25532001f49Smrgstatic float 25632001f49Smrgvrnd(void) 25732001f49Smrg{ 25832001f49Smrg return (((float) rand()) / RAND_MAX); 25932001f49Smrg} 26032001f49Smrg 26132001f49Smrgstatic void 26232001f49Smrgsetnewpart(part * p) 26332001f49Smrg{ 26432001f49Smrg float a, v[3], *c; 26532001f49Smrg 26632001f49Smrg p->age = 0; 26732001f49Smrg 26832001f49Smrg a = vrnd() * 3.14159265359 * 2.0; 26932001f49Smrg 27032001f49Smrg vinit(v, sin(a) * eject_r * vrnd(), 0.15, cos(a) * eject_r * vrnd()); 27132001f49Smrg vinit(p->p[0], v[0] + vrnd() * ridtri, v[1] + vrnd() * ridtri, 27232001f49Smrg v[2] + vrnd() * ridtri); 27332001f49Smrg vinit(p->p[1], v[0] + vrnd() * ridtri, v[1] + vrnd() * ridtri, 27432001f49Smrg v[2] + vrnd() * ridtri); 27532001f49Smrg vinit(p->p[2], v[0] + vrnd() * ridtri, v[1] + vrnd() * ridtri, 27632001f49Smrg v[2] + vrnd() * ridtri); 27732001f49Smrg 27832001f49Smrg vinit(p->v, v[0] * eject_vl / (eject_r / 2), 27932001f49Smrg vrnd() * eject_vy + eject_vy / 2, v[2] * eject_vl / (eject_r / 2)); 28032001f49Smrg 28132001f49Smrg c = blu; 28232001f49Smrg 28332001f49Smrg vinit4(p->c[0], c[0] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 28432001f49Smrg c[1] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 28532001f49Smrg c[2] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 1.0); 28632001f49Smrg vinit4(p->c[1], c[0] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 28732001f49Smrg c[1] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 28832001f49Smrg c[2] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 1.0); 28932001f49Smrg vinit4(p->c[2], c[0] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 29032001f49Smrg c[1] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 29132001f49Smrg c[2] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 1.0); 29232001f49Smrg} 29332001f49Smrg 29432001f49Smrgstatic void 29532001f49Smrgsetpart(part * p) 29632001f49Smrg{ 29732001f49Smrg float fact; 29832001f49Smrg 29932001f49Smrg if (p->p[0][1] < 0.1) { 30032001f49Smrg setnewpart(p); 30132001f49Smrg return; 30232001f49Smrg } 30332001f49Smrg 30432001f49Smrg p->v[1] += AGRAV * dt; 30532001f49Smrg 30632001f49Smrg vadds(p->p[0], dt, p->v); 30732001f49Smrg vadds(p->p[1], dt, p->v); 30832001f49Smrg vadds(p->p[2], dt, p->v); 30932001f49Smrg 31032001f49Smrg p->age++; 31132001f49Smrg 31232001f49Smrg if ((p->age) > maxage) { 31332001f49Smrg vequ(p->c[0], blu2); 31432001f49Smrg vequ(p->c[1], blu2); 31532001f49Smrg vequ(p->c[2], blu2); 31632001f49Smrg } 31732001f49Smrg else { 31832001f49Smrg fact = 1.0 / maxage; 31932001f49Smrg vadds(p->c[0], fact, blu2); 32032001f49Smrg vclamp(p->c[0]); 32132001f49Smrg p->c[0][3] = fact * (maxage - p->age); 32232001f49Smrg 32332001f49Smrg vadds(p->c[1], fact, blu2); 32432001f49Smrg vclamp(p->c[1]); 32532001f49Smrg p->c[1][3] = fact * (maxage - p->age); 32632001f49Smrg 32732001f49Smrg vadds(p->c[2], fact, blu2); 32832001f49Smrg vclamp(p->c[2]); 32932001f49Smrg p->c[2][3] = fact * (maxage - p->age); 33032001f49Smrg } 33132001f49Smrg} 33232001f49Smrg 33332001f49Smrgstatic void 33432001f49Smrgdrawtree(float x, float y, float z) 33532001f49Smrg{ 33632001f49Smrg glBegin(GL_QUADS); 33732001f49Smrg glTexCoord2f(0.0, 0.0); 33832001f49Smrg glVertex3f(x - 1.5, y + 0.0, z); 33932001f49Smrg 34032001f49Smrg glTexCoord2f(1.0, 0.0); 34132001f49Smrg glVertex3f(x + 1.5, y + 0.0, z); 34232001f49Smrg 34332001f49Smrg glTexCoord2f(1.0, 1.0); 34432001f49Smrg glVertex3f(x + 1.5, y + 3.0, z); 34532001f49Smrg 34632001f49Smrg glTexCoord2f(0.0, 1.0); 34732001f49Smrg glVertex3f(x - 1.5, y + 3.0, z); 34832001f49Smrg 34932001f49Smrg 35032001f49Smrg glTexCoord2f(0.0, 0.0); 35132001f49Smrg glVertex3f(x, y + 0.0, z - 1.5); 35232001f49Smrg 35332001f49Smrg glTexCoord2f(1.0, 0.0); 35432001f49Smrg glVertex3f(x, y + 0.0, z + 1.5); 35532001f49Smrg 35632001f49Smrg glTexCoord2f(1.0, 1.0); 35732001f49Smrg glVertex3f(x, y + 3.0, z + 1.5); 35832001f49Smrg 35932001f49Smrg glTexCoord2f(0.0, 1.0); 36032001f49Smrg glVertex3f(x, y + 3.0, z - 1.5); 36132001f49Smrg 36232001f49Smrg glEnd(); 36332001f49Smrg 36432001f49Smrg} 36532001f49Smrg 36632001f49Smrgstatic void 36732001f49Smrgcalcposobs(void) 36832001f49Smrg{ 36932001f49Smrg dir[0] = sin(alpha * M_PI / 180.0); 37032001f49Smrg dir[2] = cos(alpha * M_PI / 180.0) * sin(beta * M_PI / 180.0); 37132001f49Smrg dir[1] = cos(beta * M_PI / 180.0); 37232001f49Smrg 37332001f49Smrg if (dir[0] < 1.0e-5 && dir[0] > -1.0e-5) 37432001f49Smrg dir[0] = 0; 37532001f49Smrg if (dir[1] < 1.0e-5 && dir[1] > -1.0e-5) 37632001f49Smrg dir[1] = 0; 37732001f49Smrg if (dir[2] < 1.0e-5 && dir[2] > -1.0e-5) 37832001f49Smrg dir[2] = 0; 37932001f49Smrg 38032001f49Smrg obs[0] += v * dir[0]; 38132001f49Smrg obs[1] += v * dir[1]; 38232001f49Smrg obs[2] += v * dir[2]; 38332001f49Smrg} 38432001f49Smrg 38532001f49Smrgstatic void 38632001f49Smrgprintstring(void *font, const char *string) 38732001f49Smrg{ 38832001f49Smrg int len, i; 38932001f49Smrg 39032001f49Smrg len = (int) strlen(string); 39132001f49Smrg for (i = 0; i < len; i++) 39232001f49Smrg glutBitmapCharacter(font, string[i]); 39332001f49Smrg} 39432001f49Smrg 39532001f49Smrg 39632001f49Smrgstatic void 39732001f49Smrgprinthelp(void) 39832001f49Smrg{ 39932001f49Smrg glColor4f(0.0, 0.0, 0.0, 0.5); 40032001f49Smrg glRecti(40, 40, 600, 440); 40132001f49Smrg 40232001f49Smrg glColor3f(1.0, 0.0, 0.0); 40332001f49Smrg glRasterPos2i(300, 420); 40432001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Help"); 40532001f49Smrg 40632001f49Smrg glRasterPos2i(60, 390); 40732001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "h - Toggle Help"); 40832001f49Smrg 40932001f49Smrg glRasterPos2i(60, 360); 41032001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "t - Increase particle size"); 41132001f49Smrg glRasterPos2i(60, 330); 41232001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "T - Decrease particle size"); 41332001f49Smrg 41432001f49Smrg glRasterPos2i(60, 300); 41532001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "r - Increase emission radius"); 41632001f49Smrg glRasterPos2i(60, 270); 41732001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "R - Decrease emission radius"); 41832001f49Smrg 41932001f49Smrg glRasterPos2i(60, 240); 42032001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "f - Toggle Fog"); 42132001f49Smrg glRasterPos2i(60, 210); 42232001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "s - Toggle shadows"); 42332001f49Smrg glRasterPos2i(60, 180); 42432001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "q - Toggle texture format & type"); 42532001f49Smrg glRasterPos2i(60, 150); 42632001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "a - Increase velocity"); 42732001f49Smrg glRasterPos2i(60, 120); 42832001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "z - Decrease velocity"); 42932001f49Smrg glRasterPos2i(60, 90); 43032001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Arrow Keys - Rotate"); 43132001f49Smrg} 43232001f49Smrg 43332001f49Smrg 43432001f49Smrgstatic void 43532001f49Smrgdrawfire(void) 43632001f49Smrg{ 43732001f49Smrg static char frbuf[80] = ""; 43832001f49Smrg int j; 43932001f49Smrg static double t0 = -1.; 44032001f49Smrg double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0; 44132001f49Smrg if (t0 < 0.0) 44232001f49Smrg t0 = t; 44332001f49Smrg dt = (t - t0) * 1.0; 44432001f49Smrg t0 = t; 44532001f49Smrg 44632001f49Smrg glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); 44732001f49Smrg 44832001f49Smrg glDisable(GL_LIGHTING); 44932001f49Smrg 45032001f49Smrg glShadeModel(GL_FLAT); 45132001f49Smrg 45232001f49Smrg glEnable(GL_BLEND); 45332001f49Smrg glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 45432001f49Smrg 45532001f49Smrg glEnable(GL_FOG); 45632001f49Smrg glFogi(GL_FOG_MODE, GL_EXP); 45732001f49Smrg glFogfv(GL_FOG_COLOR, fogcolor); 45832001f49Smrg glFogf(GL_FOG_DENSITY, 0.1); 45932001f49Smrg 46032001f49Smrg 46132001f49Smrg glViewport(0, 0, (GLint) TexWidth, (GLint) TexHeight); 46232001f49Smrg glMatrixMode(GL_PROJECTION); 46332001f49Smrg glLoadIdentity(); 46432001f49Smrg gluPerspective(70.0, TexWidth/ (float) TexHeight, 0.1, 30.0); 46532001f49Smrg 46632001f49Smrg glMatrixMode(GL_MODELVIEW); 46732001f49Smrg glLoadIdentity(); 46832001f49Smrg 46932001f49Smrg if (NiceFog) 47032001f49Smrg glHint(GL_FOG_HINT, GL_NICEST); 47132001f49Smrg else 47232001f49Smrg glHint(GL_FOG_HINT, GL_DONT_CARE); 47332001f49Smrg 47432001f49Smrg glEnable(GL_DEPTH_TEST); 47532001f49Smrg 47632001f49Smrg if (fog) 47732001f49Smrg glEnable(GL_FOG); 47832001f49Smrg else 47932001f49Smrg glDisable(GL_FOG); 48032001f49Smrg 48132001f49Smrg glDepthMask(GL_TRUE); 48232001f49Smrg glClearColor(1.0, 1.0, 1.0, 1.0); 48332001f49Smrg glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 48432001f49Smrg 48532001f49Smrg 48632001f49Smrg glPushMatrix(); 48732001f49Smrg calcposobs(); 48832001f49Smrg gluLookAt(obs[0], obs[1], obs[2], 48932001f49Smrg obs[0] + dir[0], obs[1] + dir[1], obs[2] + dir[2], 49032001f49Smrg 0.0, 1.0, 0.0); 49132001f49Smrg 49232001f49Smrg glColor4f(1.0, 1.0, 1.0, 1.0); 49332001f49Smrg 49432001f49Smrg glEnable(GL_TEXTURE_2D); 49532001f49Smrg 49632001f49Smrg glBindTexture(GL_TEXTURE_2D, groundid); 49732001f49Smrg glBegin(GL_QUADS); 49832001f49Smrg glTexCoord2fv(qt[0]); 49932001f49Smrg glVertex3fv(q[0]); 50032001f49Smrg glTexCoord2fv(qt[1]); 50132001f49Smrg glVertex3fv(q[1]); 50232001f49Smrg glTexCoord2fv(qt[2]); 50332001f49Smrg glVertex3fv(q[2]); 50432001f49Smrg glTexCoord2fv(qt[3]); 50532001f49Smrg glVertex3fv(q[3]); 50632001f49Smrg glEnd(); 50732001f49Smrg 50832001f49Smrg glEnable(GL_ALPHA_TEST); 50932001f49Smrg glAlphaFunc(GL_GEQUAL, 0.9); 51032001f49Smrg 51132001f49Smrg glBindTexture(GL_TEXTURE_2D, treeid); 51232001f49Smrg for (j = 0; j < NUMTREE; j++) 51332001f49Smrg drawtree(treepos[j][0], treepos[j][1], treepos[j][2]); 51432001f49Smrg 51532001f49Smrg glDisable(GL_TEXTURE_2D); 51632001f49Smrg glDepthMask(GL_FALSE); 51732001f49Smrg glDisable(GL_ALPHA_TEST); 51832001f49Smrg 51932001f49Smrg if (shadows) { 52032001f49Smrg glBegin(GL_TRIANGLES); 52132001f49Smrg for (j = 0; j < np; j++) { 52232001f49Smrg glColor4f(black[0], black[1], black[2], p[j].c[0][3]); 52332001f49Smrg glVertex3f(p[j].p[0][0], 0.1, p[j].p[0][2]); 52432001f49Smrg 52532001f49Smrg glColor4f(black[0], black[1], black[2], p[j].c[1][3]); 52632001f49Smrg glVertex3f(p[j].p[1][0], 0.1, p[j].p[1][2]); 52732001f49Smrg 52832001f49Smrg glColor4f(black[0], black[1], black[2], p[j].c[2][3]); 52932001f49Smrg glVertex3f(p[j].p[2][0], 0.1, p[j].p[2][2]); 53032001f49Smrg } 53132001f49Smrg glEnd(); 53232001f49Smrg } 53332001f49Smrg 53432001f49Smrg glBegin(GL_TRIANGLES); 53532001f49Smrg for (j = 0; j < np; j++) { 53632001f49Smrg glColor4fv(p[j].c[0]); 53732001f49Smrg glVertex3fv(p[j].p[0]); 53832001f49Smrg 53932001f49Smrg glColor4fv(p[j].c[1]); 54032001f49Smrg glVertex3fv(p[j].p[1]); 54132001f49Smrg 54232001f49Smrg glColor4fv(p[j].c[2]); 54332001f49Smrg glVertex3fv(p[j].p[2]); 54432001f49Smrg 54532001f49Smrg setpart(&p[j]); 54632001f49Smrg } 54732001f49Smrg glEnd(); 54832001f49Smrg 54932001f49Smrg 55032001f49Smrg glDisable(GL_TEXTURE_2D); 55132001f49Smrg glDisable(GL_ALPHA_TEST); 55232001f49Smrg glDisable(GL_DEPTH_TEST); 55332001f49Smrg glDisable(GL_FOG); 55432001f49Smrg 55532001f49Smrg glMatrixMode(GL_PROJECTION); 55632001f49Smrg glLoadIdentity(); 55732001f49Smrg glOrtho(-0.5, 639.5, -0.5, 479.5 55832001f49Smrg , -1.0, 1.0); 55932001f49Smrg glMatrixMode(GL_MODELVIEW); 56032001f49Smrg glLoadIdentity(); 56132001f49Smrg 56232001f49Smrg glColor3f(1.0, 0.0, 0.0); 56332001f49Smrg glRasterPos2i(10, 10); 56432001f49Smrg printstring(GLUT_BITMAP_HELVETICA_18, frbuf); 56532001f49Smrg glColor3f(0.0, 0.0, 1.0); 56632001f49Smrg glRasterPos2i(10, 450); 56732001f49Smrg printstring(GLUT_BITMAP_HELVETICA_18, texNames[texType]); 56832001f49Smrg glColor3f(1.0, 0.0, 0.0); 56932001f49Smrg glRasterPos2i(10, 470); 57032001f49Smrg printstring(GLUT_BITMAP_HELVETICA_10, 57132001f49Smrg "Fire V1.5 Written by David Bucciarelli (tech.hmw@plus.it)"); 57232001f49Smrg 57332001f49Smrg if (help) 57432001f49Smrg printhelp(); 57532001f49Smrg 57632001f49Smrg glPopMatrix(); 57732001f49Smrg glDepthMask(GL_TRUE); 57832001f49Smrg glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 57932001f49Smrg Frames++; 58032001f49Smrg 58132001f49Smrg { 58232001f49Smrg GLint t = glutGet(GLUT_ELAPSED_TIME); 58332001f49Smrg if (t - T0 >= 2000) { 58432001f49Smrg GLfloat seconds = (t - T0) / 1000.0; 58532001f49Smrg GLfloat fps = Frames / seconds; 58632001f49Smrg sprintf(frbuf, "Frame rate: %f", fps); 5877ec3b29aSmrg printf("%s\n", frbuf); 5887ec3b29aSmrg fflush(stdout); 58932001f49Smrg T0 = t; 59032001f49Smrg Frames = 0; 59132001f49Smrg } 59232001f49Smrg } 59332001f49Smrg 59432001f49Smrg} 59532001f49Smrg 59632001f49Smrgstatic void 59732001f49Smrgregen_texImage(void) 59832001f49Smrg{ 59932001f49Smrg glBindTexture(GL_TEXTURE_2D, TexObj); 60032001f49Smrg glTexImage2D(GL_TEXTURE_2D, 0, TEXINTFORMAT, TexWidth, TexHeight, 0, 60132001f49Smrg texFormats[texType], texTypes[texType], NULL); 60232001f49Smrg glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); 60332001f49Smrg glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, 60432001f49Smrg GL_TEXTURE_2D, TexObj, 0); 60532001f49Smrg glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 60632001f49Smrg} 60732001f49Smrg 60832001f49Smrgstatic void 60932001f49Smrgkey(unsigned char key, int x, int y) 61032001f49Smrg{ 61132001f49Smrg switch (key) { 61232001f49Smrg case 27: 61332001f49Smrg cleanup(); 61432001f49Smrg exit(0); 61532001f49Smrg break; 61632001f49Smrg case ' ': 61732001f49Smrg Anim = !Anim; 61832001f49Smrg glutIdleFunc(Anim ? idle : NULL); 61932001f49Smrg break; 62032001f49Smrg case 'a': 62132001f49Smrg v += 0.0005; 62232001f49Smrg break; 62332001f49Smrg case 'z': 62432001f49Smrg v -= 0.0005; 62532001f49Smrg break; 62632001f49Smrg case 'h': 62732001f49Smrg help = (!help); 62832001f49Smrg break; 62932001f49Smrg case 'f': 63032001f49Smrg fog = (!fog); 63132001f49Smrg break; 63232001f49Smrg case 's': 63332001f49Smrg shadows = !shadows; 63432001f49Smrg break; 63532001f49Smrg case 'R': 63632001f49Smrg eject_r -= 0.03; 63732001f49Smrg break; 63832001f49Smrg case 'r': 63932001f49Smrg eject_r += 0.03; 64032001f49Smrg break; 64132001f49Smrg case 't': 64232001f49Smrg ridtri += 0.005; 64332001f49Smrg break; 64432001f49Smrg case 'T': 64532001f49Smrg ridtri -= 0.005; 64632001f49Smrg break; 64732001f49Smrg case 'v': 64832001f49Smrg ViewRotZ += 5.0; 64932001f49Smrg break; 65032001f49Smrg case 'V': 65132001f49Smrg ViewRotZ -= 5.0; 65232001f49Smrg break; 65332001f49Smrg case 'w': 65432001f49Smrg WireFrame = !WireFrame; 65532001f49Smrg break; 65632001f49Smrg case 'q': 65732001f49Smrg if (++texType > 16) 65832001f49Smrg texType = 0; 65932001f49Smrg regen_texImage(); 66032001f49Smrg break; 66132001f49Smrg case 'n': 66232001f49Smrg NiceFog = !NiceFog; 66332001f49Smrg printf("NiceFog %d\n", NiceFog); 66432001f49Smrg break; 66532001f49Smrg } 66632001f49Smrg glutPostRedisplay(); 66732001f49Smrg} 66832001f49Smrg 66932001f49Smrgstatic void 67032001f49Smrginittextures(void) 67132001f49Smrg{ 67232001f49Smrg GLenum gluerr; 67332001f49Smrg GLubyte tex[128][128][4]; 67432001f49Smrg 67532001f49Smrg glGenTextures(1, &groundid); 67632001f49Smrg glBindTexture(GL_TEXTURE_2D, groundid); 67732001f49Smrg 67832001f49Smrg glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 67932001f49Smrg if (!LoadRGBMipmaps(DEMOS_DATA_DIR "s128.rgb", GL_RGB)) { 68032001f49Smrg fprintf(stderr, "Error reading a texture.\n"); 68132001f49Smrg exit(-1); 68232001f49Smrg } 68332001f49Smrg 68432001f49Smrg glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 68532001f49Smrg glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 68632001f49Smrg 68732001f49Smrg glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 68832001f49Smrg GL_LINEAR_MIPMAP_LINEAR); 68932001f49Smrg glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 69032001f49Smrg 69132001f49Smrg glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); 69232001f49Smrg 69332001f49Smrg glGenTextures(1, &treeid); 69432001f49Smrg glBindTexture(GL_TEXTURE_2D, treeid); 69532001f49Smrg 69632001f49Smrg if (1) 69732001f49Smrg { 69832001f49Smrg int w, h; 69932001f49Smrg GLenum format; 70032001f49Smrg int x, y; 70132001f49Smrg GLubyte *image = LoadRGBImage(DEMOS_DATA_DIR "tree3.rgb", 70232001f49Smrg &w, &h, &format); 70332001f49Smrg 70432001f49Smrg if (!image) { 70532001f49Smrg fprintf(stderr, "Error reading a texture.\n"); 70632001f49Smrg exit(-1); 70732001f49Smrg } 70832001f49Smrg 70932001f49Smrg for (y = 0; y < 128; y++) 71032001f49Smrg for (x = 0; x < 128; x++) { 71132001f49Smrg tex[x][y][0] = image[(y + x * 128) * 3]; 71232001f49Smrg tex[x][y][1] = image[(y + x * 128) * 3 + 1]; 71332001f49Smrg tex[x][y][2] = image[(y + x * 128) * 3 + 2]; 71432001f49Smrg if ((tex[x][y][0] == tex[x][y][1]) && 71532001f49Smrg (tex[x][y][1] == tex[x][y][2]) && (tex[x][y][2] == 255)) 71632001f49Smrg tex[x][y][3] = 0; 71732001f49Smrg else 71832001f49Smrg tex[x][y][3] = 255; 71932001f49Smrg } 72032001f49Smrg 72132001f49Smrg if ((gluerr = gluBuild2DMipmaps(GL_TEXTURE_2D, 4, 128, 128, GL_RGBA, 72232001f49Smrg GL_UNSIGNED_BYTE, (GLvoid *) (tex)))) { 72332001f49Smrg fprintf(stderr, "GLULib%s\n", (char *) gluErrorString(gluerr)); 72432001f49Smrg exit(-1); 72532001f49Smrg } 72632001f49Smrg } 72732001f49Smrg else { 72832001f49Smrg if (!LoadRGBMipmaps(DEMOS_DATA_DIR "tree2.rgba", GL_RGBA)) { 72932001f49Smrg fprintf(stderr, "Error reading a texture.\n"); 73032001f49Smrg exit(-1); 73132001f49Smrg } 73232001f49Smrg } 73332001f49Smrg 73432001f49Smrg glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 73532001f49Smrg glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 73632001f49Smrg 73732001f49Smrg glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 73832001f49Smrg GL_LINEAR_MIPMAP_LINEAR); 73932001f49Smrg glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 74032001f49Smrg 74132001f49Smrg glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 74232001f49Smrg} 74332001f49Smrg 74432001f49Smrgstatic void 74532001f49Smrginittree(void) 74632001f49Smrg{ 74732001f49Smrg int i; 74832001f49Smrg float dist; 74932001f49Smrg 75032001f49Smrg for (i = 0; i < NUMTREE; i++) 75132001f49Smrg do { 75232001f49Smrg treepos[i][0] = vrnd() * TREEOUTR * 2.0 - TREEOUTR; 75332001f49Smrg treepos[i][1] = 0.0; 75432001f49Smrg treepos[i][2] = vrnd() * TREEOUTR * 2.0 - TREEOUTR; 75532001f49Smrg dist = 75632001f49Smrg sqrt(treepos[i][0] * treepos[i][0] + 75732001f49Smrg treepos[i][2] * treepos[i][2]); 75832001f49Smrg } while ((dist < TREEINR) || (dist > TREEOUTR)); 75932001f49Smrg} 76032001f49Smrg 76132001f49Smrgstatic int 76232001f49Smrginit_fire(int ac, char *av[]) 76332001f49Smrg{ 76432001f49Smrg int i; 76532001f49Smrg 76632001f49Smrg np = 800; 76732001f49Smrg eject_r = -0.65; 76832001f49Smrg dt = 0.015; 76932001f49Smrg eject_vy = 4; 77032001f49Smrg eject_vl = 1; 77132001f49Smrg shadows = 1; 77232001f49Smrg ridtri = 0.25; 77332001f49Smrg 77432001f49Smrg maxage = 1.0 / dt; 77532001f49Smrg 77632001f49Smrg if (ac == 2) 77732001f49Smrg np = atoi(av[1]); 77832001f49Smrg 77932001f49Smrg 78032001f49Smrg inittextures(); 78132001f49Smrg 78232001f49Smrg p = (part *) malloc(sizeof(part) * np); 78332001f49Smrg 78432001f49Smrg for (i = 0; i < np; i++) 78532001f49Smrg setnewpart(&p[i]); 78632001f49Smrg 78732001f49Smrg inittree(); 78832001f49Smrg 78932001f49Smrg return (0); 79032001f49Smrg} 79132001f49Smrg 79232001f49Smrg 79332001f49Smrg 79432001f49Smrg 79532001f49Smrg 79632001f49Smrg 79732001f49Smrgstatic void 79832001f49SmrgDrawCube(void) 79932001f49Smrg{ 80032001f49Smrg static const GLfloat texcoords[4][2] = { 80132001f49Smrg { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 } 80232001f49Smrg }; 80332001f49Smrg static const GLfloat vertices[4][2] = { 80432001f49Smrg { -1, -1 }, { 1, -1 }, { 1, 1 }, { -1, 1 } 80532001f49Smrg }; 80632001f49Smrg static const GLfloat xforms[6][4] = { 80732001f49Smrg { 0, 0, 1, 0 }, 80832001f49Smrg { 90, 0, 1, 0 }, 80932001f49Smrg { 180, 0, 1, 0 }, 81032001f49Smrg { 270, 0, 1, 0 }, 81132001f49Smrg { 90, 1, 0, 0 }, 81232001f49Smrg { -90, 1, 0, 0 } 81332001f49Smrg }; 81432001f49Smrg static const GLfloat mat[4] = { 1.0, 1.0, 0.5, 1.0 }; 81532001f49Smrg GLint i, j; 81632001f49Smrg 81732001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat); 81832001f49Smrg glEnable(GL_TEXTURE_2D); 81932001f49Smrg 82032001f49Smrg glPushMatrix(); 82132001f49Smrg glRotatef(ViewRotX, 1.0, 0.0, 0.0); 82232001f49Smrg glRotatef(15, 1, 0, 0); 82332001f49Smrg glRotatef(CubeRot, 0, 1, 0); 82432001f49Smrg glScalef(4, 4, 4); 82532001f49Smrg 82632001f49Smrg for (i = 0; i < 6; i++) { 82732001f49Smrg glPushMatrix(); 82832001f49Smrg glRotatef(xforms[i][0], xforms[i][1], xforms[i][2], xforms[i][3]); 82932001f49Smrg glTranslatef(0, 0, 1.1); 83032001f49Smrg glBegin(GL_POLYGON); 83132001f49Smrg glNormal3f(0, 0, 1); 83232001f49Smrg for (j = 0; j < 4; j++) { 83332001f49Smrg glTexCoord2fv(texcoords[j]); 83432001f49Smrg glVertex2fv(vertices[j]); 83532001f49Smrg } 83632001f49Smrg glEnd(); 83732001f49Smrg glPopMatrix(); 83832001f49Smrg } 83932001f49Smrg glPopMatrix(); 84032001f49Smrg 84132001f49Smrg glDisable(GL_TEXTURE_2D); 84232001f49Smrg} 84332001f49Smrg 84432001f49Smrg 84532001f49Smrgstatic void 84632001f49Smrgdraw(void) 84732001f49Smrg{ 84832001f49Smrg float ar; 84932001f49Smrg static GLfloat pos[4] = {5.0, 5.0, 10.0, 0.0}; 85032001f49Smrg 85132001f49Smrg drawfire(); 85232001f49Smrg 85332001f49Smrg glLightfv(GL_LIGHT0, GL_POSITION, pos); 85432001f49Smrg glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, 85532001f49Smrg GL_SEPARATE_SPECULAR_COLOR); 85632001f49Smrg 85732001f49Smrg glEnable(GL_LIGHTING); 85832001f49Smrg glEnable(GL_LIGHT0); 85932001f49Smrg glEnable(GL_DEPTH_TEST); 86032001f49Smrg glEnable(GL_NORMALIZE); 86132001f49Smrg glDisable(GL_BLEND); 86232001f49Smrg glDisable(GL_FOG); 86332001f49Smrg 86432001f49Smrg glMatrixMode(GL_MODELVIEW); 86532001f49Smrg glLoadIdentity(); 86632001f49Smrg glTranslatef(0.0, 0.0, -40.0); 86732001f49Smrg 86832001f49Smrg glClear(GL_DEPTH_BUFFER_BIT); 86932001f49Smrg 87032001f49Smrg /* draw textured cube */ 87132001f49Smrg 87232001f49Smrg glViewport(0, 0, WinWidth, WinHeight); 87332001f49Smrg glClearColor(0.5, 0.5, 0.8, 0.0); 87432001f49Smrg glClear(GL_COLOR_BUFFER_BIT); 87532001f49Smrg 87632001f49Smrg ar = (float) (WinWidth) / WinHeight; 87732001f49Smrg glMatrixMode(GL_PROJECTION); 87832001f49Smrg glLoadIdentity(); 87932001f49Smrg glFrustum(-ar, ar, -1.0, 1.0, 5.0, 60.0); 88032001f49Smrg glMatrixMode(GL_MODELVIEW); 88132001f49Smrg glBindTexture(GL_TEXTURE_2D, TexObj); 88232001f49Smrg 88332001f49Smrg DrawCube(); 88432001f49Smrg 88532001f49Smrg /* finish up */ 88632001f49Smrg glutSwapBuffers(); 88732001f49Smrg} 88832001f49Smrg 88932001f49Smrg 89032001f49Smrgstatic void 89132001f49Smrgidle(void) 89232001f49Smrg{ 89332001f49Smrg static double t0 = -1.; 89432001f49Smrg double dt, t = glutGet(GLUT_ELAPSED_TIME) / 1000.0; 89532001f49Smrg if (t0 < 0.0) 89632001f49Smrg t0 = t; 89732001f49Smrg dt = t - t0; 89832001f49Smrg t0 = t; 89932001f49Smrg 90032001f49Smrg CubeRot = fmod(CubeRot + 15.0 * dt, 360.0); /* 15 deg/sec */ 90132001f49Smrg 90232001f49Smrg glutPostRedisplay(); 90332001f49Smrg} 90432001f49Smrg 90532001f49Smrg 90632001f49Smrg/* change view angle */ 90732001f49Smrgstatic void 90832001f49Smrgspecial(int k, int x, int y) 90932001f49Smrg{ 91032001f49Smrg (void) x; 91132001f49Smrg (void) y; 91232001f49Smrg switch (k) { 91332001f49Smrg case GLUT_KEY_UP: 91432001f49Smrg ViewRotX += 5.0; 91532001f49Smrg break; 91632001f49Smrg case GLUT_KEY_DOWN: 91732001f49Smrg ViewRotX -= 5.0; 91832001f49Smrg break; 91932001f49Smrg case GLUT_KEY_LEFT: 92032001f49Smrg ViewRotY += 5.0; 92132001f49Smrg break; 92232001f49Smrg case GLUT_KEY_RIGHT: 92332001f49Smrg ViewRotY -= 5.0; 92432001f49Smrg break; 92532001f49Smrg default: 92632001f49Smrg return; 92732001f49Smrg } 92832001f49Smrg glutPostRedisplay(); 92932001f49Smrg} 93032001f49Smrg 93132001f49Smrg 93232001f49Smrg/* new window size or exposure */ 93332001f49Smrgstatic void 93432001f49Smrgreshape(int width, int height) 93532001f49Smrg{ 93632001f49Smrg WinWidth = width; 93732001f49Smrg WinHeight = height; 93832001f49Smrg} 93932001f49Smrg 94032001f49Smrg 94132001f49Smrgstatic void 94232001f49Smrginit_fbotexture(void) 94332001f49Smrg{ 94432001f49Smrg static const GLenum depthFormats[] = { 94532001f49Smrg GL_DEPTH_COMPONENT, 94632001f49Smrg GL_DEPTH_COMPONENT16, 94732001f49Smrg GL_DEPTH_COMPONENT32 94832001f49Smrg }; 94932001f49Smrg static int numDepthFormats = sizeof(depthFormats) / sizeof(depthFormats[0]); 95032001f49Smrg GLint i; 95132001f49Smrg GLenum stat; 95232001f49Smrg 95332001f49Smrg /* gen framebuffer id, delete it, do some assertions, just for testing */ 95432001f49Smrg glGenFramebuffersEXT(1, &MyFB); 95532001f49Smrg glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); 95632001f49Smrg glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &i); 95732001f49Smrg 95832001f49Smrg /* Make texture object/image */ 95932001f49Smrg glGenTextures(1, &TexObj); 96032001f49Smrg glBindTexture(GL_TEXTURE_2D, TexObj); 96132001f49Smrg /* make one image level. */ 96232001f49Smrg glTexImage2D(GL_TEXTURE_2D, 0, TEXINTFORMAT, TexWidth, TexHeight, 0, 96332001f49Smrg texFormats[texType], texTypes[texType], NULL); 96432001f49Smrg 96532001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 96632001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 96732001f49Smrg glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 96832001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); 96932001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); 97032001f49Smrg 97132001f49Smrg CheckError(__LINE__); 97232001f49Smrg 97332001f49Smrg /* Render color to texture */ 97432001f49Smrg glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, 97532001f49Smrg GL_TEXTURE_2D, TexObj, 0); 97632001f49Smrg CheckError(__LINE__); 97732001f49Smrg 97832001f49Smrg 97932001f49Smrg /* make depth renderbuffer */ 98032001f49Smrg glGenRenderbuffersEXT(1, &DepthRB); 98132001f49Smrg glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthRB); 98232001f49Smrg /* we may have to try several formats */ 98332001f49Smrg for (i = 0; i < numDepthFormats; i++) { 98432001f49Smrg glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, depthFormats[i], 98532001f49Smrg TexWidth, TexHeight); 98632001f49Smrg CheckError(__LINE__); 98732001f49Smrg 98832001f49Smrg glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, 98932001f49Smrg GL_RENDERBUFFER_EXT, DepthRB); 99032001f49Smrg CheckError(__LINE__); 99132001f49Smrg stat = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); 99232001f49Smrg if (stat == GL_FRAMEBUFFER_COMPLETE_EXT) { 99332001f49Smrg break; 99432001f49Smrg } 99532001f49Smrg } 99632001f49Smrg 99732001f49Smrg if (stat != GL_FRAMEBUFFER_COMPLETE_EXT) { 99832001f49Smrg fprintf(stderr, "Error: unable to get usable FBO combination!\n"); 99932001f49Smrg exit(1); 100032001f49Smrg } 100132001f49Smrg 100232001f49Smrg glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, 100332001f49Smrg GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i); 100432001f49Smrg CheckError(__LINE__); 100532001f49Smrg printf("Depth renderbuffer size = %d bits\n", i); 100632001f49Smrg 100732001f49Smrg glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 100832001f49Smrg 100932001f49Smrg /* 101032001f49Smrg * Check for completeness. 101132001f49Smrg */ 101232001f49Smrg 101332001f49Smrg} 101432001f49Smrg 101532001f49Smrg 101632001f49Smrgstatic void 101732001f49Smrginit(int argc, char *argv[]) 101832001f49Smrg{ 101932001f49Smrg GLint i; 102032001f49Smrg 102132001f49Smrg if (!glutExtensionSupported("GL_EXT_framebuffer_object")) { 102232001f49Smrg fprintf(stderr, "Sorry, GL_EXT_framebuffer_object is required!\n"); 102332001f49Smrg exit(1); 102432001f49Smrg } 102532001f49Smrg 102632001f49Smrg TexWidth = 512; 102732001f49Smrg TexHeight = 512; 102832001f49Smrg 102932001f49Smrg init_fbotexture(); 103032001f49Smrg init_fire(argc, argv); 103132001f49Smrg 103232001f49Smrg 103332001f49Smrg for ( i=1; i<argc; i++ ) { 103432001f49Smrg if (strcmp(argv[i], "-info")==0) { 103532001f49Smrg printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); 103632001f49Smrg printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); 103732001f49Smrg printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); 103832001f49Smrg printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); 103932001f49Smrg } 104032001f49Smrg } 104132001f49Smrg} 104232001f49Smrg 104332001f49Smrg 104432001f49Smrgstatic void 104532001f49Smrgvisible(int vis) 104632001f49Smrg{ 104732001f49Smrg if (vis == GLUT_VISIBLE) 104832001f49Smrg glutIdleFunc(Anim ? idle : NULL); 104932001f49Smrg else 105032001f49Smrg glutIdleFunc(NULL); 105132001f49Smrg} 105232001f49Smrg 105332001f49Smrg 105432001f49Smrgint 105532001f49Smrgmain(int argc, char *argv[]) 105632001f49Smrg{ 105732001f49Smrg glutInitWindowSize(WinWidth, WinHeight); 105832001f49Smrg glutInit(&argc, argv); 105932001f49Smrg 106032001f49Smrg glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); 106132001f49Smrg 106232001f49Smrg Win = glutCreateWindow("fbo_firecube"); 106332001f49Smrg glewInit(); 106432001f49Smrg init(argc, argv); 106532001f49Smrg 106632001f49Smrg glutDisplayFunc(draw); 106732001f49Smrg glutReshapeFunc(reshape); 106832001f49Smrg glutKeyboardFunc(key); 106932001f49Smrg glutSpecialFunc(special); 107032001f49Smrg glutVisibilityFunc(visible); 107132001f49Smrg 107232001f49Smrg glutMainLoop(); 107332001f49Smrg return 0; /* ANSI C requires main to return int. */ 107432001f49Smrg} 1075