Jump to content
  • Advertisement
Sign in to follow this  
yogr

Calculating projective texture coordinates

This topic is 3355 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

Hi guys, I'm practicing with projective texture mapping for the very first time and I'm having some troubles calculating the texture coords. I'm trying to implement it using the fixed pipeline (without setting the texture transform matrix), then I will try using the texture transform matrix and finally using a vertex shader. I have have simple scene with a rotating cube on a reflecting plane: the cube is a D3DXMesh, while the plane is made up of 4 vertices in an indexed vertex buffer. I reflect the camera below the plane surface and render the scene to a texture, then I lock the vertex buffer and i loops through the vertices to assign a texture coord. I've read a lot of articles, but I still have some doubts: in the "reflective water rendering" article I've learned that the transform matrix is obtained by: remapMatrix * matProj * reflectedMatView * matWorld, then the resulting tex coords are (r,s,t,q) => (r/q, s/q, t/q, 1). I can't understand why the remap matrix is applied before the division by q... when I transform a position vector using the view and projection matrix I obtain coordinates in homogeneus clip space, then dividing by w i get the values ranging from -1 to 1 and THEN I should remap the values from -1,1 to 0,1... is It wrong? Here's my code... thanks!
struct Vertex {
	float x, y, z;
	float nx, ny, nz;
	DWORD color;
	float u0, v0;
	float u1, v1;
};
const DWORD FVF_VERTEX = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1 | D3DFVF_TEX2;

Vertex data[]={
	{-100.0, -10.0, 100.0, 0.0, 1.0, 0.0, 0xFF000000, 0.0, 5.0, 0.0, 1.0},    
	{100.0, -10.0, -100.0, 0.0, 1.0, 0.0, 0xFF000000, 5.0, 0.0, 1.0, 0.0},  
	{-100.0, -10.0, -100.0, 0.0, 1.0, 0.0, 0xFF000000, 0.0, 0.0, 0.0, 0.0}, 
	{100.0, -10.0, 100.0, 0.0, 1.0, 0.0, 0xFF000000, 5.0, 5.0, 1.0, 1.0}, 
};

D3DXMATRIX matRemap(0.5, 0,   0,   0.5,
					0,   0.5, 0,   0.5,
					0,   0,   0.5, 0.5,
					0,   0,   0,   1.0);

void renderScene() {
	// Clear the render target and the zbuffer 
    pDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB( 255, 70, 70, 70 ), 1.0f, 0 );
	
	pDevice->SetTexture(0, tex);
	
	D3DXMATRIX id;
	pDevice->SetTransform(D3DTS_WORLD, D3DXMatrixIdentity(&id));
	pDevice->SetStreamSource(0, vb, 0, sizeof(Vertex));
	pDevice->SetIndices(ib);
	pDevice->SetFVF(FVF_VERTEX);
	pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);

	// Draw the box
	pDevice->SetTexture(0, 0);
	pDevice->SetTexture(1, 0);
	D3DXMATRIX rot;
	D3DXMatrixRotationYawPitchRoll(&rot, yaw, pitch, roll);
	rot._42 = 5;
	pDevice->SetTransform(D3DTS_WORLD, &rot);
	pBox->DrawSubset(0);
}

void renderReflection() {
	D3DXVECTOR3 wRefEye = wEyePos;
	wRefEye.y = - 10 - (wEyePos.y + 10);
	D3DXMATRIX refMat;
//refMat is the reflected view matrix
	pDevice->SetTransform(D3DTS_VIEW, D3DXMatrixLookAtLH(&refMat, &wRefEye, &wLookAt, &wUp));
	pDevice->SetTransform(D3DTS_PROJECTION, &matRTTProj);
	pDevice->SetRenderTarget(0, rttSurface);

	if ( SUCCEEDED( pDevice->BeginScene() ) )
    {
		pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(255, 70, 70, 70), 1.0f, 0);
		pDevice->SetTexture(1, NULL);
		renderScene();
		pDevice->EndScene();
	}

	//D3DXMATRIX matProjTex;
	D3DXMATRIX matProjTex = matRemap * matProj * refMat;
	
	// Project the texture
	Vertex *vertices = NULL;
	vb->Lock(0, 0, (VOID **) &vertices, D3DLOCK_DISCARD);
	int len = sizeof(vertices);
	for (int i=0; i<len; i++) {
		D3DXVECTOR4 c(vertices.x, vertices.y, vertices.z, 1.0);
		D3DXVECTOR4 p;
		D3DXVec4Transform(&p, &c, &matProjTex);
		p /= p.w;
		vertices.u1 = p.x;
		vertices.v1 = p.y;
	}
	vb->Unlock();

// Reset the view and proj matrices
	pDevice->SetTransform(D3DTS_VIEW, &matView);
	pDevice->SetTransform(D3DTS_PROJECTION, &matProj);
	pDevice->SetRenderTarget(0, pBackBuffer);
}

//--------------------------------------------------------------------------------------
// Render the scene using the D3D9 device
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9FrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
    HRESULT hr;

    renderReflection();
	
	pDevice->SetTexture(1, 0);

    // Render the scene
    if ( SUCCEEDED( pd3dDevice->BeginScene() ) )
    {
		pDevice->SetTexture(1, rttTex);
		renderScene();
		
		V( pd3dDevice->EndScene() );
    }

	dLastTime = curTime;
}


Share this post


Link to post
Share on other sites
Advertisement
I'm having some results using this method, but it's still wrong!

WRONG!


D3DXMATRIX matProjTex;
D3DXMATRIX matProjTex = reflectedViewMat * matProj;

// Project the texture
Vertex *vertices = NULL;
vb->Lock(0, 0, (VOID **) &vertices, D3DLOCK_DISCARD);
int len = sizeof(vertices);
for (int i=0; i<len; i++) {
// Vertex Position
D3DXVECTOR4 c(vertices.x, vertices.y, vertices.z, 1.0);
D3DXVECTOR4 p;
D3DXVec4Transform(&p, &c, &matProjTex);
p /= p.w;
// Bias (this is the remapMatrix)
vertices.u1 = p.x * 0.5 + 0.5;
vertices.v1 = p.y * 0.5 + 0.5;
}
vb->Unlock();


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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!