Page 1 of 2

heh heh heh persistance matters

Posted: Wed Apr 18, 2012 9:29 pm
by revelator
Could someone try this one out ?

http://code.google.com/p/realm/download ... z&can=2&q=

warning it will not run on machines with less than GL2 and you need a dualcore cpu atleast sorry.

This is a test so the above will probably change some but you will still need a pretty recent gfx card.

Re: heh heh heh persistance matters

Posted: Wed Apr 18, 2012 10:12 pm
by mh
GL 4.2 here; it runs but it's hellish slow, I got maybe 10fps in a timedemo demo1. AMD something or other and Intel i7. Very nice water shader.

Re: heh heh heh persistance matters

Posted: Wed Apr 18, 2012 10:28 pm
by revelator
10 fps :shock: what kind of card do you have ? i get more than 1000 fps on mine gtx 560.

as for the shader its ok allthough im still fiddling a bit with the looks :)

your code took on some pounds though hehe

Code: Select all

void R_DrawWaterSurfaces (void)
{
    gltexture_t *tex;
    msurface_t	*surf;
    brushpoly_t	*p;
    int			i;
    float		args[4] = {1.0f,1.0f,1.0f,1.0f};
    float		sadd, tadd;
    float		*v;

    // drawing parameters
    vector_t	warp1scale;
    vector_t	warp2scale;

    float		wateralpha;
    float		warp2sign;

    GLenum		WARP1_TEXENV;
    GLenum		WARP2_TEXENV;

    int			Warp1Texture;
    int			Warp2Texture;

    if (!GL_RenderState.waterthisframe) return;

    // back to the world matrix
    glLoadMatrixf (cl_entities[0].mvievmatrix);

    // enable blending
    glEnable (GL_BLEND);
    glDepthMask (GL_FALSE);

    // enable tmu 1
    glActiveTexture (GL_TEXTURE1);
    glEnable (GL_TEXTURE_2D);

    // enable vertex pointer - index 0 is the regular verts
    glEnableClientState (GL_VERTEX_ARRAY);
    glVertexPointer (3, GL_FLOAT, sizeof (waterverts_t), &waterarray[0]);

    // enable texcoord pointer for textures - index 3 is the st coords for warp 1
    if (GL_ExtensionBits & HAS_FRAGMENTSHADERS)
    {
        // values are rgb + alpha but can also be texture coords.
        glClientActiveTexture (GL_TEXTURE0);
        glEnableClientState (GL_TEXTURE_COORD_ARRAY);
        glTexCoordPointer (2, GL_FLOAT, sizeof (waterverts_t), &waterarray[3]);

        glBindTexture (GL_TEXTURE_2D, r_dst_texture.gltexnum);
    }
    else
    {
        glClientActiveTexture (GL_TEXTURE0);
        glEnableClientState (GL_TEXTURE_COORD_ARRAY);
        glTexCoordPointer (2, GL_FLOAT, sizeof (waterverts_t), &waterarray[3]);
    }

    // enable texcoord pointer for textures - index 5 is the st coords for warp 2
    // added arb shader for non nvidia cards
    if (GL_ExtensionBits & HAS_FRAGMENTSHADERS)
    {
        // values are rgb + alpha but can also be texture coords.
        glClientActiveTexture (GL_TEXTURE1);
        glEnableClientState (GL_TEXTURE_COORD_ARRAY);
        glTexCoordPointer (2, GL_FLOAT, sizeof (waterverts_t), &waterarray[5]);

        glBindTexture (GL_TEXTURE_2D, r_dst_texture.gltexnum);
    }
    else
    {
        glClientActiveTexture (GL_TEXTURE1);
        glEnableClientState (GL_TEXTURE_COORD_ARRAY);
        glTexCoordPointer (2, GL_FLOAT, sizeof (waterverts_t), &waterarray[5]);
    }

    // go through the texture list
    for (tex = texturelist; tex; tex = tex->texturelist)
    {
        // nothing chained
        if (!(surf = tex->texturechain)) continue;

        // it ain't liquid
        if (!(surf->flags & SURF_DRAWTURB)) continue;

        // setup rendering parameters
        // these are actually absolutely excellent
        if (surf->flags & SURF_DRAWLAVA)
        {
            glDisable (GL_BLEND);
            glDepthMask (GL_TRUE);

            warp1scale.vec.x = 1.0f / 256.0f;
            warp1scale.vec.y = 1.0f / 256.0f;
            warp1scale.vec.z = 1.0f;

            wateralpha = 1.0f;

            warp2scale.vec.x = 1.0f / 128.0f;
            warp2scale.vec.y = 1.0f / 128.0f;
            warp2scale.vec.z = 1.0f;

            if (GL_ExtensionBits & HAS_FRAGMENTSHADERS)
            {
                warp2sign = -1;
            }
            else
            {
                warp2sign = 1;
            }
            WARP1_TEXENV = GL_REPLACE;
            WARP2_TEXENV = GL_ADD;

            // we could use any old crap for warp1 here..
            Warp1Texture = surf->texinfo->texture->gl_texture->gltexnum;
            Warp2Texture = surf->texinfo->texture->gl_texture->gltexnum;
        }
        else if (surf->flags & SURF_DRAWTELE)
        {
            glDisable (GL_BLEND);
            glDepthMask (GL_TRUE);

            warp1scale.vec.x = 1.0f / 64.0f;
            warp1scale.vec.y = 1.0f / 64.0f;
            warp1scale.vec.z = 1.0f;

            wateralpha = 1.0f;

            warp2scale.vec.x = 1.0f / 24.0f;
            warp2scale.vec.y = 1.0f / 24.0f;
            warp2scale.vec.z = 1.0f;

            if (GL_ExtensionBits & HAS_FRAGMENTSHADERS)
            {
                warp2sign = -1;
            }
            else
            {
                warp2sign = 1;
            }
            WARP1_TEXENV = GL_REPLACE;
            WARP2_TEXENV = GL_ADD;

            // we could use any old crap for warp1 here..
            Warp1Texture = surf->texinfo->texture->gl_texture->gltexnum;
            Warp2Texture = surf->texinfo->texture->gl_texture->gltexnum;
        }
        else if (surf->flags & SURF_DRAWSLIME)
        {
            glEnable (GL_BLEND);
            glDepthMask (GL_FALSE);

            warp1scale.vec.x = 1.0f / 128.0f;
            warp1scale.vec.y = 1.0f / 128.0f;
            warp1scale.vec.z = 1.0f;

            wateralpha = r_wateralpha.value;

            warp2scale.vec.x = 1.0f / 256.0f;
            warp2scale.vec.y = 1.0f / 256.0f;
            warp2scale.vec.z = 1.0f;

            if (GL_ExtensionBits & HAS_FRAGMENTSHADERS)
            {
                warp2sign = -1;
            }
            else
            {
                warp2sign = 1;
            }
            WARP1_TEXENV = GL_MODULATE;
            WARP2_TEXENV = GL_ADD;

            // we could use any old crap for warp1 here..
            Warp1Texture = surf->texinfo->texture->gl_texture->gltexnum;
            Warp2Texture = surf->texinfo->texture->gl_texture->gltexnum;
        }
        else
        {
            glEnable (GL_BLEND);
            glDepthMask (GL_FALSE);

            warp1scale.vec.x = 1.0f / 128.0f;
            warp1scale.vec.y = 1.0f / 128.0f;
            warp1scale.vec.z = 1.0f;

            wateralpha = r_wateralpha.value;

            warp2scale.vec.x = 1.0f / 256.0f;
            warp2scale.vec.y = 1.0f / 256.0f;
            warp2scale.vec.z = 1.0f;

            if (GL_ExtensionBits & HAS_FRAGMENTSHADERS)
            {
                warp2sign = -1;
            }
            else
            {
                warp2sign = 1;
            }
            WARP1_TEXENV = GL_MODULATE;
            WARP2_TEXENV = GL_ADD;

            // we could use any old crap for warp1 here..
            Warp1Texture = surf->texinfo->texture->gl_texture->gltexnum;
            Warp2Texture = surf->texinfo->texture->gl_texture->gltexnum;
        }

        // select texture 0
        if (GL_ExtensionBits & HAS_FRAGMENTSHADERS)
        {
            glActiveTexture (GL_TEXTURE0);
            glBindTexture (GL_TEXTURE_2D, Warp1Texture);

            // overlay it with the fragment shader
            glBindProgram(GL_FRAGMENT_PROGRAM, fragment_programs[F_PROG_WARP]);
            glProgramLocalParameter4fv(GL_FRAGMENT_PROGRAM, 0, &args[0]);
            glEnable (GL_FRAGMENT_PROGRAM);
        }
        else
        {
            glActiveTexture (GL_TEXTURE0);
            glBindTexture (GL_TEXTURE_2D, Warp1Texture);
        }
        glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, WARP1_TEXENV);
        glMatrixMode (GL_TEXTURE);
        glLoadIdentity ();
        glScalef (warp1scale.vecs[0], warp1scale.vecs[1], warp1scale.vecs[2]);
        glMatrixMode (GL_MODELVIEW);

        // select texture 1
        if (GL_ExtensionBits & HAS_FRAGMENTSHADERS)
        {
            glActiveTexture (GL_TEXTURE1);
            glBindTexture (GL_TEXTURE_2D, Warp2Texture);

            // overlay it with the fragment shader
            glBindProgram(GL_FRAGMENT_PROGRAM, fragment_programs[F_PROG_WARP]);
            glProgramLocalParameter4fv(GL_FRAGMENT_PROGRAM, 1, &args[0]);
            glEnable (GL_FRAGMENT_PROGRAM);
        }
        else
        {
            glActiveTexture (GL_TEXTURE1);
            glBindTexture (GL_TEXTURE_2D, Warp2Texture);
        }
        glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, WARP2_TEXENV);
        glMatrixMode (GL_TEXTURE);
        glLoadIdentity ();
        glScalef (warp2scale.vecs[0], warp2scale.vecs[1], warp2scale.vecs[2]);
        glMatrixMode (GL_MODELVIEW);

        // should be on the array tbh.
        glColor4f (1, 1, 1, wateralpha);

        // go through the surfs in the chain
        for (/**/; surf; surf = surf->texturechain)
        {
            // water surfs have a chained list of polys rather than just 1
            for (p = surf->polys; p; p = p->next)
            {
                // need to go through each vert in the list to set the warped texcoords
                for (i = 0; i < p->numverts; i++)
                {
                    // get a pointer to the verts to keep the code more readable
                    v = p->water[i].v;

                    // calculate the amount to add for the warp
                    sadd = STSinTable[(int) ((v[surf->warpindex[1]] * 0.025 + realtime) * STMult) & STBitMask];
                    tadd = STSinTable[(int) ((v[surf->warpindex[0]] * 0.025 + realtime) * STMult) & STBitMask];

                    // set the warp verts
                    // fix water warping - derive the texcoords from the verts!!!  mad, but it works!!!
                    // warpindex is precalculated in gl_model.c - use the x2 STSinTable for 8 unit warps
                    p->water[i].warp1[0] = v[surf->warpindex[0]] + sadd;
                    p->water[i].warp1[1] = v[surf->warpindex[1]] + tadd;

                    // warp 2
                    p->water[i].warp2[0] = (v[surf->warpindex[0]] * warp2sign) + sadd;
                    p->water[i].warp2[1] = (v[surf->warpindex[1]] * warp2sign) + tadd;
                }

                // draw the vertex array
                glDrawArrays (GL_TRIANGLE_FAN, p->waterindex, p->numverts);
            }
        }
    }

    // restore state on tmu 0
    glActiveTexture (GL_TEXTURE1);
    glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    glMatrixMode (GL_TEXTURE);
    glLoadIdentity ();
    glMatrixMode (GL_MODELVIEW);
    glDisable(GL_TEXTURE_2D);

    // restore state on tmu 1
    glActiveTexture (GL_TEXTURE0);
    glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    glMatrixMode (GL_TEXTURE);
    glLoadIdentity ();
    glMatrixMode (GL_MODELVIEW);

    // kill texcoord arrays
    glClientActiveTexture (GL_TEXTURE1);
    glDisableClientState (GL_TEXTURE_COORD_ARRAY);
    glClientActiveTexture (GL_TEXTURE0);
    glDisableClientState (GL_TEXTURE_COORD_ARRAY);

    if (GL_ExtensionBits & HAS_FRAGMENTSHADERS)
    {
        glDisable(GL_FRAGMENT_PROGRAM);
    }
    glColor4f (1, 1, 1, 1);

    // draw fog if we're in liquid only
    if (CONTENTMASK_LIQUID(r_viewleaf))
    {
        float fogdist;
        float fogalpha;

        // if teleports or lava are drawn last they'll leave blending disabled coming in here, so
        // make a potentially redundant state change.  it's only once per frame, so live with it.
        glEnable (GL_BLEND);
        glDepthMask (GL_FALSE);

        // enable color array
        glEnableClientState (GL_COLOR_ARRAY);
        glColorPointer (4, GL_FLOAT, sizeof (waterverts_t), &waterarray[7]);

        // turn off texturing and ensure we have smooth shading
        glDisable (GL_TEXTURE_2D);
        glShadeModel (GL_SMOOTH);

        // default blendfunc for this
        glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        // go through the texture list
        for (tex = texturelist; tex; tex = tex->texturelist)
        {
            // nothing chained
            if (!(surf = tex->texturechain)) continue;

            // we are not below water
            if (!(surf->flags & SURF_UNDERWATER)) continue;

            // it ain't liquid
            if (!(surf->flags & SURF_DRAWTURB)) continue;

            // don't put fog on teleports
            if (surf->flags & SURF_DRAWTELE) continue;

            // go through the surfs in the chain
            for (/**/; surf; surf = surf->texturechain)
            {
                // water surfs have a chained list of polys rather than just 1
                for (p = surf->polys; p; p = p->next)
                {
                    // need to go through each vert in the list to set the colours
                    for (i = 0; i < p->numverts; i++)
                    {
                        // get a pointer to the verts to keep the code more readable
                        v = p->water[i].v;

                        // set the correct color
                        p->water[i].rgba[0] = surf->texinfo->texture->gl_texture->rgba[0];
                        p->water[i].rgba[1] = surf->texinfo->texture->gl_texture->rgba[1];
                        p->water[i].rgba[2] = surf->texinfo->texture->gl_texture->rgba[2];

                        if (surf->flags & SURF_DRAWLAVA)
                        {
                            // constant fog
                            fogalpha = FOG_ALPHA_LAVA_CONST;
                        }
                        else if (surf->flags & SURF_DRAWSLIME)
                        {
                            // constant fog
                            fogalpha = FOG_ALPHA_SLIME_CONST;
                        }
                        else
                        {
                            // distance fog
                            // use the transformed verts to get the dist
                            fogdist = (v[0] - r_origin[0]) * vpn[0] + (v[1] - r_origin[1]) * vpn[1] + (v[2] - r_origin[2]) * vpn[2];

                            if (fogdist < 0)
                            {
                                fogdist = 0;
                            }
                            else if (fogdist > FOG_RANGE)
                            {
                                fogdist = FOG_RANGE;
                            }
                            fogalpha = 0.3f + (fogdist / FOG_RANGE * FOG_ALPHA_MAX) * 0.5f;

                            // boost alpha a little cos the translucent water can make it hard to see
                            fogalpha *= 1.25f;
                        }
                        p->water[i].rgba[3] = fogalpha;
                    }

                    // draw the vertex array
                    glDrawArrays (GL_TRIANGLE_FAN, p->waterindex, p->numverts);
                }
            }
        }

        // bring texturing back
        glEnable (GL_TEXTURE_2D);

        // paranoia!!!
        glColor4f (1, 1, 1, 1);

        // now bring color arrays back to the way they were.
        glDisableClientState (GL_COLOR_ARRAY);
    }

    // kill vertex array
    glDisableClientState (GL_VERTEX_ARRAY);

    // potentially redundant if teleports or lava were drawn last and we're not underwater.
    // it's only once per frame so live with it.
    glDisable (GL_BLEND);
    glDepthMask (GL_TRUE);
}
Arb shader so it should work on all cards that support arb2.
I also fixed the damn bug with fullbrights, turned out to be the alias model ents mixing in with the brush ents so i seperated the whole shebang.
Video menu still not done the code is so huge my head spins im not the youngest anymore hehe.

Re: heh heh heh persistance matters

Posted: Wed Apr 18, 2012 10:51 pm
by mh
Admittedly it's a laptop/mobile thing, but it can still run Doom 3 at 60 fps...

Anyway, just done some GLIntercept logging. A good chunk of time is going in glFlush calls. Example:

Code: Select all

glBindTexture(GL_TEXTURE_2D,25)
glCallList(1) Time= 33us
glPopMatrix()
glFlush() Time= 6845us
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_COLOR,GL_SRC_ALPHA)
There's also some aberrant glDrawArrays:

Code: Select all

glActiveTexture(GL_TEXTURE0)
glBindTexture(GL_TEXTURE_2D,169)
glActiveTexture(GL_TEXTURE1)
glBindTexture(GL_TEXTURE_2D,380)
glDrawArrays(GL_TRIANGLE_FAN,20070,6) Time= 49929us
glDrawArrays(GL_TRIANGLE_FAN,19994,6)
Oddly, these only cause trouble with a "first" param over 20000 or so.

Re: heh heh heh persistance matters

Posted: Wed Apr 18, 2012 11:30 pm
by Orion
No crosshair :?
Even when crosshair is 1. But I played well even without it, lol.
@Topic: Here it ran even smoother than DP, on an i5, gt 220 1gb card.

Re: heh heh heh persistance matters

Posted: Wed Apr 18, 2012 11:45 pm
by mh
It's obviously an AMD thing then. I'm seeing display lists in there; might be an idea to just make the calls directly if AMD.

Re: heh heh heh persistance matters

Posted: Thu Apr 19, 2012 1:12 am
by revelator
Can you try this one ? its optimized for AMD. http://code.google.com/p/realm/download ... z&can=2&q=
And good catch with the crosshairs its fixed now.

Re: heh heh heh persistance matters

Posted: Thu Apr 19, 2012 6:49 am
by revelator
Digged in deeper and it seems the most expensive function is the lava haze code. Atleast its the only place i notice a serious frame drop. Im allready culling it as much as possible but the darn thing insists on bleeding through solids (visible in the room with a lava surf above) i fixed most of the bleeding by doing this.

// not marked this however takes care of the wall poke through. (huge framerate killer tho)
if (surf->visframe != r_framecount) continue;

Re: heh heh heh persistance matters

Posted: Fri Apr 20, 2012 6:46 am
by revelator
Fixed the darn video menu atlast :) final item to fix is bloom (mines a bit obtrusive) looking at mh's later version that only blooms fullbrights.
Newer got alias model dot3 bumpmapping to work correctly i hope i can persuade mh to give me a hand finishing that part ?.

Re: heh heh heh persistance matters

Posted: Fri Apr 20, 2012 12:22 pm
by revelator
Packed up and ready to ship :P

http://code.google.com/p/realm/download ... z&can=2&q=

shot of shaders in action.

Image

Re: heh heh heh persistance matters

Posted: Sun Apr 22, 2012 7:15 pm
by revelator
ah crap video menu still not working correctly :( mh's autoresolution code makes it go bonkers.
avoid using it for now.

Re: heh heh heh persistance matters

Posted: Tue Apr 24, 2012 1:19 am
by qbism
Gorgeous but very slow, again an ATI laptop (Mobility 5650).

Re: heh heh heh persistance matters

Posted: Tue Apr 24, 2012 2:55 am
by revelator
might add a cvar to turn of the shaders though im a bit miffed that it makes that huge an impact on laptops :S it runs like oil on my rig but ok i got two 560 gtx in sli so heh.

as mh pointed out there are a lot of array calls (whole engine uses vertex arrays) but im scratching my head a bit about the glFlush calls ???
there are only two in the code so i wonder if the arrays call those internally ?.

the video menu is in the right place atleast but i cannot figure out why the darn thing goes into windowed mode and refuses to go back to fullscreen when you change the resolution sigh. If someone can spot the thing ill let them have the source im working off.

Re: heh heh heh persistance matters

Posted: Tue Apr 24, 2012 12:26 pm
by mh
I think it's more an ATI thing than it is a laptop thing. It happens in scenes even without water shaders, so there's some state or combination of states at work here that are choking the driver. This machine timedemos my GL3 Q2 engine at over 900 fps, the CPUs an i7, so I'm quite certain that the machine itself is capable, just something causing a software fallback perhaps.

Re: heh heh heh persistance matters

Posted: Tue Apr 24, 2012 4:28 pm
by revelator
hmm not making it easy to be a developer when things like that happen :S can the number of vertex calls be limited ? batching them up maybe ? and here i thought vertex arrays where allways faster :mrgreen:
btw my pc is an i7 950 so i agree its not a cpu thing hmm. initial heap is 64 mb so not large at all but i know from experience that it varies a lot with the ammount of highres replacement textures (my own uses more than 1 gig) but it only makes load times take longer speed is fine. not sure if i might have introduced this so i should try and compile your original version and let you compare.