misc cleanups

master
Lee Salzman 2013-05-16 22:47:48 +03:00
parent 4ca29d1278
commit 851c658147
7 changed files with 345 additions and 299 deletions

View File

@ -2,58 +2,92 @@ VARP(softexplosion, 0, 1, 1);
VARP(softexplosionblend, 1, 16, 64);
//cache our unit hemisphere
static GLushort *hemiindices = NULL;
static vec *hemiverts = NULL;
static int heminumverts = 0, heminumindices = 0;
static GLuint hemivbuf = 0, hemiebuf = 0;
static void subdivide(int depth, int face);
static void genface(int depth, int i1, int i2, int i3)
namespace hemisphere
{
int face = heminumindices; heminumindices += 3;
hemiindices[face] = i1;
hemiindices[face+1] = i2;
hemiindices[face+2] = i3;
subdivide(depth, face);
}
GLushort *indices = NULL;
vec *verts = NULL;
int numverts = 0, numindices = 0;
GLuint vbuf = 0, ebuf = 0;
static void subdivide(int depth, int face)
{
if(depth-- <= 0) return;
int idx[6];
loopi(3) idx[i] = hemiindices[face+i];
loopi(3)
void subdivide(int depth, int face);
void genface(int depth, int i1, int i2, int i3)
{
int vert = heminumverts++;
hemiverts[vert] = vec(hemiverts[idx[i]]).add(hemiverts[idx[(i+1)%3]]).normalize(); //push on to unit sphere
idx[3+i] = vert;
hemiindices[face+i] = vert;
int face = numindices; numindices += 3;
indices[face] = i1;
indices[face+1] = i2;
indices[face+2] = i3;
subdivide(depth, face);
}
subdivide(depth, face);
loopi(3) genface(depth, idx[i], idx[3+i], idx[3+(i+2)%3]);
}
//subdiv version wobble much more nicely than a lat/longitude version
static void inithemisphere(int hres, int depth)
{
const int tris = hres << (2*depth);
heminumverts = heminumindices = 0;
hemiverts = new vec[tris+1];
hemiindices = new GLushort[tris*3];
hemiverts[heminumverts++] = vec(0.0f, 0.0f, 1.0f); //build initial 'hres' sided pyramid
loopi(hres) hemiverts[heminumverts++] = vec(sincos360[(360*i)/hres], 0.0f);
loopi(hres) genface(depth, 0, i+1, 1+(i+1)%hres);
void subdivide(int depth, int face)
{
if(depth-- <= 0) return;
int idx[6];
loopi(3) idx[i] = indices[face+i];
loopi(3)
{
int curvert = numverts++;
verts[curvert] = vec(verts[idx[i]]).add(verts[idx[(i+1)%3]]).normalize(); //push on to unit sphere
idx[3+i] = curvert;
indices[face+i] = curvert;
}
subdivide(depth, face);
loopi(3) genface(depth, idx[i], idx[3+i], idx[3+(i+2)%3]);
}
if(!hemivbuf) glGenBuffers_(1, &hemivbuf);
glBindBuffer_(GL_ARRAY_BUFFER, hemivbuf);
glBufferData_(GL_ARRAY_BUFFER, heminumverts*sizeof(vec), hemiverts, GL_STATIC_DRAW);
DELETEA(hemiverts);
//subdiv version wobble much more nicely than a lat/longitude version
void init(int hres, int depth)
{
const int tris = hres << (2*depth);
numverts = numindices = 0;
verts = new vec[tris+1];
indices = new GLushort[tris*3];
verts[numverts++] = vec(0.0f, 0.0f, 1.0f); //build initial 'hres' sided pyramid
loopi(hres) verts[numverts++] = vec(sincos360[(360*i)/hres], 0.0f);
loopi(hres) genface(depth, 0, i+1, 1+(i+1)%hres);
if(!hemiebuf) glGenBuffers_(1, &hemiebuf);
glBindBuffer_(GL_ELEMENT_ARRAY_BUFFER, hemiebuf);
glBufferData_(GL_ELEMENT_ARRAY_BUFFER, heminumindices*sizeof(GLushort), hemiindices, GL_STATIC_DRAW);
DELETEA(hemiindices);
if(!vbuf) glGenBuffers_(1, &vbuf);
glBindBuffer_(GL_ARRAY_BUFFER, vbuf);
glBufferData_(GL_ARRAY_BUFFER, numverts*sizeof(vec), verts, GL_STATIC_DRAW);
DELETEA(verts);
if(!ebuf) glGenBuffers_(1, &ebuf);
glBindBuffer_(GL_ELEMENT_ARRAY_BUFFER, ebuf);
glBufferData_(GL_ELEMENT_ARRAY_BUFFER, numindices*sizeof(GLushort), indices, GL_STATIC_DRAW);
DELETEA(indices);
}
void cleanup()
{
if(vbuf) { glDeleteBuffers_(1, &vbuf); vbuf = 0; }
if(ebuf) { glDeleteBuffers_(1, &ebuf); ebuf = 0; }
}
void enable()
{
if(!vbuf) init(5, 2);
glBindBuffer_(GL_ARRAY_BUFFER, vbuf);
glBindBuffer_(GL_ELEMENT_ARRAY_BUFFER, ebuf);
gle::vertexpointer(sizeof(vec), verts);
gle::enablevertex();
}
void draw()
{
glDrawRangeElements_(GL_TRIANGLES, 0, numverts-1, numindices, GL_UNSIGNED_SHORT, indices);
xtraverts += numindices;
glde++;
}
void disable()
{
gle::disablevertex();
glBindBuffer_(GL_ARRAY_BUFFER, 0);
glBindBuffer_(GL_ELEMENT_ARRAY_BUFFER, 0);
}
}
static GLuint expmodtex[2] = {0, 0};
@ -77,63 +111,101 @@ static GLuint createexpmodtex(int size, float minval)
return tex;
}
static struct spherevert
namespace sphere
{
vec pos;
float s, t;
} *sphereverts = NULL;
static GLushort *sphereindices = NULL;
static int spherenumverts = 0, spherenumindices = 0;
static GLuint spherevbuf = 0, sphereebuf = 0;
static void initsphere(int slices, int stacks)
{
spherenumverts = (stacks+1)*(slices+1);
sphereverts = new spherevert[spherenumverts];
float ds = 1.0f/slices, dt = 1.0f/stacks, t = 1.0f;
loopi(stacks+1)
struct vert
{
float rho = M_PI*(1-t), s = 0.0f;
loopj(slices+1)
vec pos;
float s, t;
} *verts = NULL;
GLushort *indices = NULL;
int numverts = 0, numindices = 0;
GLuint vbuf = 0, ebuf = 0;
void init(int slices, int stacks)
{
numverts = (stacks+1)*(slices+1);
verts = new vert[numverts];
float ds = 1.0f/slices, dt = 1.0f/stacks, t = 1.0f;
loopi(stacks+1)
{
float theta = j==slices ? 0 : 2*M_PI*s;
spherevert &v = sphereverts[i*(slices+1) + j];
v.pos = vec(-sin(theta)*sin(rho), cos(theta)*sin(rho), cos(rho));
v.s = s;
v.t = t;
s += ds;
float rho = M_PI*(1-t), s = 0.0f;
loopj(slices+1)
{
float theta = j==slices ? 0 : 2*M_PI*s;
vert &v = verts[i*(slices+1) + j];
v.pos = vec(-sin(theta)*sin(rho), cos(theta)*sin(rho), cos(rho));
v.s = s;
v.t = t;
s += ds;
}
t -= dt;
}
t -= dt;
numindices = stacks*slices*3*2;
indices = new ushort[numindices];
GLushort *curindex = indices;
loopi(stacks)
{
loopk(slices)
{
int j = i%2 ? slices-k-1 : k;
*curindex++ = i*(slices+1)+j;
*curindex++ = (i+1)*(slices+1)+j;
*curindex++ = i*(slices+1)+j+1;
*curindex++ = i*(slices+1)+j+1;
*curindex++ = (i+1)*(slices+1)+j;
*curindex++ = (i+1)*(slices+1)+j+1;
}
}
if(!vbuf) glGenBuffers_(1, &vbuf);
glBindBuffer_(GL_ARRAY_BUFFER, vbuf);
glBufferData_(GL_ARRAY_BUFFER, numverts*sizeof(vert), verts, GL_STATIC_DRAW);
DELETEA(verts);
if(!ebuf) glGenBuffers_(1, &ebuf);
glBindBuffer_(GL_ELEMENT_ARRAY_BUFFER, ebuf);
glBufferData_(GL_ELEMENT_ARRAY_BUFFER, numindices*sizeof(GLushort), indices, GL_STATIC_DRAW);
DELETEA(indices);
}
spherenumindices = stacks*slices*3*2;
sphereindices = new ushort[spherenumindices];
GLushort *curindex = sphereindices;
loopi(stacks)
void cleanup()
{
loopk(slices)
{
int j = i%2 ? slices-k-1 : k;
*curindex++ = i*(slices+1)+j;
*curindex++ = (i+1)*(slices+1)+j;
*curindex++ = i*(slices+1)+j+1;
*curindex++ = i*(slices+1)+j+1;
*curindex++ = (i+1)*(slices+1)+j;
*curindex++ = (i+1)*(slices+1)+j+1;
}
if(vbuf) { glDeleteBuffers_(1, &vbuf); vbuf = 0; }
if(ebuf) { glDeleteBuffers_(1, &ebuf); ebuf = 0; }
}
if(!spherevbuf) glGenBuffers_(1, &spherevbuf);
glBindBuffer_(GL_ARRAY_BUFFER, spherevbuf);
glBufferData_(GL_ARRAY_BUFFER, spherenumverts*sizeof(spherevert), sphereverts, GL_STATIC_DRAW);
DELETEA(sphereverts);
void enable()
{
if(!vbuf) init(12, 6);
if(!sphereebuf) glGenBuffers_(1, &sphereebuf);
glBindBuffer_(GL_ELEMENT_ARRAY_BUFFER, sphereebuf);
glBufferData_(GL_ELEMENT_ARRAY_BUFFER, spherenumindices*sizeof(GLushort), sphereindices, GL_STATIC_DRAW);
DELETEA(sphereindices);
glBindBuffer_(GL_ARRAY_BUFFER, vbuf);
glBindBuffer_(GL_ELEMENT_ARRAY_BUFFER, ebuf);
gle::vertexpointer(sizeof(vert), &verts->pos);
gle::texcoord0pointer(sizeof(vert), &verts->s);
gle::enablevertex();
gle::enabletexcoord0();
}
void draw()
{
glDrawRangeElements_(GL_TRIANGLES, 0, numverts-1, numindices, GL_UNSIGNED_SHORT, indices);
xtraverts += numindices;
glde++;
}
void disable()
{
gle::disablevertex();
gle::disabletexcoord0();
glBindBuffer_(GL_ARRAY_BUFFER, 0);
glBindBuffer_(GL_ELEMENT_ARRAY_BUFFER, 0);
}
}
VARP(explosion2d, 0, 0, 1);
@ -150,34 +222,8 @@ static void setupexplosion()
}
else if(explosion2d) SETSHADER(explosion2d); else SETSHADER(explosion3d);
if(explosion2d)
{
if(!hemivbuf) inithemisphere(5, 2);
glBindBuffer_(GL_ARRAY_BUFFER, hemivbuf);
glBindBuffer_(GL_ELEMENT_ARRAY_BUFFER, hemiebuf);
gle::vertexpointer(sizeof(vec), hemiverts);
gle::enablevertex();
}
else
{
if(!spherevbuf) initsphere(12, 6);
glBindBuffer_(GL_ARRAY_BUFFER, spherevbuf);
glBindBuffer_(GL_ELEMENT_ARRAY_BUFFER, sphereebuf);
gle::vertexpointer(sizeof(spherevert), &sphereverts->pos);
gle::texcoord0pointer(sizeof(spherevert), &sphereverts->s);
gle::enablevertex();
gle::enabletexcoord0();
}
}
static void drawexpverts(int numverts, int numindices, GLushort *indices)
{
glDrawRangeElements_(GL_TRIANGLES, 0, numverts-1, numindices, GL_UNSIGNED_SHORT, indices);
xtraverts += numindices;
glde++;
if(explosion2d) hemisphere::enable();
else sphere::enable();
}
static void drawexplosion(bool inside, float r, float g, float b, float a)
@ -196,7 +242,7 @@ static void drawexplosion(bool inside, float r, float g, float b, float a)
{
gle::colorf(r, g, b, i ? a/2 : a);
if(i) glDepthFunc(GL_GEQUAL);
drawexpverts(spherenumverts, spherenumindices, sphereindices);
sphere::draw();
if(i) glDepthFunc(GL_LESS);
}
return;
@ -209,31 +255,26 @@ static void drawexplosion(bool inside, float r, float g, float b, float a)
if(inside)
{
glCullFace(GL_FRONT);
drawexpverts(heminumverts, heminumindices, hemiindices);
hemisphere::draw();
glCullFace(GL_BACK);
LOCALPARAMF(side, (-1));
}
drawexpverts(heminumverts, heminumindices, hemiindices);
hemisphere::draw();
if(i) glDepthFunc(GL_LESS);
}
}
static void cleanupexplosion()
{
gle::disablevertex();
if(!explosion2d) gle::disabletexcoord0();
glBindBuffer_(GL_ARRAY_BUFFER, 0);
glBindBuffer_(GL_ELEMENT_ARRAY_BUFFER, 0);
if(explosion2d) hemisphere::disable();
else sphere::disable();
}
static void deleteexplosions()
{
loopi(2) if(expmodtex[i]) { glDeleteTextures(1, &expmodtex[i]); expmodtex[i] = 0; }
if(hemivbuf) { glDeleteBuffers_(1, &hemivbuf); hemivbuf = 0; }
if(hemiebuf) { glDeleteBuffers_(1, &hemiebuf); hemiebuf = 0; }
if(spherevbuf) { glDeleteBuffers_(1, &spherevbuf); spherevbuf = 0; }
if(sphereebuf) { glDeleteBuffers_(1, &sphereebuf); sphereebuf = 0; }
hemisphere::cleanup();
sphere::cleanup();
}
static const float WOBBLE = 1.25f;

View File

@ -355,7 +355,7 @@ const vector<int> &checklightcache(int x, int y)
return lce.lights;
}
static uint progress = 0;
static uint lightprogress = 0;
bool calclight_canceled = false;
volatile bool check_calclight_progress = false;
@ -371,7 +371,7 @@ void check_calclight_canceled()
void show_calclight_progress()
{
float bar1 = float(progress) / float(allocnodes);
float bar1 = float(lightprogress) / float(allocnodes);
defformatstring(text1)("%d%%", int(bar1 * 100));
renderprogress(bar1, text1);
@ -513,7 +513,7 @@ static void calcsurfaces(cube *c, const ivec &co, int size)
{
CHECK_CALCLIGHT_PROGRESS(return, show_calclight_progress);
progress++;
lightprogress++;
loopi(8)
{
@ -609,7 +609,7 @@ void calclight()
optimizeblendmap();
clearlightcache();
clearsurfaces(worldroot);
progress = 0;
lightprogress = 0;
calclight_canceled = false;
check_calclight_progress = false;
SDL_TimerID timer = SDL_AddTimer(250, calclighttimer, NULL);

View File

@ -144,11 +144,11 @@ void findnormal(const vec &pos, int smooth, const vec &surface, vec &v)
VARR(lerpsubdiv, 0, 2, 4);
VARR(lerpsubdivsize, 4, 4, 128);
static uint progress = 0;
static uint normalprogress = 0;
void show_addnormals_progress()
{
float bar1 = float(progress) / float(allocnodes);
float bar1 = float(normalprogress) / float(allocnodes);
renderprogress(bar1, "computing normals...");
}
@ -158,7 +158,7 @@ void addnormals(cube &c, const ivec &o, int size)
if(c.children)
{
progress++;
normalprogress++;
size >>= 1;
loopi(8) addnormals(c.children[i], ivec(i, o.x, o.y, o.z, size), size);
return;
@ -252,7 +252,7 @@ void calcnormals(bool lerptjoints)
{
usetnormals = lerptjoints;
if(usetnormals) findtjoints();
progress = 1;
normalprogress = 1;
loopi(8) addnormals(worldroot[i], ivec(i, 0, 0, 0, worldsize/2), worldsize/2);
}

View File

@ -180,133 +180,7 @@ void draw_env_overlay(int w, Texture *overlay = NULL, float tx = 0, float ty = 0
gle::disable();
}
static struct domevert
{
vec pos;
uchar color[4];
domevert() {}
domevert(const vec &pos, const bvec &fcolor, float alpha) : pos(pos)
{
memcpy(color, fcolor.v, 3);
color[3] = uchar(alpha*255);
}
domevert(const domevert &v0, const domevert &v1) : pos(vec(v0.pos).add(v1.pos).normalize())
{
memcpy(color, v0.color, 4);
if(v0.pos.z != v1.pos.z) color[3] += uchar((v1.color[3] - v0.color[3]) * (pos.z - v0.pos.z) / (v1.pos.z - v0.pos.z));
}
} *domeverts = NULL;
static GLushort *domeindices = NULL;
static int domenumverts = 0, domenumindices = 0, domecapindices = 0;
static GLuint domevbuf = 0, domeebuf = 0;
static bvec domecolor(0, 0, 0);
static float domeminalpha = 0, domemaxalpha = 0, domecapsize = -1, domeclipz = 1;
static void subdivide(int depth, int face);
static void genface(int depth, int i1, int i2, int i3)
{
int face = domenumindices; domenumindices += 3;
domeindices[face] = i3;
domeindices[face+1] = i2;
domeindices[face+2] = i1;
subdivide(depth, face);
}
static void subdivide(int depth, int face)
{
if(depth-- <= 0) return;
int idx[6];
loopi(3) idx[i] = domeindices[face+2-i];
loopi(3)
{
int vert = domenumverts++;
domeverts[vert] = domevert(domeverts[idx[i]], domeverts[idx[(i+1)%3]]); //push on to unit sphere
idx[3+i] = vert;
domeindices[face+2-i] = vert;
}
subdivide(depth, face);
loopi(3) genface(depth, idx[i], idx[3+i], idx[3+(i+2)%3]);
}
static int sortdomecap(GLushort x, GLushort y)
{
const vec &xv = domeverts[x].pos, &yv = domeverts[y].pos;
return xv.y < 0 ? yv.y >= 0 || xv.x < yv.x : yv.y >= 0 && xv.x > yv.x;
}
static void initdome(const bvec &color, float minalpha = 0.0f, float maxalpha = 1.0f, float capsize = -1, float clipz = 1, int hres = 16, int depth = 2)
{
const int tris = hres << (2*depth);
domenumverts = domenumindices = domecapindices = 0;
domeverts = new domevert[tris+1 + (capsize >= 0 ? 1 : 0)];
domeindices = new GLushort[(tris + (capsize >= 0 ? hres<<depth : 0))*3];
if(clipz >= 1)
{
domeverts[domenumverts++] = domevert(vec(0.0f, 0.0f, 1.0f), color, minalpha); //build initial 'hres' sided pyramid
loopi(hres) domeverts[domenumverts++] = domevert(vec(sincos360[(360*i)/hres], 0.0f), color, maxalpha);
loopi(hres) genface(depth, 0, i+1, 1+(i+1)%hres);
}
else if(clipz <= 0)
{
loopi(hres<<depth) domeverts[domenumverts++] = domevert(vec(sincos360[(360*i)/(hres<<depth)], 0.0f), color, maxalpha);
}
else
{
float clipxy = sqrtf(1 - clipz*clipz);
const vec2 &scm = sincos360[180/hres];
loopi(hres)
{
const vec2 &sc = sincos360[(360*i)/hres];
domeverts[domenumverts++] = domevert(vec(sc.x*clipxy, sc.y*clipxy, clipz), color, minalpha);
domeverts[domenumverts++] = domevert(vec(sc.x, sc.y, 0.0f), color, maxalpha);
domeverts[domenumverts++] = domevert(vec(sc.x*scm.x - sc.y*scm.y, sc.y*scm.x + sc.x*scm.y, 0.0f), color, maxalpha);
}
loopi(hres)
{
genface(depth-1, 3*i, 3*i+1, 3*i+2);
genface(depth-1, 3*i, 3*i+2, 3*((i+1)%hres));
genface(depth-1, 3*i+2, 3*((i+1)%hres)+1, 3*((i+1)%hres));
}
}
if(capsize >= 0)
{
GLushort *domecap = &domeindices[domenumindices];
int domecapverts = 0;
loopi(domenumverts) if(!domeverts[i].pos.z) domecap[domecapverts++] = i;
domeverts[domenumverts++] = domevert(vec(0.0f, 0.0f, -capsize), color, maxalpha);
quicksort(domecap, domecapverts, sortdomecap);
loopi(domecapverts)
{
int n = domecapverts-1-i;
domecap[n*3] = domecap[n];
domecap[n*3+1] = domecap[(n+1)%domecapverts];
domecap[n*3+2] = domenumverts-1;
domecapindices += 3;
}
}
if(!domevbuf) glGenBuffers_(1, &domevbuf);
glBindBuffer_(GL_ARRAY_BUFFER, domevbuf);
glBufferData_(GL_ARRAY_BUFFER, domenumverts*sizeof(domevert), domeverts, GL_STATIC_DRAW);
DELETEA(domeverts);
if(!domeebuf) glGenBuffers_(1, &domeebuf);
glBindBuffer_(GL_ELEMENT_ARRAY_BUFFER, domeebuf);
glBufferData_(GL_ELEMENT_ARRAY_BUFFER, (domenumindices + domecapindices)*sizeof(GLushort), domeindices, GL_STATIC_DRAW);
DELETEA(domeindices);
}
static void deletedome()
{
domenumverts = domenumindices = 0;
if(domevbuf) { glDeleteBuffers_(1, &domevbuf); domevbuf = 0; }
if(domeebuf) { glDeleteBuffers_(1, &domeebuf); domeebuf = 0; }
}
FVARR(fogdomeheight, -1, -0.5f, 1);
FVARR(fogdomeheight, -1, -0.5f, 1);
FVARR(fogdomemin, 0, 0, 1);
FVARR(fogdomemax, 0, 0, 1);
VARR(fogdomecap, 0, 1, 1);
@ -316,50 +190,175 @@ HVARFR(fogdomecolour, 0, 0, 0xFFFFFF,
{
fogdomecolor = bvec((fogdomecolour>>16)&0xFF, (fogdomecolour>>8)&0xFF, fogdomecolour&0xFF);
});
VARR(fogdomeclouds, 0, 1, 1);
static void drawdome()
namespace dome
{
float capsize = fogdomecap && fogdomeheight < 1 ? (1 + fogdomeheight) / (1 - fogdomeheight) : -1;
bvec color = fogdomecolour ? fogdomecolor : fogcolor;
if(!domenumverts || domecolor != color || domeminalpha != fogdomemin || domemaxalpha != fogdomemax || domecapsize != capsize || domeclipz != fogdomeclip)
struct vert
{
initdome(color, min(fogdomemin, fogdomemax), fogdomemax, capsize, fogdomeclip);
domecolor = color;
domeminalpha = fogdomemin;
domemaxalpha = fogdomemax;
domecapsize = capsize;
domeclipz = fogdomeclip;
vec pos;
uchar color[4];
vert() {}
vert(const vec &pos, const bvec &fcolor, float alpha) : pos(pos)
{
memcpy(color, fcolor.v, 3);
color[3] = uchar(alpha*255);
}
vert(const vert &v0, const vert &v1) : pos(vec(v0.pos).add(v1.pos).normalize())
{
memcpy(color, v0.color, 4);
if(v0.pos.z != v1.pos.z) color[3] += uchar((v1.color[3] - v0.color[3]) * (pos.z - v0.pos.z) / (v1.pos.z - v0.pos.z));
}
} *verts = NULL;
GLushort *indices = NULL;
int numverts = 0, numindices = 0, capindices = 0;
GLuint vbuf = 0, ebuf = 0;
bvec lastcolor(0, 0, 0);
float lastminalpha = 0, lastmaxalpha = 0, lastcapsize = -1, lastclipz = 1;
void subdivide(int depth, int face);
void genface(int depth, int i1, int i2, int i3)
{
int face = numindices; numindices += 3;
indices[face] = i3;
indices[face+1] = i2;
indices[face+2] = i1;
subdivide(depth, face);
}
glBindBuffer_(GL_ARRAY_BUFFER, domevbuf);
glBindBuffer_(GL_ELEMENT_ARRAY_BUFFER, domeebuf);
void subdivide(int depth, int face)
{
if(depth-- <= 0) return;
int idx[6];
loopi(3) idx[i] = indices[face+2-i];
loopi(3)
{
int curvert = numverts++;
verts[curvert] = vert(verts[idx[i]], verts[idx[(i+1)%3]]); //push on to unit sphere
idx[3+i] = curvert;
indices[face+2-i] = curvert;
}
subdivide(depth, face);
loopi(3) genface(depth, idx[i], idx[3+i], idx[3+(i+2)%3]);
}
gle::vertexpointer(sizeof(domevert), &domeverts->pos);
gle::colorpointer(sizeof(domevert), &domeverts->color);
gle::enablevertex();
gle::enablecolor();
static inline int sortcap(GLushort x, GLushort y)
{
const vec &xv = verts[x].pos, &yv = verts[y].pos;
return xv.y < 0 ? yv.y >= 0 || xv.x < yv.x : yv.y >= 0 && xv.x > yv.x;
}
glDrawRangeElements_(GL_TRIANGLES, 0, domenumverts-1, domenumindices + fogdomecap*domecapindices, GL_UNSIGNED_SHORT, domeindices);
xtraverts += domenumverts;
glde++;
static void init(const bvec &color, float minalpha = 0.0f, float maxalpha = 1.0f, float capsize = -1, float clipz = 1, int hres = 16, int depth = 2)
{
const int tris = hres << (2*depth);
numverts = numindices = capindices = 0;
verts = new vert[tris+1 + (capsize >= 0 ? 1 : 0)];
indices = new GLushort[(tris + (capsize >= 0 ? hres<<depth : 0))*3];
if(clipz >= 1)
{
verts[numverts++] = vert(vec(0.0f, 0.0f, 1.0f), color, minalpha); //build initial 'hres' sided pyramid
loopi(hres) verts[numverts++] = vert(vec(sincos360[(360*i)/hres], 0.0f), color, maxalpha);
loopi(hres) genface(depth, 0, i+1, 1+(i+1)%hres);
}
else if(clipz <= 0)
{
loopi(hres<<depth) verts[numverts++] = vert(vec(sincos360[(360*i)/(hres<<depth)], 0.0f), color, maxalpha);
}
else
{
float clipxy = sqrtf(1 - clipz*clipz);
const vec2 &scm = sincos360[180/hres];
loopi(hres)
{
const vec2 &sc = sincos360[(360*i)/hres];
verts[numverts++] = vert(vec(sc.x*clipxy, sc.y*clipxy, clipz), color, minalpha);
verts[numverts++] = vert(vec(sc.x, sc.y, 0.0f), color, maxalpha);
verts[numverts++] = vert(vec(sc.x*scm.x - sc.y*scm.y, sc.y*scm.x + sc.x*scm.y, 0.0f), color, maxalpha);
}
loopi(hres)
{
genface(depth-1, 3*i, 3*i+1, 3*i+2);
genface(depth-1, 3*i, 3*i+2, 3*((i+1)%hres));
genface(depth-1, 3*i+2, 3*((i+1)%hres)+1, 3*((i+1)%hres));
}
}
gle::disablevertex();
gle::disablecolor();
if(capsize >= 0)
{
GLushort *cap = &indices[numindices];
int capverts = 0;
loopi(numverts) if(!verts[i].pos.z) cap[capverts++] = i;
verts[numverts++] = vert(vec(0.0f, 0.0f, -capsize), color, maxalpha);
quicksort(cap, capverts, sortcap);
loopi(capverts)
{
int n = capverts-1-i;
cap[n*3] = cap[n];
cap[n*3+1] = cap[(n+1)%capverts];
cap[n*3+2] = numverts-1;
capindices += 3;
}
}
glBindBuffer_(GL_ARRAY_BUFFER, 0);
glBindBuffer_(GL_ELEMENT_ARRAY_BUFFER, 0);
if(!vbuf) glGenBuffers_(1, &vbuf);
glBindBuffer_(GL_ARRAY_BUFFER, vbuf);
glBufferData_(GL_ARRAY_BUFFER, numverts*sizeof(vert), verts, GL_STATIC_DRAW);
DELETEA(verts);
if(!ebuf) glGenBuffers_(1, &ebuf);
glBindBuffer_(GL_ELEMENT_ARRAY_BUFFER, ebuf);
glBufferData_(GL_ELEMENT_ARRAY_BUFFER, (numindices + capindices)*sizeof(GLushort), indices, GL_STATIC_DRAW);
DELETEA(indices);
}
void cleanup()
{
numverts = numindices = 0;
if(vbuf) { glDeleteBuffers_(1, &vbuf); vbuf = 0; }
if(ebuf) { glDeleteBuffers_(1, &ebuf); ebuf = 0; }
}
void draw()
{
float capsize = fogdomecap && fogdomeheight < 1 ? (1 + fogdomeheight) / (1 - fogdomeheight) : -1;
bvec color = fogdomecolour ? fogdomecolor : fogcolor;
if(!numverts || lastcolor != color || lastminalpha != fogdomemin || lastmaxalpha != fogdomemax || lastcapsize != capsize || lastclipz != fogdomeclip)
{
init(color, min(fogdomemin, fogdomemax), fogdomemax, capsize, fogdomeclip);
lastcolor = color;
lastminalpha = fogdomemin;
lastmaxalpha = fogdomemax;
lastcapsize = capsize;
lastclipz = fogdomeclip;
}
glBindBuffer_(GL_ARRAY_BUFFER, vbuf);
glBindBuffer_(GL_ELEMENT_ARRAY_BUFFER, ebuf);
gle::vertexpointer(sizeof(vert), &verts->pos);
gle::colorpointer(sizeof(vert), &verts->color);
gle::enablevertex();
gle::enablecolor();
glDrawRangeElements_(GL_TRIANGLES, 0, numverts-1, numindices + fogdomecap*capindices, GL_UNSIGNED_SHORT, indices);
xtraverts += numverts;
glde++;
gle::disablevertex();
gle::disablecolor();
glBindBuffer_(GL_ARRAY_BUFFER, 0);
glBindBuffer_(GL_ELEMENT_ARRAY_BUFFER, 0);
}
}
void cleanupsky()
{
deletedome();
dome::cleanup();
}
VAR(showsky, 0, 1, 1);
VAR(clampsky, 0, 1, 1);
VARR(fogdomeclouds, 0, 1, 1);
static void drawfogdome(int farplane)
{
SETSHADER(skyfog);
@ -374,11 +373,13 @@ static void drawfogdome(int farplane)
skyprojmatrix.mul(projmatrix, skymatrix);
LOCALPARAM(skymatrix, skyprojmatrix);
drawdome();
dome::draw();
glDisable(GL_BLEND);
}
VAR(showsky, 0, 1, 1);
VAR(clampsky, 0, 1, 1);
VARNR(skytexture, useskytexture, 0, 0, 1);
VARFR(skyshadow, 0, 0, 1, clearshadowcache());

View File

@ -338,7 +338,7 @@ void drawbb(const ivec &bo, const ivec &br, const vec &camera)
gle::attribf(ox rx, oy ry, oz rz);
GENFACEVERTS(bo.x, bo.x + br.x, bo.y, bo.y + br.y, bo.z, bo.z + br.z, , , , , , )
#undef GENFACEORIENT
#undef GENFACEVERTS
#undef GENFACEVERT
xtraverts += gle::end();
}

View File

@ -269,7 +269,7 @@ char *entname(entity &e)
}
extern selinfo sel;
extern bool havesel, selectcorners;
extern bool havesel;
int entlooplevel = 0;
int efocus = -1, enthover = -1, entorient = -1, oldhover = -1;
bool undonext = true;

View File

@ -40,6 +40,10 @@ uint randomMT()
return y;
}
#undef N
#undef M
#undef K
///////////////////////// network ///////////////////////
// all network traffic is in 32bit ints, which are then compressed using the following simple scheme (assumes that most values are small).