Jump to content

  • Log In with Google      Sign In   
  • Create Account

Windows has triggered a breakpoint,error at SetFVF()


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
14 replies to this topic

#1 Veil   Members   -  Reputation: 143

Like
0Likes
Like

Posted 29 April 2012 - 03:17 PM

I get the message



Windows has triggered a breakpoint in D3D.exe.

This may be due to a corruption of the heap, which indicates a bug in D3D.exe or any of the DLLs it has loaded.

This may also be due to the user pressing F12 while D3D.exe has focus.

The output window may have more diagnostic information.


it says the error is right here at the bold line:


void Terrain::Render()
{
   m_d3dDevice->SetMaterial( &m_material );
   m_d3dDevice->SetTexture(0,NULL);
   m_d3dDevice->SetStreamSource( 0, m_vb,0, sizeof(CUSTOMVERTEX) );
[u][i][b]   m_d3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );[/b][/i][/u]
   m_d3dDevice->SetIndices( m_ib );

   m_d3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST,0,0,CHUNK_VERTICES,0,CHUNK_PRIMITIVES);
}

I've been banging my head and I can't seem to understand what the problem could be.Here are the other methods,but as far as I know they work without errors:


void Terrain::CreateMaterial(float r,float g,float b,float a)
{
ZeroMemory( &m_material, sizeof(D3DMATERIAL9) );
m_material.Diffuse.r = m_material.Ambient.r = r;
m_material.Diffuse.g = m_material.Ambient.g = g;
m_material.Diffuse.b = m_material.Ambient.b = b;
m_material.Diffuse.a = m_material.Ambient.a = a;
}

void Terrain::Update()
{
int count=0;
	int vIndex=0;
HRESULT hr=m_d3dDevice->CreateVertexBuffer( CHUNK_VERTICES*sizeof(CUSTOMVERTEX),D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX,D3DPOOL_MANAGED, &m_vb, NULL );

hr=m_d3dDevice->CreateIndexBuffer(sizeof(short)*CHUNK_PRIMITIVES*3,D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_ib, NULL);

hr=m_vb->Lock( 0, 0, (void**)&pVertices, 0 );
hr=m_ib->Lock( 0, 0, (void**)&indices, 0 );

for(int i=0;i<CHUNK_HEIGHT+1;i++)
{
for(int n=0;n<CHUNK_WIDTH+1;n++)
{
pVertices->p.x = n;
pVertices->p.y = i;
pVertices->p.z = 0;
pVertices->n.x = n;
pVertices->n.y = i;
pVertices->n.z = 0;
pVertices->tu =  0;
pVertices->tv =  0;

indices[count++]=vIndex;
indices[count++]=vIndex+n;
indices[count++]=vIndex+n+1;

indices[count++]=vIndex;
indices[count++]=vIndex+n+1;
indices[count++]=vIndex+1;

vIndex++;
}
vIndex++;
}

m_vb->Unlock();
m_ib->Unlock();

}


and as for the custom vertex:


#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ  |  D3DFVF_NORMAL  |  D3DFVF_TEX1 )
#define CHUNK_HEIGHT 64
#define CHUNK_WIDTH  64

#define CHUNK_VERTICES   4225
#define CHUNK_PRIMITIVES 8192

struct CUSTOMVERTEX
{
      D3DXVECTOR3 p;
      D3DXVECTOR3 n;
 float tu,tv;
};
at the top of my code,and I don't think any of them are faulty either

Sponsor:

#2 Adam_42   Crossbones+   -  Reputation: 2512

Like
0Likes
Like

Posted 29 April 2012 - 05:03 PM

That error message means that at some point previous to that line of code the heap has been trashed.

Firstly, you appear to be writing data to the same vertex over and over again, which shouldn't cause any harm but it looks like a bug.

What I'd suggest doing is adding assert( _CrtCheckMemory( ) ); tests backwards from the point of the crash. That should let you work out which line of code makes that assert trigger.

#3 Veil   Members   -  Reputation: 143

Like
0Likes
Like

Posted 29 April 2012 - 05:43 PM

That error message means that at some point previous to that line of code the heap has been trashed.

Firstly, you appear to be writing data to the same vertex over and over again, which shouldn't cause any harm but it looks like a bug.

What I'd suggest doing is adding assert( _CrtCheckMemory( ) ); tests backwards from the point of the crash. That should let you work out which line of code makes that assert trigger.

That error message means that at some point previous to that line of code the heap has been trashed.

Firstly, you appear to be writing data to the same vertex over and over again, which shouldn't cause any harm but it looks like a bug.

What I'd suggest doing is adding assert( _CrtCheckMemory( ) ); tests backwards from the point of the crash. That should let you work out which line of code makes that assert trigger.


yeah,it's the
m_d3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
that's giving an error,any idea why this might happen?I passed a proper FVF argument that matches my CUSTOMVERTEX struct

#4 NightCreature83   Crossbones+   -  Reputation: 2845

Like
-2Likes
Like

Posted 30 April 2012 - 01:41 AM

Your problem lies in this
#define D3DFVF_CUSTOMVERTEX(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1 )
This is not a properly defined FVF.

SetFVF takes a DWORD as it's parameter not a define.
//From the DX SDK documentation
HRESULT SetFVF(
  [in]  DWORD FVF
);
And if you would look at the examples they use in the documentation you see that they all use "const DWORD" variables to define the custom vertex format.
The better way of doing this is to use a vertexdeclaration, which will allow you to use shaders properly as well and will make the switch from DX9 to higher much easier to achieve as the fixed function pipeline is dead.

Edited by NightCreature83, 30 April 2012 - 01:43 AM.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, Mad Max

#5 Adam_42   Crossbones+   -  Reputation: 2512

Like
0Likes
Like

Posted 30 April 2012 - 03:44 AM

What happens if you put assert( _CrtCheckMemory( ) ); right before the SetFVF() call?

You'll need to #include <crtdbg.h> and #include <assert.h> to get that to compile.

Edited by Adam_42, 30 April 2012 - 03:45 AM.


#6 Veil   Members   -  Reputation: 143

Like
0Likes
Like

Posted 30 April 2012 - 03:45 AM

Your problem lies in this

#define D3DFVF_CUSTOMVERTEX(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1 )
This is not a properly defined FVF.

SetFVF takes a DWORD as it's parameter not a define.
//From the DX SDK documentation
HRESULT SetFVF(
  [in]  DWORD FVF
);
And if you would look at the examples they use in the documentation you see that they all use "const DWORD" variables to define the custom vertex format.
The better way of doing this is to use a vertexdeclaration, which will allow you to use shaders properly as well and will make the switch from DX9 to higher much easier to achieve as the fixed function pipeline is dead.


I changed it to const DWORD D3DFVF_CUSTOMVERTEX = (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1);
but it still gives the same error.I actualy used #define before,because that's how I saw it in msdn.( http://msdn.microsof...9(v=vs.85).aspx )My CUSTOMVERTEX pretty much matches the FVF,doesn't it?


struct CUSTOMVERTEX
{
	  D3DXVECTOR3 p; //D3DFVF_XYZ
	  D3DXVECTOR3 n; //D3DFVF_NORMAL
	  float tu,tv;			  //D3DFVF_TEX1
};

What happens if you put assert(

_CrtCheckMemory( )



); right before the SetFVF() call?


I attached an image of the result.

The second square of code(where the error occurs in the green code) is in mlock.c
error.png
I also used windows symbols to get a more detailed stack heap,but I can't really figure out why setting a new vertex declaration corrupts the heap.
Call Stack.png

Edited by Bogomil, 30 April 2012 - 06:48 AM.


#7 NightCreature83   Crossbones+   -  Reputation: 2845

Like
0Likes
Like

Posted 30 April 2012 - 07:07 AM

You need to use another macro in your FVF as well that tells the DX9 runtime how many tex coords to expect. You have to use this macro(texcoordSizeN) as well I think

#define Description D3DFVF_TEX0 - D3DFVF_TEX8 Number of texture coordinate sets for this vertex. The actual values for these flags are not sequential. D3DFVF_TEXCOORDSIZEN(coordIndex) Define a texture coordinate data set. n indicates the dimension of the texture coordinates. coordIndex indicates texture coordinate index number. See D3DFVF_TEXCOORDSIZEN and Texture coordinates and Texture Stages.

It's been a really long time since I have done anyting with the FF.

Basically the D3DFVF_TEXn flags only define how many texture cooridnate sets the runtime expects, the TexcoordSizeN flag tells the runtime the size of these texture coordinate streams. And it might be that you need to tell the runtime about this as well.

With VertexDeclarations, which you can mix with FF, this is a bit more explicit and clearer to the reader that you specify the size of the things as well. See this for a translation between FVF->VertexDecalaration and this for an explanation of how the shader engine sees the FVF codes.

And seeing that callstack your runtime is converting to the shader pipeline in D3D9 anyways and probably because the TexCoordSizeN flag isn't present it is failing to create the correct VertexDeclaration. If you run the D3D9 runtime on a DX10 or greater card the runtime will convert all Fixed Function calls to shader calls on the fly, and thats exactly what that callstack is telling you with the line "CFVFToDecl::GetDeclaration" and "CVertexDeclaration::Create" this must be reading from some address it isn't allowed to and hence the crash.

Edited by NightCreature83, 30 April 2012 - 07:20 AM.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, Mad Max

#8 froop   Members   -  Reputation: 636

Like
0Likes
Like

Posted 30 April 2012 - 07:16 AM

Have you tried enabling the D3D Debug Runtime? It usually gives a lot of clues when something fails with D3D.

You need to use another macro in your FVF as well that tells the DX9 runtime how many tex coords to expect.


The default number of texcoords in FVF is 2 so this is not the problem here. But I agree that vertex declarations are the way to go.

#9 Veil   Members   -  Reputation: 143

Like
0Likes
Like

Posted 30 April 2012 - 07:30 AM

Have you tried enabling the D3D Debug Runtime? It usually gives a lot of clues when something fails with D3D.

You need to use another macro in your FVF as well that tells the DX9 runtime how many tex coords to expect.


The default number of texcoords in FVF is 2 so this is not the problem here. But I agree that vertex declarations are the way to go.

Have you tried enabling the D3D Debug Runtime? It usually gives a lot of clues when something fails with D3D.

You need to use another macro in your FVF as well that tells the DX9 runtime how many tex coords to expect.


The default number of texcoords in FVF is 2 so this is not the problem here. But I agree that vertex declarations are the way to go.


Yeah I still haven't implemented shaders in my engine,just working on models and terrain right now,so for now I'm using just SetFVF(),could the problem be in some DLL?I checked everything in the source,the D3DDevice is initialized,the FVF is properly declared and the vertex/index buffers create and lock/unlock without a problem.

#10 NightCreature83   Crossbones+   -  Reputation: 2845

Like
0Likes
Like

Posted 30 April 2012 - 09:05 AM

Could you provide us with the output window error when this happens, even if it is just a access violation. These errors can tell you quite a bit of whats gone wrong. And as Froop suggests turn the debug runtime on.
The error is happening on a memory allocation from just looking at your callstack, the address of that location would be interesting to see as that could be pointing at 0 or some other memory location thats not allowed. So please could you give us the output window text as well, which shows the error.

Also nearly every D3D call returns a HRESULT, inspect what that result is on all calls that return one, if it is not D3D_OK use the error tool in the SDK folder to figure out wha the error means. When running with the debug runtime the information it spits out and the return codes should point you into the direction of the problem.

Edited by NightCreature83, 30 April 2012 - 09:08 AM.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, Mad Max

#11 kauna   Crossbones+   -  Reputation: 2570

Like
0Likes
Like

Posted 30 April 2012 - 09:36 AM

Hi,

how about the size of the index buffer? The size is defined as 2 * 8192 * 3 which gives 49152 bytes. However, you write 65*65*6*2 = 50700 amount of bytes.

Best regards!

Edited by kauna, 30 April 2012 - 09:37 AM.


#12 Veil   Members   -  Reputation: 143

Like
0Likes
Like

Posted 30 April 2012 - 10:07 AM

It turned out the error is something even deeper,I commented out the entire Terrain class and everywhere it's referenced and now it won't even render the FPS counter text,which worked perfectly a while ago.It even shows the window background color as if the D3D device isn't initialized,even tho it initializes without an error.I guess I'll have to start from scratch,since it's 3000 lines of spaghetti code now and I don't know how to find the problem.

#13 NightCreature83   Crossbones+   -  Reputation: 2845

Like
0Likes
Like

Posted 30 April 2012 - 01:15 PM

When this happens it is really time to start checking every HRESULT coming from API and DX calls and when one returns different from D3D_OK or S_OK, assert and check the values you are passing to your API calls. Most API calls when they fail will give you a reason why they fail.
Also spagetti code is recoverable just requires more work, easiest is to start splitting of classes to their own files and take it from there.
Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, Mad Max

#14 Veil   Members   -  Reputation: 143

Like
0Likes
Like

Posted 01 May 2012 - 08:16 AM

When this happens it is really time to start checking every HRESULT coming from API and DX calls and when one returns different from D3D_OK or S_OK, assert and check the values you are passing to your API calls. Most API calls when they fail will give you a reason why they fail.
Also spagetti code is recoverable just requires more work, easiest is to start splitting of classes to their own files and take it from there.

When this happens it is really time to start checking every HRESULT coming from API and DX calls and when one returns different from D3D_OK or S_OK, assert and check the values you are passing to your API calls. Most API calls when they fail will give you a reason why they fail.
Also spagetti code is recoverable just requires more work, easiest is to start splitting of classes to their own files and take it from there.


Yeah I re-ordered everything and I think I fixed the problem,cause now D3D starts and it shows the text and reads directinput properly.I jus thave one final question that might sound a little noobish - how do you make a vertex declaration for the programmable function pipeline?The method I'm using now(CUSTOMVERTEX struct,DWORD FVF_CUSTOMVERTEX(blabla|blabla|etc),set FVF) I understand is the old method that doesn't support special effects.

#15 mhagain   Crossbones+   -  Reputation: 8005

Like
0Likes
Like

Posted 01 May 2012 - 08:55 AM

how do you make a vertex declaration for the programmable function pipeline?The method I'm using now(CUSTOMVERTEX struct,DWORD FVF_CUSTOMVERTEX(blabla|blabla|etc),set FVF) I understand is the old method that doesn't support special effects.


Look at the D3DXDeclaratorFromFVF function as a place to start - you can use it to get an array of D3DVERTEXELEMENT9 structs that can then be passed into a CreateVertexDeclaration call, so much of what you currently know is reusable. That should get you up and running quite fast with declarations, and make it easier to move on to custom declarations when the time comes.

It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS