DirectX problem - my C++ program freezes!
#1 Members - Reputation: 133
Posted 21 October 2012 - 07:45 AM
I'm learning DirectX 9 programming, but I've got this problem: I'm simply trying to render 3 lines to represent the 3 axis in the 3D space, but the program I wrote freezes.
I have to open up the Task Manager and close Visual Studio (which during the debug says "Run-Time Check Failure #2 - Stack around the variable 'pVoid' was corrupted")
This is the source code:
Entry point:
http://pastebin.com/BbVdeeNR
AxisRender.cpp:
http://pastebin.com/CNBubgJM
AxisRender.h:
http://pastebin.com/au7j41gw
Thank you in advance for your help!
#2 Members - Reputation: 264
Posted 21 October 2012 - 12:22 PM
CHECK_COM(m_pD3DDevice->CreateVertexBuffer(4 * sizeof(SVertexData), D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &m_pD3DPlaneVertexBuffer, NULL)); CHECK_COM(m_pD3DPlaneVertexBuffer->Lock(0, 0, reinterpret_cast<void **>(&pPlaneVertexBuffer), 0)); pPlaneVertexBuffer[0] = SVertexData(-1.0f, -1.0f, 1.0f, 0.0f, 1.0f); pPlaneVertexBuffer[1] = SVertexData(-1.0f, 1.0f, 1.0f, 0.0f, 0.0); pPlaneVertexBuffer[2] = SVertexData(1.0f, 1.0f, 1.0f, 1.0f, 0.0f); pPlaneVertexBuffer[3] = SVertexData(1.0f, -1.0f, 1.0f, 1.0f, 1.0f); CHECK_COM(m_pD3DPlaneVertexBuffer->Unlock());
and @line 41: memcpy(&pVoid, Vertices, 6 * sizeof(AxisRenderFV)); you could do this instead: memcpy(&pVoid, Vertices, sizeof(Vertices));
#4 Members - Reputation: 428
Posted 21 October 2012 - 03:00 PM
'memcpy(&pVoid..' has a (big) problem: pVoid is a pointer, and you wanto to copy data to where it points, not where the pVoid variable is stored. Use pVoid instead of &pVoid. With your current code, you overwrite pVoids value, so it points somewhere else, and trash some remaining memory after pVoid, so you end up with that mean message.
#6 Members - Reputation: 133
Posted 21 October 2012 - 03:27 PM
In english, it is something likeEccezione first-chance a 0x75e3c41f in DX9-Cube.exe: Eccezione di Microsoft C++: long nella posizione di memoria 0x003bf4fc..
(the memory addresses change every time)First-chance exception at 0x75e3c41f in DX9-Cube.exe: Microsoft C++ Exception: long in memory position 0x003bf3fc
I've tried to set some breakpoints, and it seems that the problem happens when axis.Render() is executed, but it can't figure out what's going on wrong
#9 Crossbones+ - Reputation: 5181
Posted 24 October 2012 - 06:28 PM
It will report more information on this and other errors.
L. Spiro
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums
#10 Members - Reputation: 1575
Posted 24 October 2012 - 10:49 PM
Hey, if you're writing a member function you can refer to members directly. The only time you need to say "this->m_Var" is when you have a function-local variable or argument named "m_Var" and you want to refer to the member variable instead of the local one.
You need to check return values of DriectX functions religiously. Probably your vbuffer isn't getting set up correctly.
As was mentioned earlier, since you're talking about an array there (not a pointer) you can just say "sizeof(Vertices)." That also protects you in case you make a change to the size of the array for some reason: You won't have to change the size calculations. (Also in the memcpy() later.)
You need to check the return value not just of lock, but of anything that can return an error. I know it makes the code look big and clunky, and you have to type a bit more than usual, but it will save you a LOT of problems in the long run:
1) It means that you're more aware of possible problem states before you're even done writing the code.
2) If a runtime error happens you get to know what's going on immediately instead of having to debug for an hour.
3) Chicks dig it. Really. You wouldn't believe how many women will flock to you just for checking all your return values.
4) A lot of libraries (like DirectX) use error codes to alert you to a temporary or correctable problem - you can recover from the error easily without the program crashing (or it might not even really be an error).
Something else to look at:
AxisRender::AxisRender(float p_lenght, DWORD color)
{
this->lenght = p_lenght;
}should be:AxisRender::AxisRender(float p_lenght, DWORD color) :
VertexBuffer(NULL),
d3ddev(NULL),
lenght(p_lenght),
color(color)
{
//NOP
}Initializer lists run faster than initializations in the constructor function body. When you write a constructor you should copy and paste all your member variables into the initializer list and then set a default value for all of them there in the same order. Even include the ones that don't matter, like initializing your pointers to NULL - if you don't then the compiler will do it anyway behind the scenes. Doing this also means that won't have forgotten to initialize the member variable 'color'.
I haven't messed with DirectX for a month or two but I think in render_frame() you want to set up the camera prior to calling the axis render. In this case it should correct on the second frame, since the camera setup from the previous frame will be inherited, but generally you want to set up all your matrices and then do your render call, since rendering uses the existing matrix to draw pixels with.
Keep at it, boss. Good luck!
Edited by Khatharr, 24 October 2012 - 11:22 PM.
There are ten kinds of people in this world: those who understand binary and those who don't.
#11 Members - Reputation: 1138
Posted 25 October 2012 - 05:53 AM
Even include the ones that don't matter, like initializing your pointers to NULL - if you don't then the compiler will do it anyway behind the scenes.
I think that the reality is worse, the compiler won't initialize your values to anything (and they will contain garbage) unless you are running debug build. In which case the pointers won't contain NULL either but something more debug friendly such as 0xcccccccc or 0xbaadf00d etc.
Otherwise, the points in this message chain is that OP should
- check the return values of the functions (look for MSDN which functions have return values).
- look for bad pointers. (For example, that map doesn't return NULL pointer).
- run the program step by step with a debugger
- use Direct3D debug libraries
Cheers!
#12 Members - Reputation: 133
Posted 25 October 2012 - 01:18 PM
You have no idea about how much your advises are precious to me
Ok, so now I'm using Debug runtime, and I get this output by the debugger:
But, why? Why should there be an error about a vertex shader if I do not have one?Eccezione first-chance a 0x7538c41f in DX9-Cube.exe: Eccezione di Microsoft C++: long nella posizione di memoria 0x0036f510..
Direct3D9: (ERROR) :DrawPrimitive failed.
Direct3D9: (ERROR) :Vertex shader declaration is not set
Also, I can't really understand this:
AxisRender::AxisRender(float p_lenght, DWORD color) : VertexBuffer(NULL), d3ddev(NULL), length(p_length), color(color){ //NOP}
Well, I understand it, but I'm curious to understand the low-level difference from this to assigning variables normally as I was doing I know, but I always to this, always in Java because I like to remove any small possibility of ambiguityHey, if you're writing a member function you can refer to members directly. The only time you need to say "this->m_Var" is when you have a function-local variable or argument named "m_Var" and you want to refer to the member variable instead of the local one.
But if you tell me that removing this-> would make the code faster, I will definitely do it!
Yeah, I actually did this some minutes after posting the threadAs was mentioned earlier, since you're talking about an array there (not a pointer) you can just say "sizeof(Vertices)." That also protects you in case you make a change to the size of the array for some reason: You won't have to change the size calculations. (Also in the memcpy() later.)
Edited by thedd, 25 October 2012 - 02:00 PM.
#14 Members - Reputation: 1138
Posted 25 October 2012 - 04:51 PM
http://doc.51windows.net/Directx9_SDK/?url=/directx9_sdk/graphics/programmingguide/gettingstarted/vertexdeclaration/vertexdeclaration.htm
Best regards!
#18 Members - Reputation: 1575
Posted 01 November 2012 - 05:39 PM
I know, but I always to this, always in Java because I like to remove any small possibility of ambiguity
But if you tell me that removing this-> would make the code faster, I will definitely do it!
I'm not sure that it would be faster since an object member has an offset based lookup in either case. I'd have to check the disassembly to see if there's a difference. The reason that I brought it up is that as a general rule you want to shy away from bringing customs from one language into another. If you're just coding as a hobbyist then it's not a big deal since you'll probably eventually just grow out of it (or not, but it's not bothering anyone). If you plan to code professionally then people will look down on that kind of thing because it makes the code larger and harder to read and it means that you're doing a lot of extra typing.
If you're concerned about ambiguity then it's good to remember that C++ is a very strongly typed language. The compiler will most likely tell you if you're doing something crazy. The naming convention that I've been using lately is working out well for me (Someone else on the forum suggested it and I tried it out. Thanks to them!).
Basically it's like this:
g_GlobalVariableName
a_ArgumentVariableName
m_MemberVariableName
localVariableName
Again, though, it's an issue of trying to find an efficient writing style rather than an issue of compiled code performance, so it depends on what your long term programming goals are (hobby vs career).
There are ten kinds of people in this world: those who understand binary and those who don't.






