Old school quake, well not quite but

Discuss anything not covered by any of the other categories.
revelator
Posts: 2621
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: Old school quake, well not quite but

Post by revelator »

Hmm food for thought, thanks spike :) ill see what i can do to get to the bottom of this.
Productivity is a state of mind.
revelator
Posts: 2621
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: Old school quake, well not quite but

Post by revelator »

Ok that helped a bit, i created a guard against recursion in SCR_UpdateScreen still a little stalling but much better now.

Also ran into a bug that im not sure is code related but i might be wrong, e4m1 underwater leafs seem to collapse causing underwater fog to fail, same happens in the end map before shubby. Are there any problems with wrong worldtypes in those maps ? i remember claustrophobolis had some problems with this. Fog works fine in all other maps.
Productivity is a state of mind.
revelator
Posts: 2621
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: Old school quake, well not quite but

Post by revelator »

Damn its also code related :( cheked with another engine and it does not exhibit this behaviour, guess ill be busy for the time being fixing this.

Mh's comment also had me look at the tenebrae glare code, so i applied the same bloom code i use in realm for a test but it does nothing ?, seems tenebrae uses
code that is not compatible with this method of applying bloom. Last version used a post processing shader but it was buggy as hell so i removed it for the time being untill i find out why. Atleast i fixed tenebrae old problem with breaking shadow voulmes if depthrange was enabled, i posted this fix in the engine coding section for those interrested. No more problem with the model poking through walls yay :).
Productivity is a state of mind.
revelator
Posts: 2621
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: Old school quake, well not quite but

Post by revelator »

Gaaaah :shock: i just noticed realm does not check backfacing surfs, guess i forgot to implement the code when i ported this codebit from tochris sigh.

That might actually explain the weird behaiviour with leaf planes collapsing, going to check that fingers crossed.

Finally managed to get fragment shaders to work with the dual layered water, the overlay looks pretty good though its a far bit away from the original.
It does smooth out the edgies :)

Still stalls a bit not sure what to check next urgh.
Productivity is a state of mind.
revelator
Posts: 2621
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: Old school quake, well not quite but

Post by revelator »

Sigh ok it was the lava heat haze code causing the rest of the stalling, it uses a nasty pvs hack to prevent smoke from poking through walls even if its occluded.
Unfortunatly it also causes some jerkiness when the pvs changes because it does this every frame. Im looking for a way to fix this properly.
Productivity is a state of mind.
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: Old school quake, well not quite but

Post by toneddu2000 »

wow, I admire your dedication and skills!
Meadow Fun!! - my first commercial game, made with FTEQW game engine
revelator
Posts: 2621
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: Old school quake, well not quite but

Post by revelator »

:)

Image

Image

now plays nehahra maps, still TODO: demo movie support and fixing menues.
Productivity is a state of mind.
revelator
Posts: 2621
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: Old school quake, well not quite but

Post by revelator »

Clank ... ok i found the culprit collapsing leaf planes.

Since realm was based on MHQuake it used a remnant of the old transwater code (world volumen carving) this was used as a reliable way of finding underwater
leafs for certain textures like caustics. I obviously thought that since it works so well for these kinds of effects that i could use them for checking other stuff also
like heat haze, but as it turns out the volume carving expects an actuall object to be drawn and that is not the case with the stencil heat haze since its a particle effect.
I noticed that while testing the heathaze code against SURF_UNDERWATER it would totally fuck up surfs unless i removed the check for volumentexture.

Theres one nasty thing about the heathaze code which im not sure how to handle better also.

in R_MarkLeafs it does this atm.

Code: Select all

    for(i = 0; i < cl.worldmodel->numleafs; i++)
    {
        // lava haze not visible yet, disable for now.
        cl.worldmodel->surfaces[i].leafvis = false;

        if(vis[i >> 3] & (1 << (i & 7)))
        {
            // mark surfs
            // vile hack necessitated by view frustum culling where a lava surf may be culled but it's
            // smoke would still be visible
            mark = cl.worldmodel->leafs[i + 1].firstmarksurface;
            c = cl.worldmodel->leafs[i + 1].nummarksurfaces;

            if(c)
            {
                do
                {
                    // check for a lava surf and draw haze on it.
                    if((*mark)->flags & SURF_DRAWLAVA)
                    {
                        // draw lava haze
                        (*mark)->leafvis = true;
                    }
                    mark++;
                }
                while(--c);
            }
            node = (mnode_t *) &cl.worldmodel->leafs[i + 1];

            do
            {
                if(node->visframe == r_visframecount)
                {
                    break;
                }
                node->visframe = r_visframecount;
                node = node->parent;
            }
            while(node);
        }
    }
any better way ?.
Productivity is a state of mind.
revelator
Posts: 2621
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: Old school quake, well not quite but

Post by revelator »

Bwahahah :lol: it's official im an idiot.

Been hunting this damn performance bug for weeks now and actually got it to run faster but it would still stall like crazy in fast moving scenes whenever an angle got updated, well while checking something unrelated i noticed this ->

Code: Select all

void MakeDOT3(gltexture_t *glt, unsigned int *src, int width, int height)
{
    unsigned int	*dst = NULL;
    int				x;
    int				y;
    pixelint		pix;
    float			dX, dY, nX, nY, nZ, oolen;
    char			normalmapname[256];

    // use sprintf to avoid pointer confusion from multiple nested va's
    va_snprintf("MakeDOT3", normalmapname, sizeof(normalmapname) - 1, "%s_norm", glt->identifier);

    // try for an external normal map
    dst = (unsigned int *) GL_TryForExternalTexture(glt, normalmapname);

    // we got one, so upload it
    if(dst)
    {
        int w, h;

        // get power of 2 dimensions
        for(w = 1; w < glt->width; w *= 2);
        for(h = 1; h < glt->height; h *= 2);

        // JESUS!  I never tested this in the old one...
        if(w > GLCaps.GL_MaxTextureSize)
        {
            w = GLCaps.GL_MaxTextureSize;
        }

        if(h > GLCaps.GL_MaxTextureSize)
        {
            h = GLCaps.GL_MaxTextureSize;
        }

        // now check for resizing
        if(w != glt->width || h != glt->height)
        {
            // allocated a buffer to hold the resampled data
            unsigned int *scaled = (unsigned int *) malloc(w * h * sizeof(unsigned int));

            // resize the texture
            GL_ResampleTexture(dst, glt->width, glt->height, scaled, w, h);

            // switch the data pointer
            free(dst);
            dst = scaled;
        }

        // now send it up to OpenGL
        glt->normtexnum = GL_UploadTextureToOpenGL(dst, w, h, (TEX_MIPMAP | TEX_NOCOMPRESS));
        free(dst);
        return;
    }

    // no external normal map so generate one from the texture data
    dst = (unsigned int *) malloc(width * height * sizeof(unsigned int) / 4);

    for(y = 0; y < height; y += 2)
    {
        for(x = 0; x < width; x += 2)
        {
            // Do Y Sobel filter
            ReadPixel(src, &pix, (x - 2 + width) % width, (y + 2) % height, width);
            dY  = ((float) pix.rgba.alpha) / 255.0f * -1.0f;
            ReadPixel(src, &pix, x % width, (y + 2) % height, width);
            dY += ((float) pix.rgba.alpha) / 255.0f * -2.0f;
            ReadPixel(src, &pix, (x + 2) % width, (y + 2) % height, width);
            dY += ((float) pix.rgba.alpha) / 255.0f * -1.0f;
            ReadPixel(src, &pix, (x - 2 + width) % width, (y - 2 + height) % height, width);
            dY += ((float) pix.rgba.alpha) / 255.0f *  1.0f;
            ReadPixel(src, &pix, x % width, (y - 2 + height) % height, width);
            dY += ((float) pix.rgba.alpha) / 255.0f *  2.0f;
            ReadPixel(src, &pix, (x + 2) % width, (y - 2 + height) % height, width);
            dY += ((float) pix.rgba.alpha) / 255.0f *  1.0f;

            // Do X Sobel filter
            ReadPixel(src, &pix, (x - 2 + width) % width, (y - 2 + height) % height, width);
            dX  = ((float) pix.rgba.alpha) / 255.0f * -1.0f;
            ReadPixel(src, &pix, (x - 2 + width) % width, y % height, width);
            dX += ((float) pix.rgba.alpha) / 255.0f * -2.0f;
            ReadPixel(src, &pix, (x - 2 + width) % width, (y + 2) % height, width);
            dX += ((float) pix.rgba.alpha) / 255.0f * -1.0f;
            ReadPixel(src, &pix, (x + 2) % width, (y - 2 + height) % height, width);
            dX += ((float) pix.rgba.alpha) / 255.0f *  1.0f;
            ReadPixel(src, &pix, (x + 2) % width, y % height, width);
            dX += ((float) pix.rgba.alpha) / 255.0f *  2.0f;
            ReadPixel(src, &pix, (x + 2) % width, (y + 2) % height, width);
            dX += ((float) pix.rgba.alpha) / 255.0f *  1.0f;

            // Cross Product of components of gradient reduces to
            // this is a suitable normal map for opengl - the direct3d equivalent (which ati assumes) is commented out
            nX = dY; //-dX;
            nY = -dX; //-dY;
            nZ = 1;

            // Normalize - nZ is always 1
            oolen = 1.0f / ((float) sqrt(nX * nX + nY * nY + nZ * nZ));
            nX *= oolen;
            nY *= oolen;
            nZ *= oolen;

            pix.rgba.red   = (byte) PackFloatInByte(nX);
            pix.rgba.green = (byte) PackFloatInByte(nY);
            pix.rgba.blue  = (byte) PackFloatInByte(nZ);

            WritePixel(dst, &pix.ui, x / 2, y / 2, width / 2);
        }
    }

    // upload the normal map data with specific properties
    glt->normtexnum = GL_UploadTextureToOpenGL(dst, width / 2, height / 2, (TEX_MIPMAP | TEX_NOCOMPRESS));

    // free dst
    free(dst);
}
Originally this code would spit out missing normalmaps and be done with it the next pass, but somewhere along the way i modified this function to just create them at runtime and upload them directly if missing, yep you guessed it huge performance hog by your's truely :evil: and one that could not be turned off because i newer got to the part of making a cvar to control this behaviour. Old behaviour was actually a nice feature but in my erm... wisdom i deleted the part that actually wrote a normalmap to disk so instead of just doing them one time and be done with it, it now creates them every damn frame because they are no longer saved to disk. Shoot me now :cry:
Productivity is a state of mind.
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Old school quake, well not quite but

Post by Spike »

... every frame? yeah, that's going to be a huge performance loss, definitely.
revelator
Posts: 2621
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: Old school quake, well not quite but

Post by revelator »

Yep and further i found out that the reason i newer made a cvar to control this behaviour is because realm needs normalmaps to function correctly, i just tried and every
texture that was missing a normalmap turned up with weird colors untill i reenabled it. Seems that i need to make some fallback method in case they are missing.
Productivity is a state of mind.
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Old school quake, well not quite but

Post by Spike »

defaultnormalmap = CreateTexture(TEXTURE_RGBA, 1, 1, "\x80\x80\xff\xff");
then they can all use the same image...
revelator
Posts: 2621
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: Old school quake, well not quite but

Post by revelator »

Ah your a lifesaver thanks m8 :)
Productivity is a state of mind.
revelator
Posts: 2621
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: Old school quake, well not quite but

Post by revelator »

Also spent a lot of time removing most of the hackiness from nehahra and using an opensource mod player instead of fmod,
still not quite there yet but its getting better by the day. Currently im missing the demo movie code and im running headlong into a rather obscure host error pointing me to svc_staticentities rather fun since both the server and client code was allmost a 1/1 copy of nehquakebjp minus a few things like qc controlled skyboxes which realm does not yet support, they are parsed non the less but newer forwarded, i took this code from bjp's enhanced glquake which can also load nehahra maps and does not suffer this bug, so its probably some obscure fuckup on my side.

This is turning into a full time job and i cannot do this kind of work anymore because of health issues,
so i'd better force myself to focus on other things (yeah like that's going to happen, but it must, even though i hate it) :lol: .
So as they say it will be done when its done, but i hope the wait will be worth it.
Productivity is a state of mind.
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Old school quake, well not quite but

Post by Spike »

you can greyscale (or whatever) the original 8bit image and treat it as a heightmap and generate a normalmap from that, which is what tenebrae did.
while FTE can do that, it doesn't do so by default because imho its ugly. I think DP is the same.
instead a normalmap with x=0,y=0,z=1 is perfectly sufficient. note that if your lighting directions are in worldspace then you'll need some sort of matrix to rotate the lighting directions into surface space (if you have an rtlight you can just do this on the cpu as you submit the texture coords for each vertex), and they also need to be normalised instead of saturating (cubemaps are handy for this if you're stuck with fixed function hardware). if you're doing deluxmapping (mapname.lux files) then both textures should already encode both vectors in surface space so you can just do a simple dotproduct and scale the per-pixel lighting by the result of that. Do note that you'll end up with darker lighting everywhere that the two vectors don't exactly match - you might want some bias or bounds or ambient lighting or something.

but yeah, if you want some placeholder normalmap, fill it with that pastely blue colour, and it'll effectively be perfectly flat.

and yes, removing hacks takes much longer than originally implementing them did... don't worry about removing them all at once because you'll never get it working again afterwards. :s

I assume you mean svc_spawnstatic... with the bjp1-3 protocols, the modelindex value is always a short. the vanilla protocol (including nehahra's demos) uses bytes.
if you can play a demo recorded by another engine using that protocol, then the problem is probably in your server (you can also run your server with -dedicated and see if the other client can connect okay as a demonstration that a server-protocol bug doesn't discriminate).
Post Reply