Texture Mapping (Sphere) Not Showing When I Run App

Started by
9 comments, last by unbird 14 years ago
Hey guys, First let me apologize for posting this question as it is quit similar to previous posted one (I've read nearly everything and tried many different things before deciding to post). Basically I applying a texture to my sphere in my application, but when I run the application... the texture doesn't show. The material shows, I know this because I set the material to a yellow color... but there is also a texture that doesn't seem to be mapping to the sphere. I have borrowed code from here "http://www.mvps.org/directx/articles/spheremap.htm" but have modified to suit my own application better. Also another member have also posted a similar but slightly different question here "http://www.gamedev.net/community/forums/topic.asp?topic_id=390109&whichpage=1�" PLANET HEADER

#ifndef PLANET_H
#define PLANET_H

#include "Actor.h"
#include "PlanetStruct.h"

class Planet: public Actor
{
public:
	~Planet();
	Planet();
	Planet( IDirect3DDevice9 **D3DDevice, char* name, float diameter );
	Planet( char* name, float diameter, float circumference );
	void setID( char* id );
	char* getID();
	void createMesh( IDirect3DDevice9 **D3DDevice );
	ID3DXMesh* getMesh();
	ID3DXMesh* getMesh_2();

	ID3DXMesh* CreateMappedSphere( IDirect3DDevice9 **D3DDevice, float fRad, UINT slices, UINT stacks);

protected:
	ID3DXMesh* meshPlanet;
	ID3DXMesh* meshPlanet_2;
	float diameter, circumference;
	PlanetVertex* planetVertex;
};
#endif



PLANET IMPLEMENTATION FILE

#include "Planet.h"

Planet::~Planet()
{
	// Code omitted...
}

Planet::Planet()
{
	// Code omitted...
}

Planet::Planet( IDirect3DDevice9 **D3DDevice, char* name, float diameter )
{
	id = name;
	this->diameter = diameter;
	position = new Vector3();
	meshPlanet_2 = CreateMappedSphere( &( *D3DDevice ), 3, 20, 20 );
}

Planet::Planet( char* name, float diameter, float circumference )
{
	// Code omitted...
}

void Planet::setID( char* id )
{
	// Code omitted...
}

char* Planet::getID()
{
	// Code omitted...
}

void Planet::createMesh( IDirect3DDevice9 **D3DDevice )
{
	// Code omitted...
}

ID3DXMesh* Planet::CreateMappedSphere( IDirect3DDevice9 **D3DDevice, float fRad, UINT slices, UINT stacks)
{
// CREDIT GOES TO "http://www.mvps.org/directx/articles/spheremap.htm"
    // create the sphere
    ID3DXMesh* mesh;
    if( FAILED( D3DXCreateSphere( *D3DDevice, fRad, slices, stacks, &mesh, NULL )))
		return NULL;

    // create a copy of the mesh with texture coordinates,
    // since the D3DX function doesn't include them
    ID3DXMesh* texMesh;

    if( FAILED( mesh->CloneMeshFVF( D3DXMESH_SYSTEMMEM, VERTEX_FVF, *D3DDevice, &texMesh )))
	{   // failed, return un-textured mesh
        return mesh;
	}

    // finished with the original mesh, release it
    mesh->Release();
	
    // lock the vertex buffer
    //LPVERTEX pVerts;
	

	if( SUCCEEDED( texMesh->LockVertexBuffer( 0, ( void ** ) &planetVertex )))
	{
        // get vertex count
        int numVerts = texMesh->GetNumVertices();
			
        // loop through the vertices
	planetVertex = new PlanetVertex[ numVerts ];
		
        for( int i = 0; i < numVerts; i++ )
	{

            // calculate texture coordinates
		planetVertex.tu = asinf( planetVertex.norm.x ) / D3DX_PI + <span class="cpp-number">0</span>.5f;
            planetVertex.tv = asinf( planetVertex.norm.y ) / D3DX_PI + <span class="cpp-number">0</span>.5f;


        }
	
	}

        <span class="cpp-comment">// unlock the vertex buffer</span>
        texMesh-&gt;UnlockVertexBuffer();
     
    <span class="cpp-comment">// return pointer to caller</span>
    <span class="cpp-keyword">return</span> texMesh;
}

ID3DXMesh* Planet::getMesh()
{
	<span class="cpp-keyword">return</span> meshPlanet;
}

ID3DXMesh* Planet::getMesh_2()
{
	<span class="cpp-keyword">return</span> meshPlanet_2;
}


</pre></div><!–ENDSCRIPT–>

PLANETSTRUCT HEADER
<!–STARTSCRIPT–><!–source lang="cpp"–><div class="source"><pre>
<span class="cpp-keyword">struct</span> PlanetVertex
{
    D3DXVECTOR3 pos;     <span class="cpp-comment">// vertex position</span>
    D3DXVECTOR3 norm;    <span class="cpp-comment">// vertex normal</span>
    <span class="cpp-keyword">float</span> tu;            <span class="cpp-comment">// texture coordinates</span>
    <span class="cpp-keyword">float</span> tv;	
};

<span class="cpp-directive">#define</span> VERTEX_FVF (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1)

</pre></div><!–ENDSCRIPT–>

MAIN APPLICATION
<!–STARTSCRIPT–><!–source lang="cpp"–><div class="source"><pre>
<span class="cpp-comment">// Comments omitted…</span>
<span class="cpp-comment">// Code omitted…</span>

IDirect3DDevice9 *D3DDevice = NULL;
Direct3DUtility *direct3DUtility = NULL;
IDirect3DTexture9 *TxtureCube = NULL;
<span class="cpp-comment">// Code omitted…</span>

Planet **planet = <span class="cpp-keyword">new</span> Planet *[ <span class="cpp-number">8</span> ];

<span class="cpp-keyword">struct</span> CustomVertex
{
	D3DXVECTOR3 position; <span class="cpp-comment">// Vertex Position</span>
	D3DVECTOR normal; <span class="cpp-comment">// Vertex Normal</span>
	<span class="cpp-keyword">float</span> u, v; <span class="cpp-comment">// Texture Coordinate</span>
};

<span class="cpp-directive">#define</span> D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1)

<span class="cpp-keyword">void</span> RandomNumGen::seedRandom();

<span class="cpp-comment">//— Function Prototypes —//</span>
<span class="cpp-keyword">void</span> cleanUp();
<span class="cpp-keyword">void</span> getInput();
<span class="cpp-keyword">void</span> initStars();
<span class="cpp-keyword">void</span> renderGame();
<span class="cpp-keyword">void</span> setupGame();
<span class="cpp-keyword">void</span> updateGame();

<span class="cpp-keyword">int</span> WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, <span class="cpp-keyword">int</span> nShowCmd )
{
	<span class="cpp-comment">// Code omitted…</span>
		
	setupGame();

	<span class="cpp-comment">//Code omitted…</span>

	MSG msg;
	ZeroMemory( &amp;msg, <span class="cpp-keyword">sizeof</span>( MSG ));

	<span class="cpp-keyword">while</span>( msg.message != WM_QUIT )
	{
		<span class="cpp-keyword">if</span>( PeekMessage( &amp;msg, <span class="cpp-number">0</span>, <span class="cpp-number">0</span>, <span class="cpp-number">0</span>, PM_REMOVE ))
		{
			TranslateMessage( &amp;msg );
			DispatchMessage( &amp;msg );
		}
		<span class="cpp-keyword">else</span>
		{
			updateGame();
			renderGame();
			Yield();
		}
	}

	UnregisterClass( baseWindow-&gt;getClassName(), hInstance );
	<span class="cpp-keyword">return</span> <span class="cpp-number">0</span>;
}

<span class="cpp-keyword">void</span> getInput()
{
	<span class="cpp-comment">// Code omitted…</span>
}

<span class="cpp-keyword">void</span> setupGame()
{
	<span class="cpp-comment">// Code omitted…</span>
	planet[ <span class="cpp-number">0</span> ] = <span class="cpp-keyword">new</span> Planet( &amp;D3DDevice, <span class="cpp-literal">"Sun"</span>, <span class="cpp-number">20</span>.0f );
}

<span class="cpp-keyword">void</span> renderGame()
{
	D3DXMATRIX matTranslate;
	D3DDevice-&gt;Clear( <span class="cpp-number">0</span>, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( <span class="cpp-number">0</span>, <span class="cpp-number">0</span>, <span class="cpp-number">0</span> ), <span class="cpp-number">1</span>.0f, <span class="cpp-number">0</span> );
	getInput();

	D3DDevice-&gt;BeginScene();

	<span class="cpp-comment">// Sun </span>
	D3DXMatrixTranslation( &amp;matTranslate, <span class="cpp-number">0</span>, <span class="cpp-number">0</span>, <span class="cpp-number">0</span> );
	D3DDevice-&gt;SetTransform (D3DTS_WORLD, &amp;matTranslate);
	direct3DUtility-&gt;setMaterialColor( direct3DUtility-&gt;getColorYellow(), <span class="cpp-number">0</span>.1f, <span class="cpp-number">0</span>.2f, <span class="cpp-number">0</span>.3f, <span class="cpp-number">0</span>.5f );
	D3DDevice-&gt;SetMaterial( &amp;( direct3DUtility-&gt;getMaterial() ));
	D3DDevice-&gt;SetTexture( <span class="cpp-number">0</span>, TxtureCube );
	planet[ <span class="cpp-number">0</span> ]-&gt;getMesh_2()-&gt;DrawSubset( <span class="cpp-number">0</span> );
	D3DDevice-&gt;EndScene();

	D3DDevice-&gt;Present( NULL, NULL, NULL, NULL );
}

<span class="cpp-keyword">void</span> updateGame()
{
	<span class="cpp-comment">// Code omitted…	</span>
}

<span class="cpp-keyword">void</span> initStars()
{
	<span class="cpp-comment">// Code omitted…</span>

	<span class="cpp-comment">// Texture Section</span>
	D3DXCreateTextureFromFile( D3DDevice, <span class="cpp-literal">"earthmap.jpg"</span>, &amp;TxtureCube );

	D3DDevice-&gt;SetSamplerState( <span class="cpp-number">0</span>, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
	D3DDevice-&gt;SetSamplerState( <span class="cpp-number">0</span>, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
	D3DDevice-&gt;SetSamplerState( <span class="cpp-number">0</span>, D3DSAMP_MIPFILTER, D3DTEXF_POINT );
}

<span class="cpp-keyword">void</span> cleanUp()
{
	<span class="cpp-comment">// Code omitted…</span>
}


</pre></div><!–ENDSCRIPT–>

So I have left out alot of code that I think is not needed, and &#111;nly included the important sections.

If any section is unclear or further clarification is needed please don't hesitate to ask and I will explain or add more code.

So in case you have forgotten my problem, I can't seem to get the texture to show when I ran the application.

<!–EDIT–><span class=editedby><!–/EDIT–>[Edited by - tenpoundbear on April 14, 2010 9:46:08 AM]<!–EDIT–></span><!–/EDIT–>
Advertisement
Hey guys,

I am not sure about the rules of bumping your post, but I haven't had any responses yet so I apologize if it is frowned upon.

Even if you guys don't know what is wrong, if you can possible point me to some resources that I may be able to read up on that would be great too.

I've tried making the texture file different sizes also and still nothing appearing on my sphere except for my standard yellow material.
:( :( :(
It might help if you posted some of the code from your render loop--are you making sure to set the texture you loaded onto the mesh?
i.e. device->SetTexture(yourTex);
then mesh->DrawSubset();
Do the Debug Runtimes say anything?
Quote:Original post by Megapwnd
It might help if you posted some of the code from your render loop--are you making sure to set the texture you loaded onto the mesh?
i.e. device->SetTexture(yourTex);
then mesh->DrawSubset();


Yep I set my texture in the main application file, in the renderGame() function.

Hmmm... I ran the debugger and the errors I think are because of some resources I haven't properly freed yet, other than that I can't see any problems relating as to why the texture are not appearing on sphere.

FEW LINES FROM THE DEBUGGER
Direct3D9: (ERROR) :Memory Address: 00b1ff34 lAllocID=240 dwSize=00000054, ReturnAddr=5d2999aa (pid=00001404)Direct3D9: (ERROR) :Memory Address: 00bd8004 lAllocID=241 dwSize=00000080, ReturnAddr=5d2999aa (pid=00001404)Direct3D9: (ERROR) :Memory Address: 00bd80bc lAllocID=242 dwSize=0000007c, ReturnAddr=5d2b5d24 (pid=00001404)Direct3D9: (ERROR) :Total Memory Unfreed From Current Process = 3587928 bytesD3DX: MEMORY LEAKS DETECTED: 6 allocations unfreed (5056 bytes)


I have checked to make sure the texture (jpg) image is in the right folder too in case you are wondering :)

Screen shot of my Watch window too... I don't think some of these values are right... I have no idea what "-1.#IND000" means either.

Plus they all seem to have the same pos value, which I am pretty sure is wrong or at least shouldn't be.



Anyways just some more info for you guys... I may give up altogether to be honest. I am on google page 78 of my search at the moment and I am exhausted. Seems it is not a common thing, and for a programmer like myself who is still learning (recent graduate, no industry experience) is beyond my learning capacity for now :(

Let me know if you guys know why :)

[Edited by - tenpoundbear on April 15, 2010 2:14:44 PM]
everything looks right for the most part, could you provide more code showing how you load the texture file? it looks like its loading some of the indices/uv values incorrectly.
Quote:Original post by majek
everything looks right for the most part, could you provide more code showing how you load the texture file? it looks like its loading some of the indices/uv values incorrectly.


Yep the loading the texture is done in my initStars() function which is in the MAIN APPLICATION code I provided above.

But here it is so that you don't have to scroll up,
void initStars(){// Texture Section	D3DXCreateTextureFromFile( D3DDevice, "earthmap.jpg", &TxtureCube );	D3DDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );	D3DDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );	D3DDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT );}
It looks like your PlanetVertex array is full of junk, IND = "indeterminate".
Those aren't proper values and are also known as NaN's "Not-a-Number" so, if you're running in Debug, they're uninitialised data.

Attempting to render anything with them isn't going to work.

Check that you're loading your geometry correctly.

Andy

"Ars longa, vita brevis, occasio praeceps, experimentum periculosum, iudicium difficile"

"Life is short, [the] craft long, opportunity fleeting, experiment treacherous, judgement difficult."

One bug is probably here:

...	if( SUCCEEDED( texMesh->LockVertexBuffer( 0, ( void ** ) &planetVertex )))	{        // get vertex count        int numVerts = texMesh->GetNumVertices();			        // loop through the vertices	planetVertex = new PlanetVertex[ numVerts ];  // <--- HERE!...


No need to re-allocate the array, you just received one with the lock. No wonder you got nonsense in there.

Delete that line and see what you get.

Hope that helps.

unbird
Quote:Original post by unbird
One bug is probably here:

*** Source Snippet Removed ***

No need to re-allocate the array, you just received one with the lock. No wonder you got nonsense in there.

Delete that line and see what you get.

Hope that helps.

unbird


Thanks unbird... you solved it for me :-D

I am gonna explain where I went wrong for the guys who be may still learning or wants to know where I went wrong in my code.

I think I got confused with Vertex Buffers and the way it was done in this code.

Usually, my train of thought when I am dealing with Vertex Buffers is...

1. Initialize Vertex Buffer. eg. IDirect3DVertexBuffer9 *VBStars = NULL;
2. Construct a structure to hold the required info.
2. Define a FVF to say how the structure will be used.
4. Make an array of structures for every vertex needed.
5. Create the actual Vertex Buffer (CreateVertexBuffer function).
5. Lock it and copy from info from my array structure to the actual Vertex Buffer.

But in this case... because I am using DirectX's supplied sphere mesh object there is no need for any of the stuff above.

And the line that unbird told me to remove... I had that line of code because in my mind, and my train of thought was that I needed to make an array of my structure that will hold all the vertices for the UV coordinates (think we call this texel?). Then I would copy that over to the vertex buffer.

So I was imagining doing step 4, 5 and 6 above basically.

Being that it was DirectX supplied sphere mesh, I didn't have to go through setting up the geometry. Maybe if I didn't use the supplied mesh, and instead created my own then I would need to setup the geometry through the Vertex Buffer etc... and then copy in the the video card memory, then draw.

Maybe someone who has more knowledge can confirm that for me?

But anyways, this LOC
if( SUCCEEDED( texMesh->LockVertexBuffer( 0, ( void ** ) &planetVertex )))


I think am setting up the UV coordinates directly inside the video card's vertex buffer (I think, maybe someone can confirm this for me as well), hence all that crap I am going on above isn't required here.

Anyways... hope that clears up some stuff for the guys who is still learning this stuff.

The complete amended LOC I had to change are
planetVertex = new PlanetVertex[ numVerts ]; <--- REMOVED LOC// For loopplanetVertex->tu = asinf( planetVertex->norm.x ) / D3DX_PI + 0.5f;planetVertex->tv = asinf( planetVertex->norm.y ) / D3DX_PI + 0.5f;// go to next vertexplanetVertex++;// End For Loop

Thanks for the help guys.

Do apologize if this is bit long. I hate reading post where once a problem is solved the poster just leaves it and doesn't explain any further :-D

This topic is closed to new replies.

Advertisement