Hard Light Productions Forums
Modding, Mission Design, and Coding => FS2 Open Coding - The Source Code Project (SCP) => Topic started by: Sticks on September 12, 2003, 02:08:03 pm
-
Hey folks, my starfield eyecandy is almost working perfectly. Instead of drawing a series of lines or pixels, and system now draws point sprites with a simple star texture. The only problem I'm running into currently is that the sprites are being drawn on top of any objects in the scene.
My FVF is D3DFVF_XYZRHW | D3DFVF_DIFFUSE.
In the routine I set the x and y components of the vertex to the proper screen coordinates. I then set z and rhw to 1.0f. Is this correct? I'm not sure what z coordinates to set if I want the sprites to be drawn behind everything. What is the perpose of rhw?
Also, will using a vertex buffer to store the star vertices in batches afford me any performance benefits? As it was before, with specular on I only get about 15-20 fps in the heat of battle. Now in the same situation with the new star code, I'm only getting about 10-12 fps.
My guess is that this also has a lot to do with the lack of hardware T&L right now. Although, now that I think of it, even with ships really far away, I think speculars are still being calculated, because my frames plummet any time ships are onscreen, regardless of thier distance. Again, this would probably be mostly resolved with T&L, or at the very least relieved slightly.
-
Screenshot of the new system:
(http://www.muranowak.com/newstar.jpg)
-
I'm not a coder, at least not for a loooong time, for surely this could be fixed simply by rendering the stars before the foreground objects etc?
And I think you are right about Specular at the moment, but either way, I'm really hoping the coders can work their magic with HT&L, I am having similar problems with frame-rates at the moment :(
Flipside :D
LOL You posted as I was typing :)
Looks really nice! Are you running that in Windowed Mode, cos RT was desperately trying to find out about that in another thread?
-
Well sticks what do you change at the starfield.cpp i work on it too ?
http://www.hard-light.net/forums/index.php/topic,17396.0.html
-
/*
* Copyright (C) Freespace Source Code Project. All rights reserved.
*
* All source code herein is the property of FSCP. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
* Star particle class by Sticks
*/
#include "starparticle/starparticle.h"
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
SParticle *P = 0;
int sOffset = 0;
int sTotal = 0;
int sBatch = 0;
HRESULT hr;
DWORD FtoDw(float f)
{
return *((DWORD*)&f);
}
DWORD vbSize = sizeof (SParticle);
IDirect3DVertexBuffer8 *vb;
IDirect3DTexture8 *tex = NULL;
int starNum = 0;
void sp_init(int maxStars)
{
d3d_set_initial_render_state();
lpD3DDevice->SetRenderState(D3DRS_LIGHTING, false);
lpD3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, true);
lpD3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, true);
lpD3DDevice->SetRenderState(D3DRS_POINTSIZE, FtoDw(2.0f));
lpD3DDevice->SetRenderState(D3DRS_POINTSIZE_MIN, FtoDw(0.2f));
// control the size of the particle relative to distance
lpD3DDevice->SetRenderState(D3DRS_POINTSCALE_A, FtoDw(1.0f));
lpD3DDevice->SetRenderState(D3DRS_POINTSCALE_B, FtoDw(0.0f));
lpD3DDevice->SetRenderState(D3DRS_POINTSCALE_C, FtoDw(0.0f));
// use alpha from texture
lpD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
lpD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
lpD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
// lpD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
// lpD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
HRESULT hr = 0;
hr = lpD3DDevice->CreateVertexBuffer(
maxStars * sizeof(SParticle),
D3DUSAGE_DYNAMIC | D3DUSAGE_POINTS | D3DUSAGE_WRITEONLY,
D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT, // D3DPOOL_MANAGED can't be used with D3DUSAGE_DYNAMIC
&vb);
hr = D3DXCreateTextureFromFile(lpD3DDevice,"star.bmp",&tex);
lpD3DDevice->SetTexture(0, tex);
lpD3DDevice->SetStreamSource(0, vb, sizeof(SParticle));
// lpD3DDevice->GetVertexShader(IDirect3DVertexShader8** oldFVF);
}
void sp_destroy()
{
//lpD3DDevice->SetRenderState(D3DRS_LIGHTING, true);
//lpD3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, false);
//lpD3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, false);
//lpD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
// lpD3DDevice->SetVertexShader(oldFVF);
if (sBatch > 0) {
sp_render();
sBatch = 0;
}
d3d_set_initial_render_state();
}
void sp_add(vertex *pos)
{
if (sBatch == 0) {
vb->Lock(
sOffset,
sBatch * sizeof( SParticle ),
(BYTE**)&P,
sOffset ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD);
}
sBatch++;
sOffset++;
if (sBatch == 200) {
sp_render();
sBatch = 0;
}
P->x = pos->sx;
P->y = pos->sy;
P->z = 0.0f;
P->rhw = 1.0f;
P->color = 0xdddddddd;
P++;
}
void sp_render()
{
vb->Unlock();
hr = lpD3DDevice->DrawPrimitive(
D3DPT_POINTLIST,
sOffset,
sBatch);
}
It's a whole new set of point sprite code
-
thats gonna play hell with opengl, which doesnt natively support point sprites. we'd need to use gr_scaler()
-
Couldn't the opengl implementation use billboards? That's really all point sprites are anyway.
-
gr_scaler is basically a billboard. its nicely wrapped around g3_draw_bitmap()
int g3_draw_bitmap(vertex *pnt,int orient, float rad,uint tmap_flags)
-
Won't I have to calculate the orientation to the viewpoint still with that?
-
no. it does it for you. the orient parameter deals with UV stuff
-
I heard point sprites were not compatable with a lot of cards
so you might want to use some sort of compatability code to determine if you should do it this way the old way or some software version (scaler)
could you try to implement them for the paritle system, I think there would be a signifigant improvement, also if you want, it would be cool if we were to get some vertex bufering for the models, even if it isn't HT&L,
if we could just get the HT&L everything would run so much faster,
SO MUCH FASTER!!!!!!!
it driveing me crazy
posably could someone try the high level vertex buffer
I think if we handeled them in a manner similar to the way textures are handeled it could be done
-
well...
-
Sounds nice and technical to me and there was the word 'particle' in there, so it gets my vote ;)
As for the stars, maybe you could have a compatabilty swap with FT's new code, that way the player get's nice new stars no matter what?
Yes, I know how you feel with the speed thing, I have a GF4 MX440, and some of the Higher Poly ships are starting to cause stuttering :( I've turned the detail down a bit now, but that's a pity cos I want to see all the eye candy in full detail :D
Flipside :D
EDIT : Oh, would there be any chance of using FT's 'clustering' technique in this version as well? I think it makes the thing look so much nicer :)
-
This code doesn't actually change where the stars are drawn, just how they are drawn, so implementing the clustering should be easy enough.
As for implementing vertex buffering for the models, I'm not sure that I have the expertise to do it, but certainly I will try my hand at it.
Bob, if you could tell me where FS does it's lighting and transformation calculations, it would save me a ton of time with trying to figure out some way of putting T&L in. Again, while it may not look like it, I'm actually fairly new to this D3D coding stuff so any pointers and ideas would be great.
-
mmh, I suppose motion blur on the stars is gone, with that?
-
Originally posted by Sticks
This code doesn't actually change where the stars are drawn, just how they are drawn, so implementing the clustering should be easy enough.
As for implementing vertex buffering for the models, I'm not sure that I have the expertise to do it, but certainly I will try my hand at it.
Bob, if you could tell me where FS does it's lighting and transformation calculations, it would save me a ton of time with trying to figure out some way of putting T&L in. Again, while it may not look like it, I'm actually fairly new to this D3D coding stuff so any pointers and ideas would be great.
RandomTiger is already knee-deep in restructuring the graphics code so that the transformation and lighting will be done by hardware in a (hopefully) generalized way (vertex buffering should be kept abstract, so that you could use vertex buffers in D3D and ARB_vertex_buffer_object in OpenGL).
The way FS2 currently does everything is bad, and should be changed. Right now it goes something like this:
1) transform and light a polygon
2) send that polygon to the rasterizer (graphics card)
3) repeat until you're done
With modern graphics cards, the Right-Way-To-Do-Stuff™ is to batch as many stuff as possible. Assuming software TnL is retained, that means the sequence should be:
1) transform and light all polygons
2) send all the polygons to the rasterizer
Also, modern graphics cards dislike state changes. There seriously needs to be some scheme for tracking texture stage states, and all the drawing should be sorted by texture, since changing textures is still the slowest operation on a graphics card, by far.
All that information, of course, leads back to the fact that getting efficient rendering even if you're sticking with software TnL would still be annoying. Don't forget that everything needs a layer of abstraction, for cross-API compatability.
I applaud RT for working on this huge job.