Sign in to follow this  
tenpoundbear

Debug help needed (DrawPrimitive failing)

Recommended Posts

tenpoundbear    167
Hey guys, Wondering if you guys can assist in telling me why two lines of my code is failing. MAIN APPLICATION
#include "Direct3DUtility.h"
#include "Skydome.h"

IDirect3DDevice9 *D3DDevice = NULL;
Direct3DUtility *direct3DUtility = NULL;

IDirect3DVertexBuffer9 *VBSkydome = NULL;
Skydome *skydome = NULL;

//--- Function Prototypes ---//
void cleanUp();
void getInput();
void initStars();
void renderGame();
void setupGame();
void updateGame();

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
	// Code omitted...
	skydome = new Skydome();
	skydome->GenerateDome( 5.0f, 10.0f, 10.0f, true );
	
	baseWindow->show();
	
	MSG msg;
	ZeroMemory( &msg, sizeof( MSG ));

	while( msg.message != WM_QUIT )
	{
		if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
		{
			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}
		else
		{
			updateGame();
			renderGame();
			Yield();
		}
	}

	UnregisterClass( baseWindow->getClassName(), hInstance );
	cleanUp();
	return 0;
}

void getInput()
{
	// Code omitted...
}

void setupGame()
{
	// Code omitted...
}

void renderGame()
{
	D3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 0, 50, 0 ), 1.0f, 0 );
	D3DDevice->BeginScene();

	//Skydome
	direct3DUtility->setMaterialColor( direct3DUtility->getColorWhite(), 0.8f, 0.8f, 0.0f );
	D3DDevice->SetMaterial( &( direct3DUtility->getMaterial() ));
	D3DDevice->SetFVF( VERTEX_FVF_Sky ); // <--- FAILLING HERE
	D3DDevice->SetStreamSource( 0, VBSkydome, 0, sizeof( skydome->getSkydomeVertices() ));
	D3DDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 100 ); // <-- AND HERE

	// Code omitted...

	D3DDevice->EndScene();
	D3DDevice->Present( NULL, NULL, NULL, NULL );
}

void updateGame()
{
	// Code omitted...
}

void initStars()
{
	void* verticesSkydome;
	D3DDevice->CreateVertexBuffer( sizeof( SkydomeVertices ) * 576, 0, VERTEX_FVF_Sky, D3DPOOL_MANAGED, &VBSkydome, NULL );
	VBSkydome->Lock( 0, 0, ( void** ) &verticesSkydome, 0 );
	memcpy( verticesSkydome, skydome->getSkydomeVertices(), sizeof( skydome->getSkydomeVertices() ));
	VBSkydome->Unlock();
}

void cleanUp()
{
	// Code omitted...
}







SKYDOME HEADER FILE (LOOK AT THE LATER POST FOR THE UPDATED CODE FOR THIS)
// THIS CODE IS BEEN SLIGHTLY UPDATE. LOOK AT THE BOTTOM ONE FOR THE LATEST VERSION.
// Base code taken from Sphere Games (http://www.spheregames.com) tutorial.
#ifndef SKYDOME_H
#define SKYDOME_H

#include "SkydomeStruct.h"
#define DTOR (PI / 180.0f)
#define PI 3.1415926535897f
#define DEGTORAD(Deg) ((Deg * PI) / 180.0)
#define RADTODEG(Rad) ((180.0 * Rad) / PI)

class Skydome
{
public:
	~Skydome();
	Skydome();
	void GenerateDome( float radius, float num_slices, float num_segments, bool sphere );
	SkydomeVertices* getSkydomeVertices();

private:
	SkydomeVertices *Vertices;
	int NumVertices;
};
#endif






SKYDOME IMPLEMENTATION FILE (LOOK AT THE LATER POST FOR THE UPDATED CODE FOR THIS)
// THIS CODE IS BEEN SLIGHTLY UPDATE. LOOK AT THE BOTTOM ONE FOR THE LATEST VERSION.
#include "Skydome.h"

Skydome::~Skydome()
{
	delete [] Vertices;
}

Skydome::Skydome()
{
	Vertices = NULL;
	NumVertices = 0;
}

void Skydome::GenerateDome( float radius, float num_slices, float num_segments, bool sphere )
{
	int theta, phi;

	// Initialize our Vertex array
	NumVertices = (int)((360/dtheta)*(90/dphi)*4);
	Vertices = new SkydomeVertices[ NumVertices ];
	ZeroMemory( Vertices, sizeof( SkydomeVertices ) * NumVertices );

	// Generate the dome
	int n = 0;
	for( phi=0; phi <= 90 - dphi; phi += (int)dphi )
	{
		for( theta=0; theta <= 360 - dtheta; theta += (int)dtheta )
		{
			// Calculate the vertex at phi, theta
			Vertices[ n ].pos.x = radius * sinf(phi*DTOR) * cosf(DTOR*theta);
			Vertices[ n ].pos.y = radius * sinf(phi*DTOR) * sinf(DTOR*theta);
			Vertices[ n ].pos.z = radius * cosf(phi*DTOR);
			n++; <--- THE PLUS PLUS SIGN IS NOT SHOWING HERE ><

			// Calculate the vertex at phi+dphi, theta
			Vertices[ n ].pos.x = radius * sinf((phi+dphi)*DTOR) * cosf(theta*DTOR);
			Vertices[ n ].pos.y = radius * sinf((phi+dphi)*DTOR) * sinf(theta*DTOR);
			Vertices[ n ].pos.z = radius * cosf((phi+dphi)*DTOR);
			n++;

			// Calculate the vertex at phi, theta+dtheta
			Vertices[ n ].pos.x = radius * sinf(DTOR*phi) * cosf(DTOR*(theta+dtheta));
			Vertices[ n ].pos.y = radius * sinf(DTOR*phi) * sinf(DTOR*(theta+dtheta));
			Vertices[ n ].pos.z = radius * cosf(DTOR*phi);
			n++;

			if (phi > -90 && phi < 90)
			{
				// Calculate the vertex at phi+dphi, theta+dtheta
				Vertices[ n ].pos.x = radius * sinf((phi+dphi)*DTOR) * cosf(DTOR*(theta+dtheta));
				Vertices[ n ].pos.y = radius * sinf((phi+dphi)*DTOR) * sinf(DTOR*(theta+dtheta));
				Vertices[ n ].pos.z = radius * cosf((phi+dphi)*DTOR);
				n++;
			}
		}
	}
}

SkydomeVertices* Skydome::getSkydomeVertices()
{
	return Vertices;
}






SKYDOME STRUCTURE FILE
#include <d3d9.h>
#include <d3dx9.h>

typedef struct SkydomeVertex
{
	D3DXVECTOR3 pos;    // vertex position
	D3DXVECTOR3 norm;   // vertex normal
	float tu, tv;		// texture coordinates
} SkydomeVertices;

#define VERTEX_FVF_Sky (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1)






The part where my code is falling is these 2 lines.
	D3DDevice->SetFVF( VERTEX_FVF_Sky );
	D3DDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 100 );

Direct3D9: (ERROR) :Stream 0 is not set and FVF vertex declaration is used

First-chance exception at 0x75b19617 in Win32WrapperApp.exe: Microsoft C++ exception: long at memory location 0x0037f814..
Direct3D9: (ERROR) :DrawPrimitive failed.
My window shows and the background is drawn... but not my dome. But that is expected since my drawPrimitive function fails. Many thanks guys for any help you can offer. [Edited by - tenpoundbear on April 28, 2010 12:33:05 PM]

Share this post


Link to post
Share on other sites
GregMichael    135
First of all you should *always* check that D3D isn't failing elsewhere. For example you do not check to see if you successfully create the vertex buffer, or whether or not you were able to lock it.

From the code posted it doesn't show where you are setting up the vertex buffer from the created skydome vertices...where does initStars() get called from ?

Have you also tried turning up the debug output and using the debug runtime D3D - selected via D3D control panel ?

Share this post


Link to post
Share on other sites
tenpoundbear    167
Quote:
Original post by GregMichael
First of all you should *always* check that D3D isn't failing elsewhere. For example you do not check to see if you successfully create the vertex buffer, or whether or not you were able to lock it.


I usually do, but I wanted to get the code up and running (if possible) this time first, then I was going to go back and put in the fail checks.

But I've check for FAILED in my if statements now, none are failing.

void initStars()
{
void* verticesSkydome;
if( FAILED( D3DDevice->CreateVertexBuffer( sizeof( SkydomeVertices ) * 576, 0, VERTEX_FVF_Sky, D3DPOOL_MANAGED, &VBSkydome, NULL ) ))
{
MessageBox( 0, "FAILED", 0, 0 );
}
if( FAILED( VBSkydome->Lock( 0, 0, ( void** ) &verticesSkydome, 0 )))
{
MessageBox( 0, "FAILED", 0, 0 );
}
memcpy( verticesSkydome, skydome->getSkydomeVertices(), sizeof( skydome->getSkydomeVertices() ));
if( FAILED( VBSkydome->Unlock() ))
{
MessageBox( 0, "FAILED", 0, 0 );
}
}



Quote:
Original post by GregMichael
From the code posted it doesn't show where you are setting up the vertex buffer from the created skydome vertices...where does initStars() get called from ?


Yeh this was my mistake... after checking the code I found I hadn't called initStars() anywhere.

I've called it in my main application, right after "skydome->GenerateDome( 10.0f, 15.0f, 15.0f, 15.0f, 15.0f );" now though.

....
skydome->GenerateDome( 10.0f, 15.0f, 15.0f, 15.0f, 15.0f );
initStars();
...


Quote:
Original post by GregMichael
Have you also tried turning up the debug output and using the debug runtime D3D - selected via D3D control panel ?

Yep, sure have.


After making sure I've called initStars(), the original error is gone now. But I have new errors

...
Direct3D9: (ERROR) :Memory Address: 01861c84 lAllocID=522 dwSize=00000080, ReturnAddr=6b4399aa (pid=000014c4)
Direct3D9: (ERROR) :Memory Address: 01861d3c lAllocID=523 dwSize=0000007c, ReturnAddr=6b455d24 (pid=000014c4)


Does that mean I am not copying the data over to the vertex buffer correctly?
That is the only reason I can think of at the moment.

Am I using this memcpy function correctly?

memcpy( verticesSkydome, skydome->getSkydomeVertices(), sizeof( skydome->getSkydomeVertices() ));

First parameter is the destination, takes a pointer. That looks correct to me.
Second parameter is source, takes a pointer. The getSkydomeVertices() function returns a pointer... so that looks ok also.

Still, I think I am referencing something wrong here... memcpy and pointers in general is not my strong point.

Any suggestions?

Share this post


Link to post
Share on other sites
Tom KQT    1704
Quote:
Original post by tenpoundbear
Am I using this memcpy function correctly?

memcpy( verticesSkydome, skydome->getSkydomeVertices(), sizeof( skydome->getSkydomeVertices() ));


Nope, that's not correct.
If getSkydomeVertices() returns a pointer (which is needed if you want to use it as the second parameter) then you've got an error in the last parameter which is the size of the data you want to copy.
sizeof(somethingWhatReturnsPointer) returns the size of the pointer, not of the data the pointer points to.
You'll propably want rather pass there something like
sizeof(skydomeVertexStructure) * skydomeVertexCount

[Edited by - Tom KQT on April 26, 2010 5:29:48 AM]

Share this post


Link to post
Share on other sites
tenpoundbear    167
I should know that by now... so stupid on my behalf.

Thanks Tom KQT for the tip :)

I have managed to get to the rendering stage now... but it looks no where near a sphere/dome. In fact it looks like the triangles are drawn on top of each other or very near to each other ><.

This is what it looks like...


and another from a different angle...


The code for the Skydome class has slightly changed from the original, not much though.

UPDATED SKYDOME.H

#ifndef SKYDOME_H
#define SKYDOME_H

#include "SkydomeStruct.h"

class Skydome
{
public:
~Skydome();
Skydome();
void GenerateDome( float radius, float num_slices, float num_segments, bool sphere );
SkydomeVertices* getSkydomeVertices();
int getNumVertices();

private:
SkydomeVertices *Vertices;
int NumVertices;
};
#endif



UPDATED SKYDOME.CPP

// Tutorial for this code found here http://spheregames.com
#include "Skydome.h"
#include <math.h>

#define PI 3.1415926535897f

double DegToRad( double degrees ) { return (PI * degrees)/180.0f; }

double RadToDeg( double radians ) { return 180.0f/(PI * radians); }

Skydome::~Skydome() { delete [] Vertices; }

Skydome::Skydome() {
{
Vertices = NULL;
NumVertices = 0;
}

void Skydome::GenerateDome( float radius, float num_slices, float num_segments, bool sphere )
{
// Initialize our Vertex array
NumVertices = (int) ((num_slices) * (num_segments )) * 4;
Vertices = new SkydomeVertices[ NumVertices ];
ZeroMemory( Vertices, sizeof( SkydomeVertices ) * NumVertices );

// Used to calculate the UV coordinates
float vx, vy, vz, mag;

float slice_size = sphere ? ( 180.0f / num_slices ) : ( 90.0f / num_slices );
float segment_size = ( 360.0f / num_segments );

// Generate the dome
int n = 0;
for( int i = 1; i <= num_slices; ++i )
{
float phi = DegToRad(( i-1 ) * slice_size );
float delta_phi = DegToRad( i * slice_size ) - phi;
float phi_dphi_rad = ( phi + delta_phi );

for( int j = 1; j <= num_segments; ++j )
{
float theta = DegToRad(( j-1 ) * ( 360.f / num_segments ));
float delta_theta = DegToRad( j * segment_size ) - theta;
float theta_dtheta_rad = theta + delta_theta;

// Calculate the vertex at phi, theta
Vertices[ n ].pos.x = radius * sinf( phi ) * cosf( theta );
Vertices[ n ].pos.y = radius * sinf( phi ) * sinf( theta );
Vertices[ n ].pos.z = radius * cosf( phi );

vx = Vertices[ n ].pos.x;
vy = Vertices[ n ].pos.y;
vz = Vertices[ n ].pos.z;

mag = (float)sqrt((vx*vx)+(vy*vy)+(vz*vz));
vx /= mag;
vy /= mag;
vz /= mag;

Vertices[ n ].tu = (float)(atan2(vx, vz)/(PI*2)) + 0.5f;
Vertices[ n ].tv = (float)(asin(vy) / PI) + 0.5f;
n++;

// Calculate the vertex at phi+dphi, theta
Vertices[ n ].pos.x = radius * sinf( phi_dphi_rad ) * cosf( theta );
Vertices[ n ].pos.y = radius * sinf( phi_dphi_rad ) * sinf( theta );
Vertices[ n ].pos.z = radius * cosf( phi_dphi_rad );

vx = Vertices[ n ].pos.x;
vy = Vertices[ n ].pos.y;
vz = Vertices[ n ].pos.z;

mag = (float)sqrt((vx*vx)+(vy*vy)+(vz*vz));
vx /= mag;
vy /= mag;
vz /= mag;

Vertices[ n ].tu = (float)(atan2(vx, vz)/(PI*2)) + 0.5f;
Vertices[ n ].tv = (float)(asin(vy) / PI) + 0.5f;
n++;

// Calculate the vertex at phi, theta+dtheta
Vertices[ n ].pos.x = radius * sinf( phi ) * cosf( theta_dtheta_rad );
Vertices[ n ].pos.y = radius * sinf( phi ) * sinf( theta_dtheta_rad );
Vertices[ n ].pos.z = radius * cosf( phi );

vx = Vertices[ n ].pos.x;
vy = Vertices[ n ].pos.y;
vz = Vertices[ n ].pos.z;

mag = (float)sqrt((vx*vx)+(vy*vy)+(vz*vz));
vx /= mag;
vy /= mag;
vz /= mag;

Vertices[ n ].tu = (float)(atan2(vx, vz)/(PI*2)) + 0.5f;
Vertices[ n ].tv = (float)(asin(vy) / PI) + 0.5f;
n++;

if (phi > -90 && phi < 90)
{
// Calculate the vertex at phi+dphi, theta+dtheta
Vertices[ n ].pos.x = radius * sinf( phi_dphi_rad ) * cosf( theta_dtheta_rad );
Vertices[ n ].pos.y = radius * sinf( phi_dphi_rad ) * sinf( theta_dtheta_rad );
Vertices[ n ].pos.z = radius * cosf( phi_dphi_rad );

vx = Vertices[ n ].pos.x;
vy = Vertices[ n ].pos.y;
vz = Vertices[ n ].pos.z;

mag = (float)sqrt((vx*vx)+(vy*vy)+(vz*vz));
vx /= mag;
vy /= mag;
vz /= mag;

Vertices[ n ].tu = (float)(atan2(vx, vz)/(PI*2)) + 0.5f;
Vertices[ n ].tv = (float)(asin(vy) / PI) + 0.5f;
n++;
}
}
}
}

SkydomeVertices* Skydome::getSkydomeVertices()
{
return Vertices;
}

int Skydome::getNumVertices()
{
return NumVertices;
}





I do understand 70% 75% of the maths behind the code (I hope)... but it has taken me 3-4 days from completely being clueless to at least understanding some of it.

I don't know... because the math itself is pretty mind boggling, I am not sure where it is that I am going wrong to be honest :(

Can you guys help?

[Edited by - tenpoundbear on April 28, 2010 12:56:14 PM]

Share this post


Link to post
Share on other sites
tenpoundbear    167
Hey guys,

I have been examining the position values in my structure and I am sure what I see is incorrect.

Please, pleaseeee help me here guys, I feel I am on the verge of pinpointing the problem here but I just can't reach it yet.

Below is a picture of the values of x, y, z values.


If you look carefully at line 'n: 0', 'n: 2', 'n: 4' and so on you can see that they all have the same value.

Now I am pretty certain this is wrong... they should contain different x, y, z values since the vertices are moving along longitude (horizontally across) of the sphere.

But I just don't understand why they are the same. There has to be an incorrect formula or incorrect delta or phi value somewhere?

Sorry to keep asking but I have a very good feeling that I am on the right track here.

Any help is appreciated guys.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this