Jump to content
  • Advertisement
Sign in to follow this  
jrmiller84

2d Texturing Problems

This topic is 4847 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 everyone, it's time for another n00b question! Maybe by me asking a million n00b questions, we'll stop other n00bs from reasking the same questions, but probebly not. I'll be the scapegoat. Ok, my problem today is applying textures to 2d polygons. I have created a class that allows for the creation of polygons and today I decided to implement a method for applying textures to that class. When I changed a few different things, I wound up either having all of my polygons disappear (or I suppose they are there, but are black so they arent visible) or all are shown except the ball is black. Here is my method for specifing the texture. This function always returns true, so I don't suspect it is the problem:
bool CPrimitive::SetTexture(const char *TexturePath)
{
	//if(FAILED(D3DXCreateTextureFromFile(myD3DDevice, TexturePath, &myTexture)))	{ return false; }
    if(FAILED(D3DXCreateTextureFromFile(myD3DDevice, TexturePath, &myTexture)))
    {
        return false;
    }
	return true;
}
I changed my FVF from:
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
to
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
When I use the bottom FVF nothing is shown, everything is black. When I use the top one, everything is shown except the ball (the ball is the only instance of my primitive class who has a texture specified). Also added this to the render method of my class:
HRESULT CPrimitive::Render()
{

	myD3DDevice->SetStreamSource(0, myVertexBuf, sizeof(CUSTOMVERTEX));
	myD3DDevice->SetVertexShader(D3DFVF_CUSTOMVERTEX);

	if(myTexture != NULL) {
                     myD3DDevice->SetTexture(0, myTexture);
		     myD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
        } else { 
		     myD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); 
	}	

	myD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);

    return S_OK;
}
I added the if statements to this method. I'm not sure why I cant see my textures. Is it something to do with SetTextureStageState? Im not quite sure where to look on this one. Any information would be awesome. Also, this might be kind of confusing so if you have any questions or want to see the rest of the code I will paste it in here. Thanks everyone.

Share this post


Link to post
Share on other sites
Advertisement
Hi there JrMiller84,
How are you doing?

The Problem
Textured object not displaying
The Solution
I see first of all with your custom vertex format that for the first format you specified XYZRHW (this is already transformed vertices) and in the second you are specifying XYZ which means that the vertices are to be transformed by the world/view/projection matrices.

What does this mean?
Well this means if you have a vertex defined in screen space(D3DFVF_XYZRHW)
such as (0, 200, 0) that when you change the vertex format to D3DFVF_XYZ that the vertex might not be in view since the vertex is then translated 200 above 0.0f, 0.0f, 0.0f. If this doesn't make sense let me rephrase..


1) Vertices drawn with the D3DFVF_XYZ need to be transformed by matrices to be able to get placed in screen space... this means that you are defining the vertex in object space and then a world transformation matrix will place it in the world.

2) Vertices drawn with the D3DFVF_XYZRHW are already transformed and will not be transformed using any transformation matrix on it.

So if you want a textured quad, I would depending on what you want to do change the format back to D3DFVF_XYZRHW for a quick result of redefine your object's vertices to be in object space like
(-1.0f, 0.0f, 0.0f) vertex 1
( 0.0f, 2.0f, 0.0f) vertex 2
( 1.0f, 0.0f, 0.0f) vertex 3
for a simple triangle

I hope this helps. Take care buddy.

Share this post


Link to post
Share on other sites
I think I understood what you meant after I researched D3DFVF_XYZRHW vs. D3DFVF_XYZ. So when using D3DFVF_XYZRHW and specifing an x-coordinate, it is transformed to fit in the world, but when you are using D3DFVF_XYZ everything needs to use transformations to fit in the world instead of just modifying the vertices every time the render method is executed. Do I have that correct? If so, I guess I need to research how to use matrices and world transformations. The reason I am asking all of this is because I am creating a game of pong and I have everything working fine, score count, collision detection, etc but I want the ball to be round, not a square. Thanks guys, let me know if Im doing something completely wrong.

Share this post


Link to post
Share on other sites
Hi there jrMiller84,
How are you doing buddy?

The Problem
Coordinate spaces

The Solution
Transformed Coordinates (D3DFVF_XYZRHW)
Let's assume you have a rectangle that you specify in a left handed coordinate system in the top left hand corner of your window.
D3DFVF_XYZRHW values for a rectangle. Note the last value in the list is a RHW value specified as 1.0f.

( 0.0f, 100.0f, 0.0f, 1.0f) bottom left
( 0.0f, 0.0f, 0.0f, 1.0f) top left
(100.0f, 100.0f, 0.0f, 1.0f) bottom right
(100.0f, 0.0f, 0.0f, 1.0f) top right

This rectangle will not change position as it's already been given a set of transformed vertices.

UnTransformed Coordinates (D3DFVF_XYZ)
Take this example and draw a little rectangle in the middle of your window

D3DFVF_XYZ values for a rectangle.
(-1.0f, 0.0f, 0.0f) bottom left
(-1.0f, 1.0f, 0.0f) top left
( 1.0f, 0.0f, 0.0f) bottom right
( 1.0f, 1.0f, 0.0f) top right

note that these values are significantly smaller than the previous values. To place this object (rectangle) in screen space they need to go through a series of transformations.

Object Space defined vertices
These vertices are defined in a space known as Object/Model space. To place them in a world we need to transform them using a "World" transformation matrix.

Moving from Object Space to World Space
D3DXMATRIX matWorld;
D3DXMatrixTranslation(&matWorld, 0.0f, 0.0f, 0.0f);

This matrix will place an object in the centre of the display window. So when we set the world matrix pDevice->SetTransform(D3DTS_WORLD, &matWorld); every object that gets rendered after that will get placed in the world at coordinates (0.0f, 0.0f, 0.0f) (Which is at the centre of your world).

Moving from World Space to View Space
Now that our object is in world space we need to have a camera that we want to view our object with. We call this our View Space.. We locate the camera in world space and relocate all our objects around our camera.

[source lang = "cpp"]
D3DXVECTOR3 vEyePt ( 0.0f, 0.0f,-5.0f );
D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 vUpVec ( 0.0f, 1.0f, 0.0f );
D3DXMATRIX matView;
D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
pDevice->SetTransform( D3DTS_VIEW, &matView );


As you can see we have an eye ... a point we are looking at and a up vector which states what way up is.

When we set this matrix to the device. We now are relocating our objects in view space. The view space creates a view frustum that looks like a pyramid with it's tip cut off.

Moving from view Space to Clip Space (Projection Space)
Clip space is the space where the View space is transformed into a cube. So if you can imagine what this would look like. If you have an object at the bottom of a pyramid and you make the pyramid a cube... you will have to shrink the object to fit and the objects near to the point of the pyramid will stay almost the same size. This gives us the impression of Perspective. This is what the projection transformation matrix does.

The 2nd parameter is a field of view angle which is 90 degrees here. The next is a aspect ratio which we set to one. The 4th parameter is a near clipping plane, we clip everything that is less than the near clipping plane and we don't render it. Also the same with the last parameter. It's the far clipping plane.
D3DXMatrixPerspectiveFovLH(&matProjection, D3DX_PI/4, 1, 1.0f, 1000.0);
pDevice->SetTransform(D3DTS_PROJECTION, &matProjection);


I hope this helps a bit buddy.
Take care of yourself :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!