Calculating projective texture coordinates

Started by
1 comment, last by Evil Steve 14 years, 10 months ago
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;
}


Advertisement
I'm having some results using this method, but it's still wrong!

WRONG!

D3DXMATRIX matProjTex;D3DXMATRIX matProjTex = reflectedViewMat * matProj;// Project the textureVertex *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();

Moving to Graphics Programming and Theory by request of the OP.

This topic is closed to new replies.

Advertisement