[GPG 3 글 4.11] 젬스 3권 4.11 질문입니다.

GPG 시리즈 관련 질답, 논의 공간.

Moderator: 류광

비회원

젬스 3권 4.11 질문입니다.

Post by 비회원 »

젬스 3권 4.11을 보다가 이해가 안되서 질문을 올립니다.
494쪽에서

질문1)
두 끝점들로부터 광선의 방향벡터를 얻는다.
B = B1 - B2
이렇게 되어있는데 임의의 두점중 어떤것이 B1이 되고 어떤것이 B2가 되는지 순서는 중요한게 아닌가요?
그리고, 정작 소스코드에는

Code: Select all

	// Beam vector defined by endpoints.
	// B = B2 - B1
	t_SimpleVector l_beam(
		i_endpoint1.m_x - i_endpoint2.m_x,
		i_endpoint1.m_y - i_endpoint2.m_y,
		i_endpoint1.m_z - i_endpoint2.m_z);
이렇게 되어있던데.. 이렇게 하면 B1 - B2가 되는게 아닌지..

질문2) 시선벡터를 구헌다고 하고서
E = [M03 M13 M23]T - B1 W
이렇게 되어있는데 "카메라의 위치에서 광선끝점들 중 하나를 향하는 벡터"라는 정의에 따르면 저 수식이
"광선의 끝점 위치 - 카메라 위치"가 되어야하는게 아닌가요? 그리고 W라는 문자가 의믜하는게 뭔지 궁금합니다.


위의 두부분이 이해가 가질 않아서 그 아랫부분도 이해가 가질않고 있습니다;;
D3D는 좀 익숙한지라 OPENGL로 된 소스를 D3D로 바꾸어보려고 하는데 수식이 이해가 가질 않아서
잘안되네요;;

혹시 D3D로 변환해보신분 있으시면 간단하게 설명 부탁드립니다. (_ _)
류광
Posts: 3805
Joined: 2001-07-25 09:00
Location: GPGstudy
Contact:

Post by 류광 »

예, 주석의 경우 B1 - B2가 되어야 본문이나 그 아래 코드와 일치합니다. 그리고 E의 수식 역시 지적하신대로 피연산수들의 순서가 바뀌어야 본문과 일치합니다.

원서에도 그렇게 되어 있는데, 저자의(따라서 결국은 저의) 실수입니다. 저자는 이 부분에 대해 크게 신경을 쓰지 않은 것 같은데요. 다행히도(?) 독자의 혼란을 불러일으킨 것 외에 기술적으로는 문제가 되지 않습니다. 어차피 B나 E의 방향이 뒤집히면 P의 방향도 뒤집히고, 결과 M1, M2는 B나 E를 직접 사용하는 게 아니라 P에서 비롯된 벡터들을 사용하니까요.

w는 잘못 들어간 것 같습니다.
비회원

답변 감사합니다. ^^

Post by 비회원 »

제가 책의 내용을 완전히 이해하지 못한상태에서 현재 D3D로 컨버젼시켜보고 있습니다. 그런데 잘안되는군요;;
아래 코드는 제가 지금 테스트해보고 있는 코드입니다. (DXUT에서 테스트해보았습니다. )

Code: Select all

D3DXMATRIXA16			g_matCameraToWorld;
LPDIRECT3DTEXTURE9		g_pTexture;


//OnCreateDevice에서..
V_RETURN(D3DXCreateTextureFromFile(pd3dDevice, L"beam.bmp", &g_pTexture));

// OnResetDevice에서..
pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);

// OnDestroyDevice
SAFE_RELEASE( g_pTexture );

void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
    // Update the camera's position based on user input 
    g_Camera.FrameMove( fElapsedTime );

	g_matCameraToWorld = *g_Camera.GetViewMatrix();
	g_matCameraToWorld._41 = 0;
	g_matCameraToWorld._42 = 0;
	g_matCameraToWorld._43 = 0;
	D3DXMatrixTranspose(&g_matCameraToWorld, &g_matCameraToWorld);
	g_matCameraToWorld._41 = g_Camera.GetEyePt()->x;
	g_matCameraToWorld._42 = g_Camera.GetEyePt()->y;
	g_matCameraToWorld._43 = g_Camera.GetEyePt()->z;
}

void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
    HRESULT hr;
    D3DXMATRIXA16 mWorld;
    D3DXMATRIXA16 mView;
    D3DXMATRIXA16 mProj;
    D3DXMATRIXA16 mWorldViewProjection;
    
    // If the settings dialog is being shown, then
    // render it instead of rendering the app's scene
    if( g_SettingsDlg.IsActive() )
    {
        g_SettingsDlg.OnRender( fElapsedTime );
        return;
    }

    // Clear the render target and the zbuffer 
    V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 0, 0), 1.0f, 0) );

    // Render the scene
    if( SUCCEEDED( pd3dDevice->BeginScene() ) )
    {
        // Get the projection & view matrix from the camera class
        mWorld = *g_Camera.GetWorldMatrix();
        mProj = *g_Camera.GetProjMatrix();
        mView = *g_Camera.GetViewMatrix();

		// Activate camera.
		pd3dDevice->SetTransform(D3DTS_WORLD, g_Camera.GetWorldMatrix());
		pd3dDevice->SetTransform(D3DTS_VIEW, g_Camera.GetViewMatrix());		
		pd3dDevice->SetTransform(D3DTS_PROJECTION, g_Camera.GetProjMatrix());

		// Solid beams.
		pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
		pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR);
		pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR);

		pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR);

		pd3dDevice->SetRenderState(D3DRS_TEXTUREFACTOR, D3DCOLOR_XRGB(255, 255, 255));
		pd3dDevice->SetTexture(0, g_pTexture);

		// Render cube of beams.
		RenderBeam(
			D3DXVECTOR3(10.0, 10.0, 200.0),
			D3DXVECTOR3(10.0, -10.0, 200.0),
			10.0);
		RenderBeam(
			D3DXVECTOR3(10.0, -10.0, 200.0),
			D3DXVECTOR3(-10.0, -10.0, 200.0),
			10.0);
		RenderBeam(
			D3DXVECTOR3(-10.0, -10.0, 200.0),
			D3DXVECTOR3(-10.0, 10.0, 200.0),
			10.0);
		RenderBeam(
			D3DXVECTOR3(-10.0, 10.0, 200.0),
			D3DXVECTOR3(10.0, 10.0, 200.0),
			10.0);
		RenderBeam(
			D3DXVECTOR3(10.0, 10.0, 250.0),
			D3DXVECTOR3(10.0, -10.0, 250.0),
			10.0);
		RenderBeam(
			D3DXVECTOR3(10.0, -10.0, 250.0),
			D3DXVECTOR3(-10.0, -10.0, 250.0),
			10.0);
		RenderBeam(
			D3DXVECTOR3(-10.0, -10.0, 250.0),
			D3DXVECTOR3(-10.0, 10.0, 250.0),
			10.0);
		RenderBeam(
			D3DXVECTOR3(-10.0, 10.0, 250.0),
			D3DXVECTOR3(10.0, 10.0, 250.0),
			10.0);
		RenderBeam(
			D3DXVECTOR3(10.0, 10.0, 200.0),
			D3DXVECTOR3(10.0, 10.0, 250.0),
			10.0);
		RenderBeam(
			D3DXVECTOR3(10.0, -10.0, 200.0),
			D3DXVECTOR3(10.0, -10.0, 250.0),
			10.0);
		RenderBeam(
			D3DXVECTOR3(-10.0, -10.0, 200.0),
			D3DXVECTOR3(-10.0, -10.0, 250.0),
			10.0);
		RenderBeam(
			D3DXVECTOR3(-10.0, 10.0, 200.0),
			D3DXVECTOR3(-10.0, 10.0, 250.0),
			10.0);

		pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
		pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);

        mWorldViewProjection = mWorld * mView * mProj;

        // Update the effect's variables.  Instead of using strings, it would 
        // be more efficient to cache a handle to the parameter by calling 
        // ID3DXEffect::GetParameterByName
        V( g_pEffect->SetMatrix( "g_mWorldViewProjection", &mWorldViewProjection ) );
        V( g_pEffect->SetMatrix( "g_mWorld", &mWorld ) );
        V( g_pEffect->SetFloat( "g_fTime", (float)fTime ) );

        DXUT_BeginPerfEvent( DXUT_PERFEVENTCOLOR, L"HUD / Stats" ); // These events are to help PIX identify what the code is doing
        RenderText();
        V( g_HUD.OnRender( fElapsedTime ) );
        V( g_SampleUI.OnRender( fElapsedTime ) );
        DXUT_EndPerfEvent();

        V( pd3dDevice->EndScene() );
    }
}

typedef struct _VERTEX
{
	D3DXVECTOR3 vPos;
	D3DXVECTOR2 vTexCoord;

	static DWORD FVF;
} VERTEX;

DWORD VERTEX::FVF = {D3DFVF_XYZ|D3DFVF_TEX1};

// Desc: Render a single beam.
void RenderBeam(const D3DXVECTOR3 &i_endpoint1, const D3DXVECTOR3 &i_endpoint2, float i_size)
{
	// Eye vector to beam.
	// E = Cp - B1
	D3DXVECTOR3 l_eye(
		i_endpoint1.x - g_matCameraToWorld._41,
		i_endpoint1.y - g_matCameraToWorld._42,
		i_endpoint1.z - g_matCameraToWorld._43);

	// Beam vector defined by endpoints.
	// B = B2 - B1
	D3DXVECTOR3 l_beam(
		i_endpoint2.x - i_endpoint1.x,
		i_endpoint2.y - i_endpoint1.y,
		i_endpoint2.z - i_endpoint1.z);

	// Cross product of beam and eye.
	// P = B x E
	D3DXVECTOR3 l_perpendicularBeam;

	D3DXVec3Cross(&l_perpendicularBeam, &l_beam, &l_eye);

	// Extract camera front vector from camera to world matrix.
	// Bf = Cf
	D3DXVECTOR3 l_frontVector;
	l_frontVector.x = g_matCameraToWorld._31;
	l_frontVector.y = g_matCameraToWorld._32;
	l_frontVector.z = g_matCameraToWorld._33;

	// Determine up and right vectors.
	// Bu = (Bf x P) * (1 / ||(Bf x P)||)
	// Br = Bf x Bu
	D3DXVECTOR3 l_upVector;
	D3DXVec3Cross(&l_upVector, &l_perpendicularBeam, &l_frontVector);
	D3DXVec3Normalize(&l_upVector, &l_upVector);
	D3DXVECTOR3 l_rightVector;
	D3DXVec3Cross(&l_rightVector, &l_upVector, &l_frontVector);

	// Form matrix from the vectors.
	D3DXMATRIXA16 l_billboardMatrix;
	l_billboardMatrix._31	= l_frontVector.x;
	l_billboardMatrix._32	= l_frontVector.y;
	l_billboardMatrix._33	= l_frontVector.z;
	l_billboardMatrix._21	= l_upVector.x;
	l_billboardMatrix._22	= l_upVector.y;
	l_billboardMatrix._23	= l_upVector.z;
	l_billboardMatrix._11	= l_rightVector.x;
	l_billboardMatrix._12	= l_rightVector.y;
	l_billboardMatrix._13	= l_rightVector.z;

	// Create a matrix for each endpoint.
	D3DXMATRIXA16 l_billboardMatrix1 = l_billboardMatrix;
	l_billboardMatrix1._41	= i_endpoint1.x;
	l_billboardMatrix1._42	= i_endpoint1.y;
	l_billboardMatrix1._43	= i_endpoint1.z;
	D3DXMATRIXA16 l_billboardMatrix2 = l_billboardMatrix;
	l_billboardMatrix2._41	= i_endpoint2.x;
	l_billboardMatrix2._42	= i_endpoint2.y;
	l_billboardMatrix2._43	= i_endpoint2.z;

	// Transform vertices.
	VERTEX a_Vertices[6];

	a_Vertices[0].vPos = D3DXVECTOR3(0.0, i_size, 0.0);
	a_Vertices[0].vTexCoord = D3DXVECTOR2(0, 1);
	a_Vertices[1].vPos = D3DXVECTOR3(i_size, 0.0, 0.0);
	a_Vertices[1].vTexCoord = D3DXVECTOR2(0, 0.5);
	a_Vertices[2].vPos = D3DXVECTOR3(-i_size, 0.0, 0.0);
	a_Vertices[2].vTexCoord = D3DXVECTOR2(0.5, 1);
	a_Vertices[3].vPos = D3DXVECTOR3(i_size, 0.0, 0.0);
	a_Vertices[3].vTexCoord = D3DXVECTOR2(0, 0);
	a_Vertices[4].vPos = D3DXVECTOR3(-i_size, 0.0, 0.0);
	a_Vertices[4].vTexCoord = D3DXVECTOR2(0.5, 0.5);
	a_Vertices[5].vPos = D3DXVECTOR3(0.0, -i_size, 0.0);
	a_Vertices[5].vTexCoord = D3DXVECTOR2(0.5, 0);

	D3DXVec3TransformCoord(&a_Vertices[0].vPos, &a_Vertices[0].vPos, &l_billboardMatrix1);
	D3DXVec3TransformCoord(&a_Vertices[1].vPos, &a_Vertices[1].vPos, &l_billboardMatrix1);
	D3DXVec3TransformCoord(&a_Vertices[2].vPos, &a_Vertices[2].vPos, &l_billboardMatrix1);
	D3DXVec3TransformCoord(&a_Vertices[3].vPos, &a_Vertices[3].vPos, &l_billboardMatrix2);
	D3DXVec3TransformCoord(&a_Vertices[4].vPos, &a_Vertices[4].vPos, &l_billboardMatrix2);
	D3DXVec3TransformCoord(&a_Vertices[5].vPos, &a_Vertices[5].vPos, &l_billboardMatrix2);

	IDirect3DDevice9* pd3dDevice = DXUTGetD3DDevice();	

	pd3dDevice->SetFVF(VERTEX::FVF);
	pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 4, a_Vertices, sizeof(VERTEX));
}

위에 처럼 코딩을 해보니깐 너무 쌩뚱맞게 나옵니다;; 긴막대가 몇개가 보기 싫게 엉켜서요;
어느정도는 이해한거 같은데 그상태에서 컨버젼을 시키려고하니 잘안되네요;
빌보드 행렬을 구하는 수식에서 분명 문제가 있을듯 한데...
어떤 부분이 잘못되었는지 알고싶습니다. 도움부탁드려요~ (_ _)
비회원

자문 자답입니다 ㅋㅋ

Post by 비회원 »

-_- 알고 보니 행렬값의 일부를 초기화하지 않았네여 -_-;;; 무흣 ㅋㅋ;;
Post Reply