24.1 막외 렌더링 프로그램 오류 수정

53970 단어 잘못
24. 프로그램 코드는 책과 함께 제공된 CD에서 유래한 것으로, bool InitializeObjects(), void RenderScene() 두 함수의 코드로 인해 제대로 실행되지 않습니다.먼저 이 두 함수를 보면 원래의 코드는 다음과 같다.
bool InitializeObjects()
{
// Setup the g_Light source.
g_Light.Type = D3DLIGHT_DIRECTIONAL;
g_Light.Direction
= D3DXVECTOR3(0.0f, 0.0f, 1.0f);
g_Light.Diffuse.r
= 1;
g_Light.Diffuse.g
= 1;
g_Light.Diffuse.b
= 1;
g_Light.Diffuse.a
= 1;
g_Light.Specular.r
= 1;
g_Light.Specular.g
= 1;
g_Light.Specular.b
= 1;
g_Light.Specular.a
= 1;

g_D3DDevice
->SetLight(0, &g_Light);
g_D3DDevice
->LightEnable(0, TRUE);

// Setup the material properties for the teapot.
ZeroMemory(&g_Material, sizeof(D3DMATERIAL9));
g_Material.Diffuse.r
= g_Material.Ambient.r = 0.6f;
g_Material.Diffuse.g
= g_Material.Ambient.g = 0.6f;
g_Material.Diffuse.b
= g_Material.Ambient.b = 0.7f;
g_Material.Specular.r
= 0.4f;
g_Material.Specular.g
= 0.4f;
g_Material.Specular.b
= 0.4f;
g_Material.Power
= 8.0f;

// Create the teapot.
if(FAILED(D3DXCreateTeapot(g_D3DDevice, &g_Teapot, NULL)))
return false;


// Create the texture that will be rendered to.
if(FAILED(D3DXCreateTexture(g_D3DDevice, WINDOW_WIDTH,
WINDOW_HEIGHT,
1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
D3DPOOL_DEFAULT,
&g_SurfaceTexture))) return false;

// Set texture to offscreen surface.
g_SurfaceTexture->GetSurfaceLevel(0, &g_OffScreenSurface);


// Square that will be textured with offscreen rendering data.
stD3DVertex square[] =
{
{
-1, 1, -1, 0, 0}, {1, 1, -1, 1, 0},
{
-1, -1, -1, 0, 1}, {1, -1, -1, 1, 1}
};

g_D3DDevice
->CreateVertexBuffer(4 * sizeof(stD3DVertex), 0,
D3DFVF_VERTEX, D3DPOOL_DEFAULT,
&g_VertexBuffer, NULL);

void *pData = NULL;
g_VertexBuffer
->Lock(0, sizeof(square), (void**)&pData, 0);
memcpy(pData, square,
sizeof(square));
g_VertexBuffer
->Unlock();


// Set the image states to get a good quality image.
g_D3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
g_D3DDevice
->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);

// Set default rendering states.
g_D3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
g_D3DDevice
->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
g_D3DDevice
->SetRenderState(D3DRS_ZENABLE, TRUE);

// Set the projection matrix.
D3DXMatrixPerspectiveFovLH(&g_projection, 45.0f,
WINDOW_WIDTH
/WINDOW_HEIGHT, 0.1f, 1000.0f);
g_D3DDevice
->SetTransform(D3DTS_PROJECTION, &g_projection);

// Define camera information.
D3DXVECTOR3 cameraPos(0.0f, 0.0f, -4.0f);
D3DXVECTOR3 lookAtPos(
0.0f, 0.0f, 0.0f);
D3DXVECTOR3 upDir(
0.0f, 1.0f, 0.0f);

// Build view matrix.
D3DXMatrixLookAtLH(&g_ViewMatrix, &cameraPos,
&lookAtPos, &upDir);

return true;
}


void RenderScene()
{
// Get a copy of the back buffer.
g_D3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &g_BackSurface);

// Prepare to draw to the offscreen surface.
g_D3DDevice->SetRenderTarget(0, g_OffScreenSurface);

// Clear the offscreen surface.
g_D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(255,255,255), 1.0f, 0);

// Begin the scene. Start rendering.
g_D3DDevice->BeginScene();

// Turn on lighting.
g_D3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);

// Set projection.
g_D3DDevice->SetTransform(D3DTS_PROJECTION, &g_projection);

// Create rotation matrix to rotate teapot.
D3DXMATRIXA16 w;
D3DXMatrixRotationY(
&w, g_RotationAngle);
g_D3DDevice
->SetTransform(D3DTS_WORLD, &w);

// Add to the rotation.
g_RotationAngle += 0.02f;
if(g_RotationAngle >= 360)
g_RotationAngle
= 0.0f;

// Apply the view (camera).
g_D3DDevice->SetTransform(D3DTS_VIEW, &g_ViewMatrix);

// Set the material and draw the Teapot.
g_D3DDevice->SetMaterial(&g_Material);
g_D3DDevice
->SetTexture(0, NULL);
g_Teapot
->DrawSubset(0);

// End the scene. Stop rendering.
g_D3DDevice->EndScene();

// Switch back to our back buffer.
g_D3DDevice->SetRenderTarget(0, g_BackSurface);

// Clear the back buffer.
g_D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);

// Begin the scene. Start rendering.
g_D3DDevice->BeginScene();

// Turn off lighting. Don't need it.
g_D3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);

// Set projection.
g_D3DDevice->SetTransform(D3DTS_PROJECTION, &g_projection);

// Rotate just a little to see this is a flat surface.
D3DXMatrixRotationY(&w, 120);
g_D3DDevice
->SetTransform(D3DTS_WORLD, &w);

// Apply the view (camera).
g_D3DDevice->SetTransform(D3DTS_VIEW, &g_ViewMatrix);

g_D3DDevice
->SetTexture(0, g_SurfaceTexture);
g_D3DDevice
->SetStreamSource(0, g_VertexBuffer, 0, sizeof(stD3DVertex));
g_D3DDevice
->SetFVF(D3DFVF_VERTEX);
g_D3DDevice
->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);

// End the scene. Stop rendering.
g_D3DDevice->EndScene();

// Display the scene.
g_D3DDevice->Present(NULL, NULL, NULL, NULL);
}

  
InitializeObjects() 함수에서 텍스쳐를 만들 때 WINDOWWIDTH, WINDOW_HEIGHT는 무늬의 폭과 높이로서 이 무늬와 관련된 스크린 표면을 얻고 장면을 이 스크린 표면에 렌더링하고 이 표면을 렌더링하는 것이 주요한 사고방식이다.
주의: 무늬를 만들 때 무늬를 위한 깊이 캐시를 만들지 않기 때문에 장면을 스크린 표면으로 렌더링할 때 백버퍼의 깊이 캐시를 사용합니다!그러나 백버퍼의 깊이 캐시 폭과 높이는 WINDOW보다 작아야 한다WIDTH, WINDOW_HEIGHT(윈도우즈 렌더링 창의 너비와 높이는 각각 WINDOW WIDTH, WINDOW HEIGHT이지만 창의 외곽선, 메뉴 상자를 잘라내야 합니다. 이후 실제로 백buffer의 너비와 높이는 WINDOW WIDTH, WINDOW HEIGHT보다 작아야 합니다. 즉, 화면 표면에 렌더링할 때 화면 표면의 깊이 캐시 사이즈와 데이터 캐시 사이즈가 일치하지 않습니다.)이때 깊이 캐시 사이즈는 효과 데이터 캐시보다 작아서 오류가 발생했습니다!!!
두 가지 방법으로 해결할 수 있습니다.
1. 
    if(FAILED(D3DXCreateTexture(g_D3DDevice, 256,
256, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
D3DPOOL_DEFAULT,
&g_SurfaceTexture))) return false;

무늬를 만들 때 너비와 높이를 창의 너비와 높이보다 일정한 수치로 바꾸면 된다.이 때 화면 표면의 데이터 캐시 사이즈는 백버퍼의 깊이 캐시 사이즈보다 작기 때문에 백버퍼의 깊이 캐시를 자신의 깊이 캐시로 사용해도 오류가 발생하지 않습니다.
2. 원거리 스크린 표면에 수동으로 깊이 캐시를 생성합니다.
bool InitializeObjects()
{
// Setup the g_Light source.
g_Light.Type = D3DLIGHT_DIRECTIONAL;
g_Light.Direction
= D3DXVECTOR3(0.0f, 0.0f, 1.0f);
g_Light.Diffuse.r
= 1;
g_Light.Diffuse.g
= 1;
g_Light.Diffuse.b
= 1;
g_Light.Diffuse.a
= 1;
g_Light.Specular.r
= 1;
g_Light.Specular.g
= 1;
g_Light.Specular.b
= 1;
g_Light.Specular.a
= 1;

g_D3DDevice
->SetLight(0, &g_Light);
g_D3DDevice
->LightEnable(0, TRUE);

// Setup the material properties for the teapot.
ZeroMemory(&g_Material, sizeof(D3DMATERIAL9));
g_Material.Diffuse.r
= g_Material.Ambient.r = 0.6f;
g_Material.Diffuse.g
= g_Material.Ambient.g = 0.6f;
g_Material.Diffuse.b
= g_Material.Ambient.b = 0.7f;
g_Material.Specular.r
= 0.4f;
g_Material.Specular.g
= 0.4f;
g_Material.Specular.b
= 0.4f;
g_Material.Power
= 8.0f;

// Create the teapot.
if(FAILED(D3DXCreateTeapot(g_D3DDevice, &g_Teapot, NULL)))
return false;


// Create the texture that will be rendered to.
if(FAILED(D3DXCreateTexture(g_D3DDevice, WINDOW_WIDTH,
WINDOW_HEIGHT,
0, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
D3DPOOL_DEFAULT,
&g_SurfaceTexture))) return false;

if(FAILED(g_D3DDevice->CreateDepthStencilSurface(WINDOW_WIDTH,
WINDOW_HEIGHT, D3DFMT_D16, D3DMULTISAMPLE_NONE,
0, TRUE,
&g_SurfaceTextureDepth, NULL))) return false;

// Set texture to offscreen surface.
g_SurfaceTexture->GetSurfaceLevel(0, &g_OffScreenSurface);

// Square that will be textured with offscreen rendering data.
stD3DVertex square[] =
{
{
-1, 1, -1, 0, 0}, {1, 1, -1, 1, 0},
{
-1, -1, -1, 0, 1}, {1, -1, -1, 1, 1}
};

g_D3DDevice
->CreateVertexBuffer(4 * sizeof(stD3DVertex), 0,
D3DFVF_VERTEX, D3DPOOL_DEFAULT,
&g_VertexBuffer, NULL);

void *pData = NULL;
g_VertexBuffer
->Lock(0, sizeof(square), (void**)&pData, 0);
memcpy(pData, square,
sizeof(square));
g_VertexBuffer
->Unlock();


// Set the image states to get a good quality image.
g_D3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
g_D3DDevice
->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);

// Set default rendering states.
g_D3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
g_D3DDevice
->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
g_D3DDevice
->SetRenderState(D3DRS_ZENABLE, TRUE);
g_D3DDevice
->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);


// Set the projection matrix.
D3DXMatrixPerspectiveFovLH(&g_projection, 45.0f,
WINDOW_WIDTH
/WINDOW_HEIGHT, 0.1f, 1000.0f);
g_D3DDevice
->SetTransform(D3DTS_PROJECTION, &g_projection);

// Define camera information.
D3DXVECTOR3 cameraPos(0.0f, 0.0f, -4.0f);
D3DXVECTOR3 lookAtPos(
0.0f, 0.0f, 0.0f);
D3DXVECTOR3 upDir(
0.0f, 1.0f, 0.0f);

// Build view matrix.
D3DXMatrixLookAtLH(&g_ViewMatrix, &cameraPos,
&lookAtPos, &upDir);

return true;
}


void RenderScene()
{
// Begin the scene. Start rendering.
g_D3DDevice->BeginScene();

// Get a copy of the back buffer.
// g_D3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &g_BackSurface);

g_D3DDevice
->GetRenderTarget(0, &g_BackSurface);
// Prepare to draw to the offscreen surface.
g_D3DDevice->SetRenderTarget(0, g_OffScreenSurface);
g_D3DDevice
->SetDepthStencilSurface(g_SurfaceTextureDepth);

// Clear the offscreen surface.
g_D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(255,100,100,255), 1.0f, 0);

// Turn on lighting.
g_D3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
g_D3DDevice
->SetRenderState(D3DRS_ZENABLE, TRUE);
// Set projection.
g_D3DDevice->SetTransform(D3DTS_PROJECTION, &g_projection);

// Create rotation matrix to rotate teapot.
D3DXMATRIXA16 w;
D3DXMatrixRotationY(
&w, g_RotationAngle);
g_D3DDevice
->SetTransform(D3DTS_WORLD, &w);

// Add to the rotation.
g_RotationAngle += 0.02f;
if(g_RotationAngle >= 360)
g_RotationAngle
= 0.0f;

// Apply the view (camera).
g_D3DDevice->SetTransform(D3DTS_VIEW, &g_ViewMatrix);

// Set the material and draw the Teapot.
g_D3DDevice->SetMaterial(&g_Material);
g_D3DDevice
->SetTexture(0, NULL);
g_Teapot
->DrawSubset(0);

// End the scene. Stop rendering.
//g_D3DDevice->EndScene();

// Switch back to our back buffer.
g_D3DDevice->SetRenderTarget(0, g_BackSurface);
g_D3DDevice
->SetDepthStencilSurface(NULL);


// Begin the scene. Start rendering.
g_D3DDevice->BeginScene();
// Clear the back buffer.
g_D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(255,0,0,255), 1.0f, 0);

// Turn off lighting. Don't need it.
g_D3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
g_D3DDevice
->SetRenderState(D3DRS_ZENABLE, FALSE);

// Set projection.
g_D3DDevice->SetTransform(D3DTS_PROJECTION, &g_projection);

// Rotate just a little to see this is a flat surface.
D3DXMatrixRotationY(&w, 120);
g_D3DDevice
->SetTransform(D3DTS_WORLD, &w);

// Apply the view (camera).
g_D3DDevice->SetTransform(D3DTS_VIEW, &g_ViewMatrix);


g_D3DDevice
->SetTexture(0, g_SurfaceTexture);
g_D3DDevice
->SetStreamSource(0, g_VertexBuffer, 0, sizeof(stD3DVertex));
g_D3DDevice
->SetFVF(D3DFVF_VERTEX);
g_D3DDevice
->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);

// End the scene. Stop rendering.
g_D3DDevice->EndScene();

// Display the scene.
g_D3DDevice->Present(NULL, NULL, NULL, NULL);

g_BackSurface
->Release();
}

  
오프 스크린 표면을 위한 깊이 캐시 크기는 오프 스크린 표면의 데이터 캐시 크기와 동일합니다.WINDOWWIDTH, WIDNOW_HEIGHT.

좋은 웹페이지 즐겨찾기