Tuesday, April 24, 2012

Particles

I came down on OpenGL a little heavier than on D3D in the last post, so to redress the balance I have to say that OpenGL instancing is very nice indeed; much nicer than D3D.

Here's some code:

void R_DrawParticles (void)
{
 int i, j;
 particle_t *p;

 if (!r_newrefdef.num_particles) return;

 GL_UseProgram (gl_particleprog);

 glUniformMatrix4fv (u_partmatrix, 1, GL_FALSE, r_mvpmatrix.m[0]);
 glUniform3fv (u_partrorigin, 1, r_origin);
 glUniform3fv (u_partvpn, 1, vpn);
 glUniform3fv (u_partvright, 1, vright);
 glUniform3fv (u_partvup, 1, vup);

 GL_Enable ((BLEND_BIT | DEPTHTEST_BIT) | (gl_cull->value ? CULLFACE_BIT : 0));

 GL_EnableVertexAttribArrays (VAA0 | VAA1 | VAA2);
 glBindBuffer (GL_ARRAY_BUFFER, gl_particledynamicvbo);

 if (r_firstparticle + r_newrefdef.num_particles >= MAX_PARTICLES)
 {
  glBufferData (GL_ARRAY_BUFFER, MAX_PARTICLES * sizeof (particle_t), NULL, GL_STREAM_DRAW);
  r_firstparticle = 0;
 }

 glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, sizeof (particle_t), (void *) (r_firstparticle * sizeof (particle_t)));
 glVertexAttribPointer (1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof (particle_t), (void *) (r_firstparticle * sizeof (particle_t) + 12));

 if ((p = glMapBufferRange (GL_ARRAY_BUFFER, r_firstparticle * sizeof (particle_t), r_newrefdef.num_particles * sizeof (particle_t), BUFFER_MAP_BITS)) == NULL)
 {
  ri.Con_Printf (PRINT_ALL, "R_DrawParticles : glMapBufferRange failed\n");
  return;
 }

 memcpy (p, r_newrefdef.particles, r_newrefdef.num_particles * sizeof (particle_t));
 glUnmapBuffer (GL_ARRAY_BUFFER);

 glBindBuffer (GL_ARRAY_BUFFER, gl_particletexcoordvbo);
 glVertexAttribPointer (2, 2, GL_FLOAT, GL_FALSE, 0, (void *) 0);

 glVertexAttribDivisor (0, 1);
 glVertexAttribDivisor (1, 1);

 glDrawArraysInstanced (GL_TRIANGLE_FAN, 0, 4, r_newrefdef.num_particles);

 glVertexAttribDivisor (0, 0);
 glVertexAttribDivisor (1, 0);

 r_firstparticle += r_newrefdef.num_particles;
}

11 comments:

Marty said...

This isn't 100% confirmed, but I believe I have found the reason for my DirectQ 1.9.0 hard crash, which always rebooted Window. Since August I have had a Logitech webcam and had installed its drivers and software. I used Revo Uninstaller to do a thorough uninstall of it's software and drivers, then unplugged the web cam and rebooted. After I rebooted I plugged the webcam back in and let Window XP install it's default USB Video Device driver and the webcam works fine on Skype and DirectQ 1.9.0 with addon textures and models hasn't crashed since. I played through most of Negke's Bad Dark Cistern, with no crashes.

Marty said...

I spoke too soon it is still crashing, just not soon after demo loads, like before. I guess I could try a clean nvidia driver install, but I did that when the latest 296.10 WHQL drivers were released, I believe. Nvidia AGP 7600GS 512Mb. I am also going to diable fastwrites in Rivatuner, as that is the Nvidia default. This card is at stock speeds. Nforce 2 board is in performance mode in the bios.
Other games haven't crashed though. Darkplaces takes almost any external replacement content I throw at it, but for the most part I prefer DirectQ for it's speed and realistic classic look.

mhquake said...

Comparing with DarkPlaces isn't going to be very meaningful - for example, DarkPlaces does a lot of stuff in software that DirectQ does in hardware instead.

I'd definitely recommend reverting your settings back to defaults and seeing what happens. My experience is that any optimization in a driver control panel always comes with a tradeoff, and that tradeoff is often quality or stability.

It may well work with everything else, but all it takes is a program that stresses the hardware in a different manner to come along and it may stop working.

Marty said...

I reverted back to DirectQ 1.8.8 after I did a clean reinstall of the Nvidia driver. I haven't tested 1.9.0 after the clean Nvidia driver install, because, frankly, I was tired of my system crashing only under DirectQ. No other games I have tried have crash, so I am at a loss?
Addons: Plagues-Weapons, QRP_item_textures_v.0.73_dp, qrp-maptextures-2007-10-06r2.pk3, LIT files,wav's for music tracks, gfx\conback.tga, conchars.png, conchars.tga. vised maps, Darkplaces and it's dll's in the same Quake folder.

Anonymous said...

DirectQ 1.8.8 Patch 2 crashed, the same as 1.90 so I went back to DirectQ 1.8.8 2011-08-11 without trying any releases in between and I was able to play Negke's Bad Dark Cistern all the way through, without any crashes. Something was added between 8/2011 and 12/2011 that is causing my system to crash. I fully understand that you have moved on to a Direct X 11 build, so the Direct X 9 build is now low priority. Thanks for you help and all of the hard work you do to keep Quake alive.

Marty said...

I confirmed that the crashes started with 1.8.8 Patch 1. I played through several map with DirectQ 1.8.8 2011-08-11 and have not experienced one crash as with newer releases. What were the changes starting with 1.8.8 Patch 1? Thanks

mhquake said...

OK, that's useful to know. I'll need to dig through the code to find possible candidates for causing this, but at least I now have two versions I can compare directly with not too much changed between them.

Marty said...

The only thing I can narrow down any more is that the most of the time the crash happens when the demo is playing and after I hit escape, or when I choose new game. After I removed my logitech webcam drivers and software I could sometimes play the game for a while before the crash. I then did a Nvidia geforce driver clean install and for good measure, reinstalled DirectX 9.0c before I retested the versions mentioned earlier.

stoo said...

Sorry to drop in with an unrelated question, but can you describe the expected behaviour of cl_autoaim 0?

There is _definitely_ some autoaim occurring even with cl_autoaim set to 0.

Recorded a quick video showing what I mean here.

I didn't show it in the video, but the behaviour is identical with cl_autoaim 1.

stoo said...

*sigh*

Ignore me. Guess what moron forgot to set sv_aim 1?

That's right, this moron.

=peg= said...

*bump*

(Just in case my previous posts in the clipping bug thread have slipped under the radar..)