Sign in to follow this  

[Question]LPDIRECT3DVERTEXBUFFER9::Lock is making weird things

This topic is 670 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey Guys,

void func(IDirect3DDevice9* pDevice)
{
	LPDIRECT3DVERTEXBUFFER9 v_buffer;
	vertex vertices[] =
	{
		{ 320.0f, 50.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(0, 0, 255), },
		{ 520.0f, 400.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(0, 255, 0), },
		{ 120.0f, 400.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(255, 0, 0), },
	};
 
	// create the vertex and store the pointer into v_buffer, which is created globally
	pDevice->CreateVertexBuffer(3 * sizeof(vertex),
		0,
		(D3DFVF_XYZRHW | D3DFVF_DIFFUSE),
		D3DPOOL_MANAGED,
		&v_buffer,
		NULL);
 
	VOID* pVoid;    // the void pointer
 
	v_buffer->Lock(0, 0, (void**)&pVoid, 0);    // lock the vertex buffer
	memcpy(pVoid, vertices, sizeof(vertices));    // copy the vertices to the locked buffer
	v_buffer->Unlock();    // unlock the vertex buffer
 
	// select which vertex format we are using
	pDevice->SetFVF((D3DFVF_XYZRHW | D3DFVF_DIFFUSE));
 
	// select the vertex buffer to display
	pDevice->SetStreamSource(0, v_buffer, 0, sizeof(vertex));
 
	// copy the vertex buffer to the back buffer
	pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
 
	v_buffer->Release();
}

If I call this code within my rendering function it closes the application.

Thatswhy I debugged it and came to the result that something went wrong at the lock but Im not 100% sure.

 

Actualy it should just draw a triangle for testing purpose with floating colors like this:

X2czO9U.png

 

 

But ye ... dunno whats wrong here >.<   tbh I never had problems with something like this before o.o

 

I mean its similar to the following circle function which works 100% fine  (g_pVB is the buffer)

void D3DBase::DrawCircleFilled(float x, float y, float rad, float rotate, CircleType type, int resolution, G::Color color, IDirect3DDevice9* pDevice)
{
	std::vector<vertex> circle(resolution + 2);
	float angle = (rotate*D3DX_PI) / 180;
	float pi;

	if (type == CircleType::FULL) pi = D3DX_PI;        // Full circle
	if (type == CircleType::HALF) pi = D3DX_PI / 2;      // 1/2 circle
	if (type == CircleType::THIRD) pi = D3DX_PI / 3;      // 1/3 circle
	if (type == CircleType::QUARTER) pi = D3DX_PI / 4;   // 1/4 circle

	circle[0].x = x;
	circle[0].y = y;
	circle[0].z = 0;
	circle[0].rhw = 1;
	circle[0].color = color.ToDWORD();

	for (int i = 1; i < resolution + 2; i++)
	{
		circle[i].x = (float)(x - rad*cos(pi*((i - 1) / (resolution / 2.0f))));
		circle[i].y = (float)(y - rad*sin(pi*((i - 1) / (resolution / 2.0f))));
		circle[i].z = 0;
		circle[i].rhw = 1;
		circle[i].color = color.ToDWORD();
	}
	

	//new Rotate
	int _res = resolution + 2;
	for (int i = 0; i < _res; i++)
	{
		// translate point back to origin:
		circle[i].x -= x;
		circle[i].y -= y;

		// rotate point
		float xnew = circle[i].x * cos(angle) - circle[i].y * sin(angle);
		float ynew = circle[i].x * sin(angle) + circle[i].y * cos(angle);

		// translate point back:
		circle[i].x = xnew + x;
		circle[i].y = ynew + y;
	}

	pDevice->CreateVertexBuffer((resolution + 2) * sizeof(vertex), D3DUSAGE_WRITEONLY, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, D3DPOOL_DEFAULT, &g_pVB, NULL);

	VOID* pVertices;
	g_pVB->Lock(0, (resolution + 2) * sizeof(vertex), (void**)&pVertices, 0);
	memcpy(pVertices, &circle[0], (resolution + 2) * sizeof(vertex));
	g_pVB->Unlock();

	pDevice->SetTexture(0, NULL);
	pDevice->SetPixelShader(NULL);
	pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
	pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
	pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

	pDevice->SetStreamSource(0, g_pVB, 0, sizeof(vertex));
	pDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
	pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, resolution);
	if (g_pVB != NULL) g_pVB->Release();
}

Thatswhy Im more than confused here :Q_  Why does the single triangle not work but the circle  work ??  its so weird xD

Maybe Im just blind right now :D

,greetings

Edited by GAFO666

Share this post


Link to post
Share on other sites

Your code mostly looks correct; there are the usual small issues, such as you don't actually need to specify an FVF code in your CreateVertexBuffer call unless you'e using ProcessVertices, but they're not going to cause a crash.
 
One of two things has happened here.
 
Either v_buffer is NULL; i.e your call to CreateVertexBuffer failed.  You should be checking the HRESULT from all D3D calls and responding accordingly (in this case you might display an appropriate error message and terminate the program).  Running your program under the debugger you will be able to inspect the value of v_buffer and determine if this is the case.
 
Or 3 * sizeof (vertex) is not actually equal to sizeof (vertices); i.e when you memcpy the vertices you overrun the buffer.  This is more likely to crash your program if you create your D3D device with D3DCREATE_SOFTWARE_VERTEXPROCESSING, but should be corrected in any case.

Share this post


Link to post
Share on other sites
void func(IDirect3DDevice9* pDevice)
{
	LPDIRECT3DVERTEXBUFFER9 v_buffer;
	vertex vertices[] =
	{
		{ 320.0f, 50.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(0, 0, 255), },
		{ 520.0f, 400.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(0, 255, 0), },
		{ 120.0f, 400.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(255, 0, 0), },
	};

	
	//HRESULT res = pDevice->CreateVertexBuffer(3 * sizeof(vertex),0,	(D3DFVF_XYZRHW | D3DFVF_DIFFUSE),D3DPOOL_MANAGED,&v_buffer,	NULL); //fails

	//HRESULT res = pDevice->CreateVertexBuffer(3 * sizeof(vertex), D3DUSAGE_WRITEONLY, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, D3DPOOL_DEFAULT, &v_buffer, NULL); //S_OK
	HRESULT res = pDevice->CreateVertexBuffer(sizeof(vertices), D3DUSAGE_WRITEONLY, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, D3DPOOL_DEFAULT, &v_buffer, NULL);//S_OK

	if (res == S_OK)
	{
		VOID* pVoid;
		//v_buffer->Lock(0, 3 * sizeof(vertex), (void**)&pVoid, 0);
		v_buffer->Lock(0, 0, (void**)&pVoid, 0);

		memcpy(pVoid, vertices, sizeof(vertices));
		v_buffer->Unlock();


		pDevice->SetFVF((D3DFVF_XYZRHW | D3DFVF_DIFFUSE));
		pDevice->SetStreamSource(0, v_buffer, 0, sizeof(vertex));
		pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);

		if (v_buffer != NULL)
			v_buffer->Release();

		dFonts.ArialBold->DrawTextF(10, 10, ccList.Red, "%X", res);
	}
	else
		dFonts.ArialBold->DrawTextF(10, 10, ccList.Red, "CreateVertexBuffer failed.");

 	
}

oh, it failed in hresult as you said, i tried another version of creating the buffer along with the circle function

with two ways :  3*sizeof(vertex)  and sizeof(vertices) .

 

Now it does not crash anymore, the hresult is S_OK but still nothing drawn o.o

 

 

edit:

if (sizeof(vertex)* 3 == sizeof(vertices))
		dFonts.ArialBold->DrawTextF(10, 25, ccList.Red, "vertex x3 and  vertices have the same size");

tells me that they are equal in size smile.png

 

 

edit2:

k found the problem, z had to be 0.0f and not 0.5f as described on directxtutorials.

here is the working code:

void func(IDirect3DDevice9* pDevice)
{
	LPDIRECT3DVERTEXBUFFER9 v_buffer;
	vertex vertices[] =
	{
		{ 320.0f, 50.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(0, 0, 255), },
		{ 520.0f, 400.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(0, 255, 0), },
		{ 120.0f, 400.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(255, 0, 0), },
	};
	
	
	pDevice->CreateVertexBuffer(sizeof(vertices), D3DUSAGE_WRITEONLY, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, D3DPOOL_DEFAULT, &v_buffer, NULL);//S_OK
	
	VOID* pVoid;		
	v_buffer->Lock(0, 0, (void**)&pVoid, 0);
	memcpy(pVoid, vertices, sizeof(vertices));
	v_buffer->Unlock();


	pDevice->SetFVF((D3DFVF_XYZRHW | D3DFVF_DIFFUSE));
	pDevice->SetStreamSource(0, v_buffer, 0, sizeof(vertex));
	pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);

	if (v_buffer != NULL)
		v_buffer->Release();			
}
Edited by GAFO666

Share this post


Link to post
Share on other sites


z had to be 0.0f and not 0.5f as described on directxtutorials

 

that would seem to indicate that your camera is in a different location than their's with respect to the object.

 

if you move an object and it suddenly becomes visible, odds are it was outside the viewing frustum before.

Share this post


Link to post
Share on other sites

This topic is 670 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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