Initial Comit: First commit.
[SauerEngine.git] / src / engine / lensflare.h
blob711da66bfae759f1345b8ee0c8a418f37c7d6cb4
1 static struct flaretype
3 int type; /* flaretex index, 0..5, -1 for 6+random shine */
4 float loc; /* postion on axis */
5 float scale; /* texture scaling */
6 uchar alpha; /* color alpha */
7 } flaretypes[] =
9 {2, 1.30f, 0.04f, 153}, //flares
10 {3, 1.00f, 0.10f, 102},
11 {1, 0.50f, 0.20f, 77},
12 {3, 0.20f, 0.05f, 77},
13 {0, 0.00f, 0.04f, 77},
14 {5, -0.25f, 0.07f, 127},
15 {5, -0.40f, 0.02f, 153},
16 {5, -0.60f, 0.04f, 102},
17 {5, -1.00f, 0.03f, 51},
18 {-1, 1.00f, 0.30f, 255}, //shine - red, green, blue
19 {-2, 1.00f, 0.20f, 255},
20 {-3, 1.00f, 0.25f, 255}
23 struct flare
25 vec o, center;
26 float size;
27 uchar color[3];
28 bool sparkle;
31 VAR(flarelights, 0, 0, 1);
32 VARP(flarecutoff, 0, 1000, 10000);
33 VARP(flaresize, 20, 100, 500);
35 struct flarerenderer : partrenderer
37 int maxflares, numflares;
38 unsigned int shinetime;
39 flare *flares;
41 flarerenderer(const char *texname, int maxflares)
42 : partrenderer(texname, PT_FLARE, 0, 0), maxflares(maxflares), shinetime(0)
44 flares = new flare[maxflares];
46 void reset()
48 numflares = 0;
51 void newflare(vec &o, const vec &center, uchar r, uchar g, uchar b, float mod, float size, bool sun, bool sparkle)
53 if(numflares >= maxflares) return;
54 vec target; //occlusion check (neccessary as depth testing is turned off)
55 if(!raycubelos(o, camera1->o, target)) return;
56 flare &f = flares[numflares++];
57 f.o = o;
58 f.center = center;
59 f.size = size;
60 f.color[0] = uchar(r*mod);
61 f.color[1] = uchar(g*mod);
62 f.color[2] = uchar(b*mod);
63 f.sparkle = sparkle;
66 void addflare(vec &o, uchar r, uchar g, uchar b, bool sun, bool sparkle)
68 //frustrum + fog check
69 if(isvisiblesphere(0.0f, o) > (sun?VFC_FOGGED:VFC_FULL_VISIBLE)) return;
70 //find closest point between camera line of sight and flare pos
71 vec viewdir;
72 vecfromyawpitch(camera1->yaw, camera1->pitch, 1, 0, viewdir);
73 vec flaredir = vec(o).sub(camera1->o);
74 vec center = viewdir.mul(flaredir.dot(viewdir)).add(camera1->o);
75 float mod, size;
76 if(sun) //fixed size
78 mod = 1.0;
79 size = flaredir.magnitude() * flaresize / 100.0f;
81 else
83 mod = (flarecutoff-vec(o).sub(center).squaredlen())/flarecutoff;
84 if(mod < 0.0f) return;
85 size = flaresize / 5.0f;
87 newflare(o, center, r, g, b, mod, size, sun, sparkle);
90 void makelightflares()
92 numflares = 0; //regenerate flarelist each frame
93 shinetime = lastmillis/10;
95 if(editmode || !flarelights) return;
97 const vector<extentity *> &ents = et->getents();
98 vec viewdir;
99 vecfromyawpitch(camera1->yaw, camera1->pitch, 1, 0, viewdir);
100 extern const vector<int> &checklightcache(int x, int y);
101 const vector<int> &lights = checklightcache(int(camera1->o.x), int(camera1->o.y));
102 loopv(lights)
104 entity &e = *ents[lights[i]];
105 if(e.type != ET_LIGHT) continue;
106 bool sun = (e.attr1==0);
107 float radius = float(e.attr1);
108 vec flaredir = vec(e.o).sub(camera1->o);
109 float len = flaredir.magnitude();
110 if(!sun && (len > radius)) continue;
111 if(isvisiblesphere(0.0f, e.o) > (sun?VFC_FOGGED:VFC_FULL_VISIBLE)) continue;
112 vec center = vec(viewdir).mul(flaredir.dot(viewdir)).add(camera1->o);
113 float mod, size;
114 if(sun) //fixed size
116 mod = 1.0;
117 size = len * flaresize / 100.0f;
119 else
121 mod = (radius-len)/radius;
122 size = flaresize / 5.0f;
124 newflare(e.o, center, e.attr2, e.attr3, e.attr4, mod, size, sun, sun);
128 int count()
130 return numflares;
133 bool haswork()
135 return (numflares != 0) && !glaring && !reflecting && !refracting;
138 void render()
140 bool fog = glIsEnabled(GL_FOG)==GL_TRUE;
141 if(fog) glDisable(GL_FOG);
142 defaultshader->set();
143 glDisable(GL_DEPTH_TEST);
144 if(!tex) tex = textureload(texname);
145 glBindTexture(GL_TEXTURE_2D, tex->id);
146 glBegin(GL_QUADS);
147 loopi(numflares)
149 flare *f = flares+i;
150 vec center = f->center;
151 vec axis = vec(f->o).sub(center);
152 uchar color[4] = {f->color[0], f->color[1], f->color[2], 255};
153 loopj(f->sparkle?12:9)
155 const flaretype &ft = flaretypes[j];
156 vec o = vec(axis).mul(ft.loc).add(center);
157 float sz = ft.scale * f->size;
158 int tex = ft.type;
159 if(ft.type < 0) //sparkles - always done last
161 shinetime = (shinetime + 1) % 10;
162 tex = 6+shinetime;
163 color[0] = 0;
164 color[1] = 0;
165 color[2] = 0;
166 color[-ft.type-1] = f->color[-ft.type-1]; //only want a single channel
168 color[3] = ft.alpha;
169 glColor4ubv(color);
170 const float tsz = 0.25; //flares are aranged in 4x4 grid
171 float tx = tsz*(tex&0x03);
172 float ty = tsz*((tex>>2)&0x03);
173 glTexCoord2f(tx, ty+tsz); glVertex3f(o.x+(-camright.x+camup.x)*sz, o.y+(-camright.y+camup.y)*sz, o.z+(-camright.z+camup.z)*sz);
174 glTexCoord2f(tx+tsz, ty+tsz); glVertex3f(o.x+( camright.x+camup.x)*sz, o.y+( camright.y+camup.y)*sz, o.z+( camright.z+camup.z)*sz);
175 glTexCoord2f(tx+tsz, ty); glVertex3f(o.x+( camright.x-camup.x)*sz, o.y+( camright.y-camup.y)*sz, o.z+( camright.z-camup.z)*sz);
176 glTexCoord2f(tx, ty); glVertex3f(o.x+(-camright.x-camup.x)*sz, o.y+(-camright.y-camup.y)*sz, o.z+(-camright.z-camup.z)*sz);
179 glEnd();
180 glEnable(GL_DEPTH_TEST);
181 if(fog) glEnable(GL_FOG);
184 //square per round hole - use addflare(..) instead
185 particle *addpart(const vec &o, const vec &d, int fade, int color, float size) { return NULL; }
187 static flarerenderer flares("packages/particles/lensflares.png", 64);