Thread: DirectX8 FVFs

  1. #1
    Registered User
    Join Date
    Jun 2003
    Posts
    361

    DirectX8 FVFs

    Just a quick question about D3DFVF_DIFFUSE, D3DFVF_XYZRHW and other definitions like that. I'm trying to make a function to declare a FVF manually, by passing through the necessery boolean flags, and the function will initialize the appropriate FVF. But I'm wondering what to store the combined flags as.

    I.e. for "Window Creation" you can set a whole bunch of styles under a DWORD variable.
    (DWORD Styles = Style1|Style2|Style3);

    And so forth. Is it possible to use a DWORD type variable to hold values for each FVF "style"? Even after looking at the definition of DWORD (unsigned long), it doesn't help me much to figure out if it's useable or not.

    Any insight's welcome.

    Erik

  2. #2
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    The current FVF flags can all be described by 2 bytes. You might want to just use 4 anyways in case they add more later.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  3. #3
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    There are 2 rules for defining FVFs.

    1. The FVF declaration must match the order of the members.

    For instance:

    struct TestVertex
    {
    float x,y,z;
    float nx,ny,nz;
    float u,v;

    static const DWORD FVF;
    };

    The FVF declaration for this vertex structure has to be:

    const DWORD FVF=D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;

    Because you have defined it as position vector, normal vector, texture coords. Any other definition will cause problems.

    2. There are certain flags that cannot be combined and certain ones that do not work on all video cards. Take the point size declaration for point sprites. Not all video cards support variable size point sprites and most only support 64x64 pixel point sprites. Anything outside of this range will default back to 64x64 - which is one reason why I rarely use point sprites because they are so limited. However they are nice for particle effects like snow, stars, rain, etc. They are not good for stuff like len's flares, corona's, fire, etc.

    Other than that I've always seen FVF's defined as DWORDs.
    So I'm not sure what the exact values for the declarations are. I just use a DWORD to be safe and quite honestly I have bigger fish to fry than wondering whether or not FVF is a 2 byte or 4 byte value.

  4. #4
    Registered User
    Join Date
    Jun 2003
    Posts
    361
    Cool, thanks for the info, but I just realized I probably can't do this anyways.....I was being stupid not remembering that I actually have to declare a structure for a vertex....hmm....I'd have to write out all the possible structures (with all the combinations I want to allow), and then create a variable based on the data...but that wouldn't work anyways because the variable would quickly go out of scope....hmm....

    Has anyone ever done this before? Or any ideas better than writing out a large number of structures to meet every possible combination of flags?

    Thanks for the help so far

    [EDIT]
    Forget it I'm giving up, I don't know if this is a cheap way to get around the problem or not, but I'm pretty much just going to declare the structure to use all of the flags I want, which actually don't turn out to be that many, but still a considerable amount. And then I'll just use the values I need when I need them.

    Along a somewhat same line, but not quite, I'm just wondering...
    Code:
    //VALUE DEFINITIONS
    #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1)
    
    //VERTEX STRUCTURE
    struct CUSTOMVERTEX
    {
    	float X, Y, Z, RHW;
    	unsigned long Colour;
    	float TU, TV;
    };
    How, oh how, do I store vertices as a private member variable in a class?

    The good ol'
    Code:
    CUSTOMVERTEX m_pVertices[] ={
    //INSERT ALL INFO HERE
    }
    Method does not work, as I can't initialize variables in the class definiton. Which works out sort of okay because I'm planning to initalise all values through code with AddSquareToBuffer() functions and the such, but still I need a member variable to hold my vertices...

    Which left me trying:
    Code:
    CUSTOMVERTEX m_pVertices[];
    //OR
    CUSTOMVERTEX m_pVertices;
    Both of which my compiler does not seem to enjoy very thoroughly.

    Another idea was to create the m_pVertices variable at another point, but it doesn't take long to see that a function will quickly go out of scope and leave me without the information anymore. Unless I pass it along from function to function....all the time....without rest.

    Is there something simple I'm missing here?
    Note: I'm hoping to stay away from the
    Code:
    #define BE_INEFFICIENT_AS_POSSIBLE 1000000000
    CUSTOMVERTEX m_pVertices[BE_INEFFICIENT_AS_POSSIBLE];
    Method...

    Thanks for any help
    Erik
    [/EDIT]
    Last edited by Epo; 09-28-2004 at 10:28 PM. Reason: I gave up on the old problem and tackled a new one...then I noticed a typo...then I noticed another....then I added my structure and definition....then I fixed another typo

  5. #5
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    You are incorrect, my friend. If you declare your vertexes as the type of vertex you have declared then the variable will not go out of scope in your class or in your code. Also DirectX provides several default configs of vertexes and is quite useful.

    What do you need in your vertex??? Normals? Texture coords? Position? Point size (for point sprites)? ??? You can include all of this information in DirectX.

    This is an example of a vertex that has a position vector, normal vector, and texture coordinates. Note that you can also create a constructor inside the vertex structure because in ALL Direct3D SetStreamSource() calls in prep for a DrawPrimitive or DrawIndexedPrimitive you must pass in the stride factor. The stride factor is essentially the size of one vertex. In this way you can store more information than DirectX uses and still be able to send it through the fixed function pipeline.

    I'm going to write a fair amount of code here to show you how a lot of this fits together.

    CFileLog.h
    Code:
    #ifndef CFILELOG
    #define CFILELOG
     
    #include <fstream.h>
    #include <time.h>
     
    class CFileLog
    {
    char curtime[10];
    char curdate[10];
    public:
     
    	ofstream File;
    	CFileLog(void) {};
    	~CFileLog(void) {File.close();};
     
    	void UpdateDateTime(void)
    	{
    	 _strtime(curtime);
    	 _strdate(curdate);
    	}
     
     
    	char *GetTime(void) {return curtime;};
    	char *GetDate(void) {return curdate;};
     
    	void Create(const char *filename,const char *title) 
    	{
    	 File.open(filename);
     
    	 //Put header in
    	 File << title << endl;
    	 UpdateDateTime();
    	 File << "Created on " << curdate << " at "<<curtime<<endl;
    	 File << "--------------------" << endl;
    	 File << endl;
    	}
    	void Close(void) {File.close();};
    };
    #endif
    Object3D.h
    Code:
     
    #ifndef OBJECT3D
    #define OBJECT3D
     
    #include "CFileLog.h"
    #include <string>
    #include "d3dx9.h"
     
    struct CustomVertex
    {
      D3DXVECTOR3 pos;
      D3DXVECTOR3 normal;
      float u,v;
     
      static const DWORD FVF;
      CustomVertex(D3DXVECTOR3 _pos,D3DXVECTOR3 _normal,float _u,float _v):pos
    (_pos),normal(_normal),u(_u),v(_v) {}
    };
     
    class Object
    {
    protected:
    	CFileLog ObjectLog;
     
    	D3DXVECTOR3 World_pos;
    	D3DXVECTOR3 Model_rotation;
    	D3DXVECTOR3 World_rotation;
     
    	IDirect3DDevice9 *Device;
    	IDirect3DVertexBuffer9 *VB;
    	IDirect3DIndexBuffer9 *IB;
    	IDirect3DTexture9 *Texture;
     
    	int NumVertices;
    	int NumTriangles;
     
    	void SetTexture(std::string File)
    	{
    	 if (FAILED(D3DXCreateTextureFromFile(Device,File.c_str(),&Texture)))
    	 {
    		 Object.Log.File << "Failed to load object texture" << endl;
    		 return;
    	 }
    	}
      public: 
    	 Object(void) { ...init all vars to 0 or NULL... };
    	 ~Object(void)
    	{
    	  if (VB) VB->Release();
    	  if (IB) IB->Release();
    	  if (Texture) Texture->Release();
    	}
    	void Init(IDirect3DDevice9 *_device,const char *LogFilename,const char *LogTitle,std::string TextureFile) 
    	{
    	  Device=_device;
    	  ObjectLog.Create(LogFilename,LogTitle);
    	  SetTexture(TextureFile);
    	}
    	void Create(D3DXVECTOR3 _worldpos,D3DXVECTOR3 _modelrot,D3DXVECTOR3 _worldrot)
    	{
    	  World_pos=_worldpos;
    	  Model_rotation=_modelrot;
    	  World_rotation=_worldrot;
    	  NumVertices= <...your data goes here...>;
    	  int NumFaces= <...your data goes here...>;
    	  NumTris=		 <...your data goes here...>
    	  int NumIndices=<...your data goes here...>;
     
    	  Device->CreateVertexBuffer(NumVertices,D3DUSAGE_WRITEONLY,CustomVertex::FVF,D3DPOOL_MANAGED,&VB,NULL);
     
    	  CustomVertex *Vertices;
    	  VB->Lock(0,0,(void **)&Vertices,0);
     
    	  //Fill in your object vertex data here
     
    	  VB->Unlock();
     
    	  Device->CreateIndexBuffer(NumIndices,D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,D3DPOOL_MANAGED,&IB,NULL);
     
    	  WORD *Indices;
    	  IB->Lock(0,0,(void **)&Indices,0);
     
    	  //Fill in your index data here
     
    	  IB->Unlock();
    	 }
     
    	 void Render(float timeDelta)
    	 {
    	   D3DXMATRIX trans;
    	   D3DXMatrixTranslation(&trans,World_pos.x,World_pos.y,World_pos.z);
     
    	   D3DXMATRIX mrot;
    	   D3DXRotationYawPitchRoll(&mrot,Model_rotation.x,Model_rotation.y,Model_rotation.z);
     
    	   D3DXMATRIX wrot;
    	   D3DXRotationYawPitchRoll(&wrot,World_rotation.x,World_rotation.y,World_rotation.z)
     
    	   D3DXMATRIX world;
    	   world=mrot*trans*wrot;
     
    	   Device->SetTransform(D3DTS_WORLD,&world);
     
    	   //Set any custom render states applicable to this object only here
     
    	   Device->SetStreamSource(0,&VB,0,sizeof(CustomVertex));
    	   Device->SetIndices(&IB);
    	   Device->SetFVF(CustomVertex::FVF);
    	   Device->SetTexture(0,Texture);
    	   Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,NumVertices,0,NumTris);
     
    	   //Disable custom render states here so they are not applied to other objects
    	 }
    };
    Lots of code but it shows a good example of how you might fit all of this together. Feel free to use it.
    Last edited by VirtualAce; 09-29-2004 at 12:10 AM.

  6. #6
    Registered User
    Join Date
    Jun 2003
    Posts
    361
    Hm, I probably should have mentioned this before, but I'm using DX8. Is there anything in this code that I can't convert to DX8 strictly due to the functions or variable types not existing? (Not that it may be difficult to translate, but is there something that I actually can not physically do under DX8?)

    But this is awesome, thanks for the code so far, I've been trying to pick it apart for the last couple of days, and it's slowly coming along.

    I've just a question about:
    Code:
     Device->CreateVertexBuffer(NumVertices,D3DUSAGE_WRITEONLY,  CustomVertex::FVF,D3DPOOL_MANAGED,&VB,NULL);
    Specifically the:
    CustomVertex::FVF
    part. I see you declare FVF as a "static const", but, when in the world does it ever get assigned a value if it's a "const" and not actually initialized right then and there in your structure definition? (From what I can tell anyways)

    Also, just a general question about classes I guess, I didn't know I could actually initialize variables within the header file as so:
    Code:
    Constructor(void) {var1(0), var2(0)};
    I'm pretty sure that's the method I saw being used a while back, but there might be some syntax (or just general) problems with what I wrote there, but I think you can get what I mean. The question is, say my variable is a pointer, or another type that I generally initalise as NULL. Will the "(0)" do the same job, or should I put "(NULL)" instead? (I don't know if this is a ridiculous question, all common sense is telling me to put (NULL), but before I start using this new method I want to be absolutely sure)

    Thanks again, I really appreciate the help you've given so far (You too MrWizard)

  7. #7
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Heyo. You are right, he didn't put the line of code that assigns the const it's value. You will need something like:

    Code:
    const DWORD CustomVertex::FVF = D3DFVF_XYZ; // whatever
    You can put that in the header after the declaration or in the associated cpp file if you want.

    As far as the class constructor assignments. You have to do it as follows:

    Code:
    // ctor
    Foo::Foo(void) : m_myFloat(5.3f), m_myInt(100) { }
    You see the syntax? Those assignments do not go within the curly braces. You can put whatever else you want in the body of the constructor but those initializations go before the braces and after the colon.

    You can use NULL or 0 for the pointer. I personally use NULL but that's just a preference. Feel free to use 0 if you prefer.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  8. #8
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    That's because all my code was in Object3D.h. The const assignment goes into Object3D.cpp - but I didn't want to write a header and a source file on the board so I merged it into one.

    I'm not sure if MSVC will accept assigning the const a value inside of the header. I've had problems with this approach. The problem is that when the header is included it is re-assigned. This should be taken care of by the multiple include check using the #ifndef blocks, but for some reason MSVC still says that the FVF has been redefined. Assigning values to variables in headers will always result in problems. I've never been able to assign any variable to any value inside of a header save for #define's and other macro definitions.

  9. #9
    Registered User
    Join Date
    Jun 2003
    Posts
    361
    Awesome, thanks for clearing that up guys.

    Just a quick question about boolean variables. For some reason, I'm getting odd results when passing them as references. I.e.
    Code:
    int main(void)
    {
    	bool bVar = false;
    	setBool(&bVar);
    
    	while(bVar)
    	{
    		MessageBox(NULL, "Should See This", "Blah", MB_OK);
    		bVar = false;
    	}
    
    	return 0;
    }
    
    void setBool(bool *bVar)
    {
    	*bVar = true;
    }
    This is a very simple version of the code I'm using, and my problem is that once I get to that "while" loop, the program just hangs. It doesn't go into the loop at all, it just sits there and doesn't want to go any further.

    I've stepped through and watched the value of my boolean variable, and everything seems to be working fine, I get a 0 when it's false, and a 1 for the boolean variable in the main function. But, when MSVC shows me the value, it looks something like:
    bVar = 1 "|"
    Now, while the 1 is correct, I don't know what the big straight line is doing in the quotes. To make a short question ridiculously long, it's okay to pass boolean variables as references right?

    I started writing this code (not the code you see above) about a year ago, and it's awesome for me to see how it's come along, mainly thanks to the help I've gotten here on this board. It's gone from one enormous CPP file with about 30 global variables to a nice mish-mash of a main cpp file and classes and pointers, and as the days go by, it just looks prettier and prettier Thanks again for all the help everyone here's given.

  10. #10
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    The code should work fine. Are you using VC6? I tested it out just to double-check and it worked as advertised on my machine.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  11. #11
    Registered User
    Join Date
    Jun 2003
    Posts
    361
    It's times like this I wonder how I've ever learned to program enough to be attempting DirectX. You're right, the code above works perfectly, just as it should...

    It wouldn't work, though, if for some reason one was to place a semi-colon at the end of the while(bVar) line....like I had.

    Thanks for testing out the code and in turn making me take a second (closer) look at mine.

  12. #12
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Man I've made that same error about a billion times. I'll go searching through line after line of code only to find it was my own stupid fault.

    I also love it when I implement some new class in my game and then MSVC proceeds to puke out about 50,000 errors along with 10,000 warnings, when I only added 20 lines of code at the max.

    I'm starting to understand MSVC extremely cryptic and extremely long errors. If anyone from MS is reading this which I doubt they are - please write your errors in English and please keep them short enough that I don't have to scroll over 20 times just to read the error.

    Borland definitely has a monopoly over MS on one thing - compilers that are easy to use.

  13. #13
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    Braces should be mandatory. It would save a lot of trouble and it wouldn't hurt readability that much.
    My program teacher forbade everyone to write compund statements withot braces.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  14. #14
    Registered User
    Join Date
    Jun 2003
    Posts
    361
    Alright, I've gotten through much of your code (Bubba) and translated it into something working, thanks again for the help, it's pushed this project of mine along very nicely (AND it made me learn about Index Buffers and what they are)

    Other than the fact that this code is grossly unneccessary and accomplishes absolutely nothing, is there anything wrong with the following code:
    Code:
    HRESULT cObject2D::InitVBuffer()
    {
    	HRESULT Attempt;
    
    	Attempt = m_pD3DDevice->CreateVertexBuffer(4 * sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &m_pVBuffer2D);
    	if(FAILED(Attempt))
    		return E_FAIL;
    
    	m_pVBuffer->Release();
    	m_pVBuffer = NULL;
    
    	Attempt = m_pD3DDevice->CreateVertexBuffer(10 * sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &m_pVBuffer2D);
    	if(FAILED(Attempt))
    		return E_FAIL;
    
    	m_pVBuffer->Release();
    	m_pVBuffer = NULL;
    
    	Attempt = m_pD3DDevice->CreateVertexBuffer(1 * sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &m_pVBuffer2D);
    	if(FAILED(Attempt))
    		return E_FAIL;
    
    	m_pVBuffer->Release();
    	m_pVBuffer = NULL;
    
    	Attempt = m_pD3DDevice->CreateVertexBuffer(1000 * sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &m_pVBuffer2D);
    	if(FAILED(Attempt))
    		return E_FAIL;
    
    	m_pVBuffer->Release();
    	m_pVBuffer = NULL;
    
    	return S_OK;
    }
    m_pD3DDevice is a private member variable of my class

    I know that there is absolutely no time I would ever use this, but it's the question of Releasing, Nulling, then Re-Initializing a Vertex Buffer that I'm curious whether will work. If so, this may just solve my problem of adding Vertices on the fly...but I'll be more specific about it once I get there Until then, I'm curious about the code above...Thanks

  15. #15
    Registered User
    Join Date
    Jun 2003
    Posts
    361
    Under the assumption that the above code was going to work, I went ahead and tried out my plan, here's some (somewhat lengthy) code:
    Code:
    //IN THE HEADER
    IDirect3DDevice8 *m_pD3DDevice;
    IDirect3DVertexBuffer8 *m_pVBuffer2D;
    
    //THIS CODE INITIALIZES ONE CUSTOM VERTEX TYPE THE FIRST
    //TIME BECAUSE I CAN'T WORK WITH AN EMPTY VERTEX BUFFER
    HRESULT cObject2D::InitVBuffer()
    {
    	HRESULT Attempt;
    	CUSTOMVERTEX *VBufferVertices;
    
    	Attempt = m_pD3DDevice->CreateVertexBuffer(1 * sizeof(CUSTOMVERTEX), 0,
    					D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &m_pVBuffer2D);
    	if(FAILED(Attempt))
    		return E_FAIL;
    
    	Attempt = m_pVBuffer2D->Lock(0, 1 * sizeof(CUSTOMVERTEX), (BYTE**)&VBufferVertices, 0);
    	if(FAILED(Attempt))
    		return E_FAIL;
    
    	VBufferVertices[0].vPosition = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
    	VBufferVertices[0].Colour = D3DCOLOR_XRGB(0, 0, 0);
    
    	m_pVBuffer2D->Unlock();
    
    	m_pNumV += 1;
    
    	AddBox(D3DXVECTOR3(50.0f, 0.0f, 1.0f), 40.0f, 40.0f);
    	AddBox(D3DXVECTOR3(0.0f, 50.0f, 1.0f), 40.0f, 40.0f);
    
    	return S_OK;
    }
    
    //HERE'S WHERE ALL THE MAGIC HAPPENS
    HRESULT cObject2D::AddBox(D3DXVECTOR3 Coords, float fWidth, float fHeight)
    {
    	IDirect3DVertexBuffer8 *VBufferStorage = NULL;
    	CUSTOMVERTEX *VBufferVertices = NULL;
    	HRESULT Attempt;
    
    	//CREATE TEMP BUFFER TO HOLD OLD DATA
    	Attempt = m_pD3DDevice->CreateVertexBuffer(m_pNumV * sizeof(CUSTOMVERTEX), 0, 
    								D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT,
    								&VBufferStorage);
    	if(FAILED(Attempt))
    		return E_FAIL;
    
    	//COPY OLD DATA TO TEMP BUFFER
    	*VBufferStorage = *m_pVBuffer2D;
    
    	//CLEAR OLD BUFFER AND NULL IT
    	if(m_pVBuffer2D != NULL)
    	{
    		m_pVBuffer2D->Release();
    		m_pVBuffer2D = NULL;
    	}
    
    	//RE-CREATE OLD BUFFER FOR NEW SHAPE (SIZE OF: 4 NEW VERTICES + TEMP BUFFER)
    	Attempt = m_pD3DDevice->CreateVertexBuffer(sizeof(CUSTOMVERTEX) * (4 + m_pNumV), 0,
    								D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT,
    								&m_pVBuffer2D);
    	if(FAILED(Attempt))
    		return E_FAIL;
    
    	//COPY THE OLD DATA BACK INTO THE NEW AND IMPROVED BUFFER
    	*m_pVBuffer2D = *VBufferStorage;
    
    	//LOCK THE LAST 4 POSITIONS OF THE NEW AND IMPROVED BUFFER
    	Attempt = m_pVBuffer2D->Lock(0, 0, (BYTE**)&VBufferVertices, 0);
    	if(FAILED(Attempt))
    		return E_FAIL;
    
    	VBufferVertices[m_pNumV + 0].vPosition = Coords + (D3DXVECTOR3(-fWidth / 2, +fHeight / 2, 0.0f));
    	VBufferVertices[m_pNumV + 1].vPosition = Coords + (D3DXVECTOR3(+fWidth / 2, +fHeight / 2, 0.0f));
    	VBufferVertices[m_pNumV + 2].vPosition = Coords + (D3DXVECTOR3(-fWidth / 2, -fHeight / 2, 0.0f));
    	VBufferVertices[m_pNumV + 3].vPosition = Coords + (D3DXVECTOR3(+fWidth / 2, -fHeight / 2, 0.0f));
    
    	VBufferVertices[m_pNumV + 0].Colour = D3DCOLOR_XRGB(255, 0, 0);
    	VBufferVertices[m_pNumV + 1].Colour = D3DCOLOR_XRGB(0, 255, 0);
    	VBufferVertices[m_pNumV + 2].Colour = D3DCOLOR_XRGB(0, 0, 255);
    	VBufferVertices[m_pNumV + 3].Colour = D3DCOLOR_XRGB(0, 255, 255);
    
    	m_pVBuffer2D->Unlock();
    
    	m_pNumV += 4;
    
    	//CLEAN OUT UNNECCESSARY VARIABLES, JUST FOR KICKS
    	VBufferVertices = NULL;
    
    	VBufferStorage->Release();
    	VBufferStorage = NULL;
    
    	//SUCCESSFULLY TACKED 4 MORE VERTICES TO THE END OF OUR BUFFER, REPORT SUCCESS
    	return S_OK;
    }
    
    //NOT AS IMPORTANT, JUST SHOWING WHAT I'M RENDERING WITH
    void cObject2D::RenderAll()
    {
    	m_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
    	m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
    	m_pD3DDevice->SetRenderState(D3DRS_LIGHTING, false);
    
    	m_pD3DDevice->SetTransform(D3DTS_PROJECTION, &m_pMatProj);
    	m_pD3DDevice->SetTransform(D3DTS_WORLD, &m_pMatView);
    	m_pD3DDevice->SetTransform(D3DTS_VIEW, &m_pMatView);
    
    	m_pD3DDevice->SetStreamSource(0, m_pVBuffer2D, sizeof(CUSTOMVERTEX));
        m_pD3DDevice->SetVertexShader(D3DFVF_CUSTOMVERTEX);
    
    	m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 1, 2);
    }
    If you actually read it all, you'll see that I've tried to implement code that will update the Vertex Buffer on the fly with the correct number of vertices, allowing me to add a box simply through a function. Now, the first time that AddBox() gets called, it works just fine, no hitches, I can see the square. But, if I call it a second time (as shown in the code), then my screen is all blank (just the black window shows). Now, there are a few things that've come up when I've tested this code...

    1) *VBufferStorage = *m_pVBuffer2D; and *m_pVBuffer2D = *VBufferStorage;
    I use those to store the original vertex buffer, then recopy the data over once the new buffer has been initialized, respectively. Assuming I only called this function once (when it actually works), I don't get why VBufferStorage doesn't point to a NULL when I NULL out m_pVBuffer2D a few lines later.

    2) Which is what led me to try those very same lines without the "*"s, and let's just say, MSVC is very against that, and I don't see it wise to try and force it on the compiler

    3) I tried to use the memcpy() function instead of straight assignment "=", and I have problems because the sizeof(VBufferStorage) and sizeof(m_pVBuffer2D) is always 4, as I'm guessing the "sizeof" a IDirect3DVertexBuffer8 type is 4? Is there a way I can figure out their size in bytes depending on how many vertices they're storing?

    I know there's a lot to read up there and look through, but any advice on any of the problems, or even suggestions and ideas on how to improve the methods I'm using is always appreciated greatly.

    Thanks,
    Erik
    Last edited by Epo; 10-09-2004 at 05:02 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. small programming job VC++ Wavs in DirectX8
    By calgonite in forum Projects and Job Recruitment
    Replies: 2
    Last Post: 02-16-2006, 11:52 AM
  2. DirectX8: Render Only Portions of Screen?
    By Epo in forum Game Programming
    Replies: 2
    Last Post: 12-24-2003, 02:30 PM
  3. Transparancy in DirectX8
    By Tommaso in forum Game Programming
    Replies: 3
    Last Post: 08-27-2003, 04:18 PM