Forum

Quake Video Code Rant

Discuss programming topics for the various GPL'd game engine sources.

Moderator: InsideQC Admins

Postby Baker » Wed Mar 02, 2011 10:25 am

leileilol wrote:It's one of the many reason Darkplaces has a software renderer now even.


Never would have guessed that. Although 4 years ago LH was saying if he ever made one it would look exactly the OpenGL version.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby qbism » Wed Mar 02, 2011 6:11 pm

Beyond hardware limitations, SW engine can be a choice of artistic medium: Will it better convey a particular idea?

In some cases the SW engine solves a lot of perception issues of blending and cohesion, the way the whole rendered scene fits together, especially with Makaqu-style shading. Objects and monsters really look like they're in the environment and not pasted-on. The gritty contrasting pixel-art of each frame fits with the dark and blocky scenes. That's one definition of "realism".
User avatar
qbism
 
Posts: 1236
Joined: Thu Nov 04, 2004 5:51 am

Postby Ranger366 » Wed Mar 02, 2011 6:40 pm

Image
Well, some stuff only looks good in software rendering.
In GLQuake or GLProQuake it looks like crap (no fullbright?).
Again, thanks leileilol for Engoo.
User avatar
Ranger366
 
Posts: 203
Joined: Thu Mar 18, 2010 5:51 pm

Postby Baker » Wed Mar 02, 2011 7:09 pm

Ranger366 wrote:In GLQuake or GLProQuake it looks like crap (no fullbright?).


If you like the original GLQuake look and feel, that is what GL ProQuake is supposed to be. Modern ProQuake has buried features like fullbrights, interpolation, overbrights but everything is off by default because it isn't the same as GLQuake.

Some people like the original old crusty GLQuake look. Kind of like how some people like the original old WinQuake look.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby leileilol » Wed Mar 02, 2011 11:41 pm

qbism wrote:In some cases the SW engine solves a lot of perception issues of blending and cohesion, the way the whole rendered scene fits together, especially with Makaqu-style shading.


I prefer lightgrid. It's possible to do lightgrids in software (even more so than glquake considering stock sources), and it's possible for DP to make them out of q1bsps. it's just nothing has proposed for an external file standard for it yet.
i should not be here
leileilol
 
Posts: 2783
Joined: Fri Oct 15, 2004 3:23 am

Postby Sajt » Thu Mar 03, 2011 12:28 am

Argh. I was 90% finished implementing lightgrid into hmap2 and darkplaces a few years ago, but never finished it. (They were stored in an external file.) It all worked except I didn't quite figure out the best algorithm for calculating the light position of a cell, especially if it straddles a wall and two separate rooms. It's worth noting that Quake maps are usually a lot more compact (e.g. thin floors with room below) than Quake3 maps, so maybe the huge lightgrid size of Q3 is inappropriate for Quake.
F. A. Špork, an enlightened nobleman and a great patron of art, had a stately Baroque spa complex built on the banks of the River Labe.
Sajt
 
Posts: 1215
Joined: Sat Oct 16, 2004 3:39 am

Postby revelator » Thu Mar 03, 2011 9:39 pm

heh reminds me of something i dug up while looking over the quake 2 xp source. i wonder if related ?.

Code: Select all
#define LIGHTGRID_STEP 128
#define LIGHTGRID_NUM_STEPS (8192/LIGHTGRID_STEP)   // 64
byte r_lightgrid[LIGHTGRID_NUM_STEPS * LIGHTGRID_NUM_STEPS * LIGHTGRID_NUM_STEPS][3];

//___________________________________________________________
void R_InitLightgrid(void)
{
   int      i, x, y, z;
   vec3_t   p, end;
   float   r;
   byte   *b;

   memset(r_lightgrid, 0, sizeof(r_lightgrid));

   if (!r_worldmodel->lightdata) return;

   b = &r_lightgrid[0][0];
   // Huh ?
   for (x = 0; x < 8192; x += LIGHTGRID_STEP) {
      for (y = 0; y < 8192; y += LIGHTGRID_STEP) {
         for (z = 0; z < 8192; z += LIGHTGRID_STEP) {
            end[0] = p[0] = x - 4096;
            end[1] = p[1] = y - 4096;
            end[2] = (p[2] = z - 4096) - 2048;
            r = RecursiveLightPoint(r_worldmodel->nodes, p, end);
            if (r != -1) {
               for (i = 0; i < 3; i++) {
                  float mu = pointcolor[i];
                  float f = mu * (2 * (1 - mu) + mu);
                  *b++ = 255.0 * f;
               }
            } else {
               b += 3;
            }
         }
      }
   }
}

//___________________________________________________________
void R_LightColor(vec3_t org, vec3_t color)
{
   byte      *b[8];
   int         i, lnum;
   dlight_t   *dl;
   float      f, light, add;
   vec3_t      dist;
   float      x = (4096 + org[0]) / LIGHTGRID_STEP;
   float      y = (4096 + org[1]) / LIGHTGRID_STEP;
   float      z = (4096 + org[2]) / LIGHTGRID_STEP;
   int         s = x;
   int         t = y;
   int         r = z;

   x = x - s;
   y = y - t;
   z = z - r;

   b[0] = &r_lightgrid[(((s * LIGHTGRID_NUM_STEPS) + t) * LIGHTGRID_NUM_STEPS) + r][0];
   b[1] = &r_lightgrid[(((s * LIGHTGRID_NUM_STEPS) + t) * LIGHTGRID_NUM_STEPS) + r + 1][0];
   b[2] = &r_lightgrid[(((s * LIGHTGRID_NUM_STEPS) + t + 1) * LIGHTGRID_NUM_STEPS) + r][0];
   b[3] = &r_lightgrid[(((s * LIGHTGRID_NUM_STEPS) + t + 1) * LIGHTGRID_NUM_STEPS) + r + 1][0];
   b[4] = &r_lightgrid[((((s + 1) * LIGHTGRID_NUM_STEPS) + t) * LIGHTGRID_NUM_STEPS) + r][0];
   b[5] = &r_lightgrid[((((s + 1) * LIGHTGRID_NUM_STEPS) + t) * LIGHTGRID_NUM_STEPS) + r + 1][0];
   b[6] = &r_lightgrid[((((s + 1) * LIGHTGRID_NUM_STEPS) + t + 1) * LIGHTGRID_NUM_STEPS) + r][0];
   b[7] = &r_lightgrid[((((s + 1) * LIGHTGRID_NUM_STEPS) + t + 1) * LIGHTGRID_NUM_STEPS) + r + 1][0];

   f = ((float) 4 / (float) (255));

   if (!(b[0][0] && b[0][1] && b[0][2])) {
      f -= (1.0 / (510.0)) * (1 - x) * (1 - y) * (1 - z);
   }
   if (!(b[1][0] && b[1][1] && b[1][2])) {
      f -= (1.0 / (510.0)) * (1 - x) * (1 - y) * (z);
   }
   if (!(b[2][0] && b[2][1] && b[2][2])) {
      f -= (1.0 / (510.0)) * (1 - x) * (y) * (1 - z);
   }
   if (!(b[3][0] && b[3][1] && b[3][2])) {
      f -= (1.0 / (510.0)) * (1 - x) * (y) * (z);
   }
   if (!(b[4][0] && b[4][1] && b[4][2])) {
      f -= (1.0 / (510.0)) * (x) * (1 - y) * (1 - z);
   }
   if (!(b[5][0] && b[5][1] && b[5][2])) {
      f -= (1.0 / (510.0)) * (x) * (1 - y) * (z);
   }
   if (!(b[6][0] && b[6][1] && b[6][2])) {
      f -= (1.0 / (510.0)) * (x) * (y) * (1 - z);
   }
   if (!(b[7][0] && b[7][1] && b[7][2])) {
      f -= (1.0 / (510.0)) * (x) * (y) * (z);
   }

   for (i = 0; i < 3; i++) {   
      // hahaha slap me silly
      color[i] = (1 - x) * ((1 - y) * ((1 - z) * b[0][i] + (z) * b[1][i]) + y * ((1 - z) * b[2][i] + (z) * b[3][i])) + x * ((1 - y) * ((1 - z) * b[4][i] + (z) * b[5][i]) + y * ((1 - z) * b[6][i] + (z) * b[7][i]));
      color[i] *= f;

      if(color[i] <= 0.35) {
         color[i] = 0.35;
      }
   }

   // add dynamic light
   light = 0;
   dl = r_newrefdef.dlights;

   for (lnum = 0; lnum < r_newrefdef.num_dlights; lnum++, dl++) {
      VectorSubtract(org, dl->origin, dist);
      f = ((dl->intensity * 2) - VectorLength(dist)) / (dl->intensity * 2);
      if (f <= 0)   continue;
      add = f * (0.2 + (0.8 * f));
      if (add > 0.01) {
         VectorMA(color, add, dl->color, color);
      }
   }
}

//___________________________________________________________
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Postby dreadlorde » Fri Mar 04, 2011 12:03 am

:(
Ken Thompson wrote:One of my most productive days was throwing away 1000 lines of code.

Get off my lawn!
User avatar
dreadlorde
 
Posts: 268
Joined: Tue Nov 24, 2009 2:20 am

Postby Baker » Wed Mar 09, 2011 5:46 pm

As I'm detangling the video code in my own engine ...

Code: Select all
   //johnfitz -- get desktop bit depth
   hdc = GetDC(NULL);
   modelist[0].bpp = desktop_bpp = GetDeviceCaps(hdc, BITSPIXEL);
   ReleaseDC(NULL, hdc);
   //johnfitz

   //johnfitz -- get refreshrate
   if (EnumDisplaySettings (NULL, ENUM_CURRENT_SETTINGS, &devmode))
      modelist[0].refreshrate = devmode.dmDisplayFrequency;


Better would probably be ...

Code: Select all
   //johnfitz -- get refreshrate
   if (EnumDisplaySettings (NULL, ENUM_CURRENT_SETTINGS, &devmode))
   {
      modelist[0].refreshrate = devmode.dmDisplayFrequency;
      modelist[0].bpp = desktop_bpp = devmode.dmBitsPerPel;  // Get desktop BPP from devmode
   }
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby Baker » Wed Mar 09, 2011 7:57 pm

So much wrong and bad stuffs in the legacy video code

Code: Select all
/*
================
CenterWindow
================
*/
static void CenterWindow (HWND hWndCenter, int width, int height)
{
   int     CenterX, CenterY;

   CenterX = (GetSystemMetrics(SM_CXSCREEN) - width) / 2;
   CenterY = (GetSystemMetrics(SM_CYSCREEN) - height) / 2;
   if (CenterX > CenterY*2)
      CenterX >>= 1;   // dual screens
   CenterX = (CenterX < 0) ? 0 : CenterX;
   CenterY = (CenterY < 0) ? 0 : CenterY;
   SetWindowPos (hWndCenter, NULL, CenterX, CenterY, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_DRAWFRAME);
}


This just isn't true in a world with widescreen displays ...

Code: Select all
   if (CenterX > CenterY*2)
      CenterX >>= 1;   // dual screens
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby metlslime » Wed Mar 09, 2011 10:59 pm

Baker wrote:So much wrong and bad stuffs in the legacy video code
This just isn't true in a world with widescreen displays ...

Code: Select all
   if (CenterX > CenterY*2)
      CenterX >>= 1;   // dual screens


I think it will still mostly work ... there isn't a widescreen display with a > 2:1 aspect ratio is there?
metlslime
 
Posts: 316
Joined: Tue Feb 05, 2008 11:03 pm

Postby mh » Wed Mar 09, 2011 11:44 pm

There is; I got a person who's tested crazy modes like 3200x1200 and 3840x1440. ATI EyeFinity stuff will also give you a width over 3 times your height on one virtual display device. It also needs to account for window resizing.

GetSystemMetrics (SM_CMONITORS) is probably a better way of checking for dual displays. Not portable of course, but perfectly OK to use if you're a Windows-only engine.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby metlslime » Thu Mar 10, 2011 12:35 am

I meant a single display. If your desktop is > 2:1 with multiple monitors (e.g. EyeFinity), this code would successfully detect that.

Of course with 3 monitors it will fail to pick an acceptable window position :)

It would also fail to detect two vertical monitors (popular among coders) and various other configurations.
metlslime
 
Posts: 316
Joined: Tue Feb 05, 2008 11:03 pm

Postby Baker » Thu Mar 10, 2011 1:49 am

mh wrote:There is; I got a person who's tested crazy modes like 3200x1200 and 3840x1440. ATI EyeFinity stuff will also give you a width over 3 times your height on one virtual display device. It also needs to account for window resizing.

GetSystemMetrics (SM_CMONITORS) is probably a better way of checking for dual displays. Not portable of course, but perfectly OK to use if you're a Windows-only engine.


Thanks in advance. You saved me a Googling.

Yeah, not portable but none of vid_wgl.c/gl_vidnt.c is. Although ironically one reason I am detangling the video code is to make native OS X (for sure) and maybe someday Linux versions of at this engine.

metlslime wrote:
Baker wrote:So much wrong and bad stuffs in the legacy video code
This just isn't true in a world with widescreen displays ...

Code: Select all
   if (CenterX > CenterY*2)
      CenterX >>= 1;   // dual screens


I think it will still mostly work ... there isn't a widescreen display with a > 2:1 aspect ratio is there?


It wasn't centering my Window properly on a single monitor laptop running 1400x900. I think I was running a 600x600 window. 1400-600=900. 900-600 = 300. 900 > (300*2) = true = calculation fail. Yeah I was using an irregular screen size, but there isn't a reason I shouldn't be able to.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby metlslime » Thu Mar 10, 2011 2:48 am

ah... wow that is broken. I didn't notice that the comparison wasn't between desktop height/width, but between x and y of a candidate centerpoint.

:P
metlslime
 
Posts: 316
Joined: Tue Feb 05, 2008 11:03 pm

PreviousNext

Return to Engine Programming

Who is online

Users browsing this forum: No registered users and 1 guest