Jump to content
  • Advertisement
Sign in to follow this  
CodeReaver

Unwanted translucency when lighting a mesh:

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

My mesh appears translucent when I use lighting. I can see the polygons nearest to the camera, but I can also see through them to the ones further back. I started with a mesh with do normals or adjacancy information so I added a compute adjacancy and compure normals thing that was suggested. Computing normals gave some sense of light and shade but didn't lelp with the unwanted translucency. I've tried changing the z-buffer settings but the changes I tried seem to prevent it from being displayed properly or at all. Perhaps I'm missing something.:
D3Dpp.BackBufferFormat	= D3DFMT_UNKNOWN;  //D3Ddm.Format;
// D3Dpp.EnableAutoDepthStencil = TRUE;
// D3Dpp.AutoDepthStencilFormat = D3DFMT_D16;
I tried using diffuse like this and it at least made MeshView able to view the file that gets saved properly:
g_pD3DDevice->SetRenderState(D3DRS_COLORVERTEX, TRUE);
g_pD3DDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
Leaving the culling on seemed to help but only at some angles. Is there anything else I could try? The whole file:
#pragma comment(lib,"dxguid.lib")
#pragma comment(lib,"d3dxof.lib")
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
#pragma comment(lib,"winmm.lib")
#include "AMF_Window.h"
#include <mmsystem.h>
#include <d3dx9.h>

/******************************************************************************************/
/*  DIRECTX STUFF                                                                         */
/******************************************************************************************/

struct SR_POLYGON {
	WORD v1, v2, v3, unknown;
	VOID* textureData;  // TEXTUREDATA*
};
struct SR_EX_POLYGON {
	WORD v1, v2, v3; 
};

struct SR_SEGMENT {
	DWORD unknown1;
	WORD unknown2, unknown3;
	WORD vFirst, vLast;
	signed short x, y, z;
	WORD parentID;
	VOID* unknown5;
};
struct SR_EX_SEGMENT {
	WORD vFirst, vLast;
	float x, y, z;
	SR_EX_SEGMENT* parent;
};

struct SR_VERTEX {
	signed short x, y, z;
	WORD normalID;
};
struct SR_EX_VERTEX {
    D3DXVECTOR3	pos;
    D3DXVECTOR3 norm;
	DWORD colour;
};
#define D3DFVF_SR_EX_VERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL)

LPDIRECT3D9				g_pD3D			= NULL;	// D3D Object
LPDIRECT3DDEVICE9		g_pD3DDevice	= NULL;	// D3D Device
LPDIRECT3DVERTEXBUFFER9	g_pVB			= NULL; // D3D Vertex Buffer
LPD3DXMESH				g_pD3DXMesh		= NULL; // D3D X-Mesh
D3DXVECTOR3				centrePos		= D3DXVECTOR3(0,0,0);
D3DXVECTOR3				cameraPos		= D3DXVECTOR3(0,0,0);
int						modelRotX		= 0;
int						modelRotY		= 0;
float					radius			= 0;
bool					fullscreen		= false;
bool					InitD3D		(HWND hWnd);
void					Cleanup		();
void					Render		();
void					SetupMatrices();
void					SetupLights();

bool InitD3D (HWND hWnd) {

	// Create the D3D Object.
	if((g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL) return false;

	// Set the presentation paramaters.
	D3DPRESENT_PARAMETERS D3Dpp = {0};
	// Get the display mode
	D3DDISPLAYMODE D3Ddm;
	if(FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &D3Ddm))) return false;

	if(!fullscreen) {
		D3Dpp.Windowed			= TRUE;
		D3Dpp.SwapEffect		= D3DSWAPEFFECT_DISCARD;
		D3Dpp.BackBufferWidth	= 0;
		D3Dpp.BackBufferHeight	= 0;
		D3Dpp.BackBufferFormat	= D3DFMT_UNKNOWN;  //D3Ddm.Format;
		// D3Dpp.EnableAutoDepthStencil = TRUE;
		// D3Dpp.AutoDepthStencilFormat = D3DFMT_D16;
	}
	else {
		// I'm not using fullscreen mode this time.
		D3Dpp.Windowed               = FALSE;
		D3Dpp.SwapEffect             = D3DSWAPEFFECT_DISCARD;
		RECT deskTopRect;
		GetClientRect(GetDesktopWindow(), &deskTopRect);
		D3Dpp.BackBufferWidth        = deskTopRect.right-deskTopRect.left;
		D3Dpp.BackBufferHeight       = deskTopRect.bottom-deskTopRect.top;
		D3Dpp.BackBufferFormat       = D3DFMT_A8R8G8B8;
	}

	// Create the Direct3D device.
	if (FAILED(
		g_pD3D->CreateDevice(
			D3DADAPTER_DEFAULT,
			D3DDEVTYPE_HAL,
			hWnd,
			D3DCREATE_SOFTWARE_VERTEXPROCESSING,	// Can use D3DCREATE_HARDWARE_VERTEXPROCESSING instead
		    &D3Dpp,
			&g_pD3DDevice
		)
	)) return false;

    // Turn off culling, so we see the front and back of the triangle
	// OK, the culling makes a difference.
    // g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

    // Setup lighting
	SetupLights();

    // Turn on the zbuffer
    g_pD3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);

	return true;
}

void Cleanup() {
	
    if (g_pD3DXMesh != NULL)        
        g_pD3DXMesh->Release();			// Release the mesh.
    if (g_pVB != NULL)        
        g_pVB->Release();				// Release the vertex buffer.
    if (g_pD3DDevice != NULL)
        g_pD3DDevice->Release();		// Release the D3D device.
    if (g_pD3D != NULL)
        g_pD3D->Release();				// Release the D3D object.
}

void SetupMatrices() {

	D3DXMATRIXA16 matWorld, matWorldRotX, matWorldRotY;

	// Rotate once per second.
	//DWORD dwTime = timeGetTime() % 10000;
	//float fAngle = dwTime * (2.0f * D3DX_PI) / 10000.0f;
	//D3DXMatrixRotationY(&matWorldRot, fAngle);

	// Rotation set by  user
	modelRotX	= modelRotX % 100;
	float angle = modelRotX * (2.0f * D3DX_PI) / 100.0f;
	D3DXMatrixRotationZ(&matWorldRotX, angle);

	modelRotY	= modelRotY % 100;
	angle		= modelRotY * (2.0f * D3DX_PI) / 100.0f;
	D3DXMatrixRotationY(&matWorldRotY, angle);

	D3DXMatrixIdentity(&matWorld);
	matWorld._11 /= (2*radius);
	matWorld._22 /= (2*radius);
	matWorld._33 /= (2*radius);
	matWorld._41 -= (centrePos.x / (2*radius));
	matWorld._42 -= (centrePos.y / (2*radius));
	matWorld._43 -= (centrePos.z / (2*radius));

    D3DXMatrixMultiply(&matWorld, &matWorld, &matWorldRotX);
    D3DXMatrixMultiply(&matWorld, &matWorld, &matWorldRotY);
	g_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld);

	// Create the view matrix.
	D3DXMATRIXA16	matView;
	// The direction the camera is facing.
	D3DXVECTOR3		vLookatPt	( 0.0f, 0.0f, 0.0f);
	// The y axis represents up.
	D3DXVECTOR3		vUpVec		( 0.0f, 1.0f, 0.0f);
	D3DXMatrixLookAtLH(&matView, &cameraPos, &vLookatPt, &vUpVec);
	// Transform the view matrix.
	g_pD3DDevice->SetTransform(D3DTS_VIEW, &matView);


	D3DXMATRIXA16 matProj;
	D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1.0f, 0.0f, 100.0f);
	g_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);
}

void SetupLights() {

    g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
	g_pD3DDevice->SetRenderState(D3DRS_COLORVERTEX, TRUE);
	g_pD3DDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
    g_pD3DDevice->SetRenderState(D3DRS_AMBIENT, 0xFF808080);

    D3DMATERIAL9 mtrl;
    ZeroMemory(&mtrl, sizeof(D3DMATERIAL9));
    mtrl.Diffuse.r = mtrl.Ambient.r = 0.5f;
    mtrl.Diffuse.g = mtrl.Ambient.g = 0.5f;
    mtrl.Diffuse.b = mtrl.Ambient.b = 0.5f;
    mtrl.Diffuse.a = mtrl.Ambient.a = 1.0f;
    g_pD3DDevice->SetMaterial(&mtrl);

    D3DLIGHT9 light;
    ZeroMemory(&light, sizeof(D3DLIGHT9));
    light.Type			= D3DLIGHT_DIRECTIONAL;
    light.Range			= 1000.0f;
    light.Diffuse.r		= 0.5f;
    light.Diffuse.g		= 0.5f;
    light.Diffuse.b		= 0.5f;
	light.Diffuse.a		= 1.0f;
	D3DXVECTOR3 vecDir = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
    D3DXVec3Normalize((D3DXVECTOR3*)&light.Direction, &vecDir);

    g_pD3DDevice->SetLight(0, &light);
    g_pD3DDevice->LightEnable(0, TRUE);
}

void Render() {

	if (g_pD3DDevice == NULL) return;

	// Clear the backbuffer to black
	g_pD3DDevice->Clear(
		0,
		NULL,
		D3DCLEAR_TARGET,
		D3DCOLOR_XRGB(0,0,0),
		1.0f,
		0
	);
	
	// Begin the scene
	if(SUCCEEDED(g_pD3DDevice->BeginScene())) {
        SetupMatrices();
		if (g_pD3DXMesh != NULL) g_pD3DXMesh->DrawSubset(0);
		g_pD3DDevice->EndScene();
	}

	g_pD3DDevice->Present(NULL, NULL, NULL, NULL);
}

/******************************************************************************************/
/*  WINDOWS STUFF                                                                         */
/******************************************************************************************/

enum {
	ID_DX_VIEW=1, ID_SUBWIN,
	ID_LOAD,	ID_MLOAD,
	ID_SAVE,	ID_MSAVE,
	ID_MWIRE,	ID_MSOLID,	ID_MRESETVIEW,
	ID_MEXIT
}; 
HWND	subWin, dxView,	loadButton, saveButton;
HMENU	hMenu,	hFileSubMenu, hViewSubMenu;
void CreateSubWindows();
bool LoadSR1Object();
bool SaveSR1Object();

int	WINAPI WinMain (HINSTANCE hInst,HINSTANCE hPrev,LPSTR line,int CmdShow) {

	SetUpWindow("SR1-ModelEx", hInst);
	ShowWindow(g_hWnd, SW_SHOW);
	CreateSubWindows();

	MSG msg ={0};
	if(InitD3D(dxView)) {
		while(msg.message != WM_QUIT) {
			if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
			Render();
		}
	}
	Cleanup();
	return (int) msg.wParam;
}

LRESULT	WINAPI MsgProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) {
	switch(msg) {
		case WM_DESTROY: {
			PostQuitMessage(NULL);
			break;
		}
		case WM_COMMAND: {
			if (wParam==ID_MLOAD)
				LoadSR1Object();
			if (wParam==ID_MSAVE)
				SaveSR1Object();
			if (wParam==ID_MWIRE)
				g_pD3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
			if (wParam==ID_MSOLID)
				g_pD3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
			if (wParam==ID_MRESETVIEW) {
				cameraPos.x = -1.5f;
				modelRotX = 0;
				modelRotY = 0;
				g_pD3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
			}
			if (wParam==ID_MEXIT) PostQuitMessage(NULL);

			switch(HIWORD(wParam)) {
				case BN_CLICKED:
					if ((LOWORD(wParam))==ID_LOAD)	LoadSR1Object();
					if ((LOWORD(wParam))==ID_SAVE)	SaveSR1Object();
				break;
			}
			break;
		}
		case WM_KEYDOWN:
			switch (wParam) {
				case VK_ADD:
				case VK_OEM_PLUS:
					cameraPos.x+=0.10f;
					break;
				case VK_SUBTRACT:
				case VK_OEM_MINUS:
					cameraPos.x-=0.10f;
					break;
				case VK_LEFT:
				case VK_NUMPAD4:
					modelRotY--;
					break;
				case VK_RIGHT:
				case VK_NUMPAD6:
					modelRotY++;
					break;
				case VK_UP:
				case VK_NUMPAD8:
					modelRotX++;
					break;
				case VK_DOWN:
				case VK_NUMPAD2:
					modelRotX--;
					break;
			}
			break;
		case WM_SIZE: {
			RECT rcClient;
			GetClientRect(g_hWnd, &rcClient);
			LPRECT rcParent = (LPRECT)(LPARAM)&rcClient;
			MoveWindow(
				subWin, 
				0, 
				0, 
				rcParent->right, 
				rcParent->bottom, 
				TRUE
			);
			UpdateWindow(subWin);
			break;
		}

	}
	return DefWindowProc(hwnd,msg,wParam,lParam);
}

void CreateSubWindows() {
	// Main Menu
	hMenu = CreateMenu();
	hFileSubMenu = CreatePopupMenu();
	AppendMenu(hFileSubMenu, MF_STRING, ID_MLOAD, "Load");
	AppendMenu(hFileSubMenu, MF_STRING, ID_MSAVE, "Save");
	AppendMenu(hFileSubMenu, MF_STRING, ID_MEXIT, "Exit");
	AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT_PTR)hFileSubMenu, "File");
	hViewSubMenu = CreatePopupMenu();
	AppendMenu(hViewSubMenu, MF_STRING, ID_MSOLID, "Solid");
	AppendMenu(hViewSubMenu, MF_STRING, ID_MWIRE, "Wireframe");
	AppendMenu(hViewSubMenu, MF_STRING, ID_MRESETVIEW, "Reset View");
	AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT_PTR)hViewSubMenu, "View");
	SetMenu(g_hWnd, hMenu);

	// Model view window
	subWin = CreateWindowEx(
       	WS_EX_CLIENTEDGE, "Static", "", WS_VISIBLE | WS_CHILD | WS_MAXIMIZE,
		50,25,300,300, g_hWnd, (HMENU) ID_SUBWIN, g_hInst, 0
	);
	ShowWindow(subWin, SW_SHOW);
	dxView = CreateWindowEx(
       	WS_EX_CLIENTEDGE, "Static", "", WS_VISIBLE | WS_CHILD,
		50,25,300,300, subWin, (HMENU) ID_DX_VIEW, g_hInst, 0
	);
	ShowWindow(dxView, SW_SHOW);

	// Load button
	/*loadButton = CreateWindowEx(
       	0, "Button", "Load", BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD,
		10,10,50,20, g_hWnd, (HMENU) ID_LOAD, g_hInst, 0
	);
	SendDlgItemMessage(g_hWnd, ID_LOAD ,WM_SETFONT, (WPARAM) g_hFont, FALSE);
	ShowWindow(loadButton, SW_SHOW);*/

	// Save button
	/*saveButton = CreateWindowEx(
       	0, "Button", "Save", BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD,
		10,30,50,20, g_hWnd, (HMENU) ID_SAVE, g_hInst, 0
	);
	SendDlgItemMessage(g_hWnd, ID_SAVE ,WM_SETFONT, (WPARAM) g_hFont, FALSE);
	ShowWindow(saveButton, SW_SHOW);*/
	return;
}

bool LoadSR1Object() {

	OPENFILENAME ofn = {0};
	char fileName[MAX_PATH] = "";

	ofn.lStructSize = sizeof(ofn);
	ofn.hwndOwner = g_hWnd;
	ofn.lpstrFilter = "Soul Reaver Object Files (*.SRObj)\0*.SRObj\0All Files (*.*)\0*.*\0";
	ofn.lpstrFile = fileName;
	ofn.nMaxFile = MAX_PATH;
	ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
	ofn.lpstrDefExt = "SRObj";

	if(!GetOpenFileName(&ofn)) {
		return false;
	}

	// Open the file
	HANDLE SRObj = CreateFile(
		fileName, GENERIC_READ, FILE_SHARE_READ,
		NULL, OPEN_EXISTING, NULL, NULL
	);
	if (!SRObj) {
		MessageBox(g_hWnd, "Couldn't open the file", "Error", MB_ICONERROR | MB_OK);
		return false;
	}

	// Load File into Memory
	DWORD fileSize = 0, bytesRead;
	fileSize = GetFileSize(SRObj, NULL);
	VOID* SRObjData = malloc(fileSize);
	if (!SRObjData) {
		MessageBox(g_hWnd, "Couldn't allocate memory", "Error", MB_ICONERROR | MB_OK);
		return false;
	}
	if (!ReadFile(SRObj, SRObjData, fileSize, &bytesRead, NULL)) {
		MessageBox(g_hWnd, "Couldn't read the file", "Error", MB_ICONERROR | MB_OK);
		delete SRObjData;
		CloseHandle(SRObj);
		return false;
	}
	CloseHandle(SRObj);

	// Build map of file
	DWORD loadPoint			= (((*(DWORD*) SRObjData)>>9)<<11)+0x00000800;
	VOID* dataStart			= (BYTE*)	SRObjData+loadPoint;
	VOID* modelData			= (BYTE*)	dataStart+*(DWORD*)((BYTE*)dataStart+*((BYTE*)dataStart+0x0000000C));
	DWORD vertexCount		= *(DWORD*)	modelData;
	SR_VERTEX* vertices		= (SR_VERTEX*)((BYTE*)dataStart+*(DWORD*)((BYTE*)modelData+0x00000004));
	DWORD polygonCount		= *(DWORD*)	((BYTE*)modelData+0x00000010);
	SR_POLYGON* polygons	= (SR_POLYGON*)((BYTE*)dataStart+*(DWORD*)((BYTE*)modelData+0x00000014));
	DWORD segmentCount		= *(DWORD*)	((BYTE*)modelData+0x00000018);
	SR_SEGMENT* segments	= (SR_SEGMENT*)((BYTE*)dataStart+*(DWORD*)((BYTE*)modelData+0x0000001C));

	// Extract the vertices
	SR_EX_VERTEX* exVertices = new SR_EX_VERTEX[vertexCount];
	for (DWORD v=0; v<vertexCount; v++) {
		exVertices[v].pos.x = (float) vertices[v].y;
		exVertices[v].pos.y = (float) vertices[v].z;
		exVertices[v].pos.z = (float) vertices[v].x;
		exVertices[v].colour = 0xFF0000FF;
		exVertices[v].norm  = D3DXVECTOR3(0,0,0);
	}

	// Extract the segment data
	SR_EX_SEGMENT*	exSegments		= new SR_EX_SEGMENT[segmentCount];
	SR_EX_SEGMENT*	currentSegment	= NULL;
	D3DXVECTOR3		currentTrans	= D3DXVECTOR3(0,0,0);
	for (DWORD s=0; s<segmentCount; s++) {
		exSegments[s].x = (float) segments[s].y;
		exSegments[s].y = (float) segments[s].z;
		exSegments[s].z = (float) segments[s].x;
		exSegments[s].vFirst = segments[s].vFirst;
		exSegments[s].vLast = segments[s].vLast;
		if (segments[s].parentID==0xFFFF) exSegments[s].parent = NULL;
		else exSegments[s].parent = &exSegments[segments[s].parentID];
	}
	for (DWORD s=0; s<segmentCount; s++) {
		ZeroMemory(&currentTrans, sizeof(currentTrans));
		currentSegment = &exSegments[s];
		while (currentSegment) {
			currentTrans.x += currentSegment->x;
			currentTrans.y += currentSegment->y;
			currentTrans.z += currentSegment->z;
			currentSegment = currentSegment->parent;
		}
		if ((exSegments[s].vFirst!=0xFFFF) && (exSegments[s].vLast!=0xFFFF)) {
			for (WORD v=exSegments[s].vFirst; v<=exSegments[s].vLast; v++) {
				exVertices[v].pos.x += currentTrans.x;
				exVertices[v].pos.y += currentTrans.y;
				exVertices[v].pos.z += currentTrans.z;
			}
		}
	}

	// Extract the polygons
	SR_EX_POLYGON* exPolygons = new SR_EX_POLYGON[polygonCount];
	for (DWORD p=0; p<polygonCount; p++) {
		exPolygons

.v1 = polygons

.v1; exPolygons

.v2 = polygons

.v2; exPolygons

.v3 = polygons

.v3; } // Do the scaling for (DWORD v=0; v<vertexCount; v++) { exVertices[v].pos.x /= 100.0f; exVertices[v].pos.y /= 100.0f; exVertices[v].pos.z /= 100.0f; } D3DXComputeBoundingSphere( &(*exVertices).pos, vertexCount, sizeof(SR_EX_VERTEX), &centrePos, &radius ); // Get rid of any existing mesh if (g_pD3DXMesh != NULL) g_pD3DXMesh->Release(); // Create Mesh if(FAILED( D3DXCreateMeshFVF( polygonCount, vertexCount, 0, D3DFVF_SR_EX_VERTEX, g_pD3DDevice, &g_pD3DXMesh ) )) { MessageBox(g_hWnd, "Doesn't work!", "Error", MB_ICONERROR | MB_OK | MB_SETFOREGROUND ); return false; } // Do Vertex Buffer void* outVertices = NULL; if(FAILED(g_pD3DXMesh->LockVertexBuffer(0,(void**)&outVertices))) { MessageBox(g_hWnd, "Doesn't work!", "Error", MB_ICONERROR | MB_OK | MB_SETFOREGROUND ); return false; } memcpy(outVertices, exVertices, vertexCount*sizeof(SR_EX_VERTEX)); g_pD3DXMesh->UnlockVertexBuffer(); // Do Index Buffer void* outPolygons = NULL; if(FAILED(g_pD3DXMesh->LockIndexBuffer(0,(void**)&outPolygons))) { MessageBox(g_hWnd, "Doesn't work!", "Error", MB_ICONERROR | MB_OK | MB_SETFOREGROUND ); return false; } memcpy(outPolygons, exPolygons, polygonCount*sizeof(SR_EX_POLYGON)); g_pD3DXMesh->UnlockIndexBuffer(); // Compute normals DWORD *adjacency = new DWORD[g_pD3DXMesh->GetNumFaces()*3]; if(FAILED(g_pD3DXMesh->GenerateAdjacency(0.01f, adjacency))) { delete adjacency; return false; } if(FAILED(D3DXComputeNormals(g_pD3DXMesh, adjacency))) { delete adjacency; return false; } delete adjacency; delete exVertices; delete exSegments; delete exPolygons; free(SRObjData); cameraPos.x = -1.5f; modelRotX = 0; modelRotY = 0; return true; } bool SaveSR1Object() { OPENFILENAME ofn = {0}; char fileName[MAX_PATH] = ""; ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = g_hWnd; ofn.lpstrFilter = "DirectX Mesh Files (*.x)\0*.x\0All Files (*.*)\0*.*\0"; ofn.lpstrFile = fileName; ofn.nMaxFile = MAX_PATH; ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; ofn.lpstrDefExt = "SRObj"; if(GetSaveFileName(&ofn)) { // D3DXF_FILEFORMAT_BINARY, D3DXF_FILEFORMAT_COMPRESSED D3DXSaveMeshToX(fileName, g_pD3DXMesh, NULL, NULL, NULL, 0, D3DXF_FILEFORMAT_TEXT); return true; } return false; }

Share this post


Link to post
Share on other sites
Advertisement
First of all, the term translucent is a bit misleading here, I think. Translucency is the effect of a transparent object which appears solid (i.e. an ice cube for example). In your case, I rather think you mean the back faces are shown in front of the front faces sometimes.

You do turn on the Z-buffer but have you created one? It might help to uncomment these lines:

// D3Dpp.EnableAutoDepthStencil = TRUE;
// D3Dpp.AutoDepthStencilFormat = D3DFMT_D16;


Culling should also be turned on (usually counter-clockwise).

Illco

Share this post


Link to post
Share on other sites
I commented them out because they didn't work properly. My image was reduced to a few horizontal streaks. I already said that leaving the culling switched on only helped at some angles, but not all.

Quote:
The back faces are shown in front of the front faces sometimes.

That was what I meant though.

Share this post


Link to post
Share on other sites
Quote:
Original post by CodeReaver
My image was reduced to a few horizontal streaks.

That happens if you forget to clear your depth buffer :P
But of course that may not be your problem.

Share this post


Link to post
Share on other sites
I'm using this:

// Clear the backbuffer to black
g_pD3DDevice->Clear(
0,
NULL,
D3DCLEAR_TARGET,
D3DCOLOR_XRGB(0,0,0),
1.0f,
0
);


Also, does culling take the normals into account? Like if some vertices are clockwise instead of anti-clockwise or vice-versa, would it use the normals to figure out which side to cull? If that doesn't work, would it need to be the indices in my mesh I need to change?

Share this post


Link to post
Share on other sites
You aren't clearing the depth buffer on your Clear() call. Try replacing "D3DCLEAR_TARGET" with "D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER". This will clear the depth buffer values as well.

Share this post


Link to post
Share on other sites
That should do the trick, I believe. I missed the clearing point.

Quote:

Also, does culling take the normals into account? Like if some vertices are clockwise instead of anti-clockwise or vice-versa, would it use the normals to figure out which side to cull? If that doesn't work, would it need to be the indices in my mesh I need to change?

No, culling is based solely on the winding order of the face -- i.e. the order in which the vertices are listed. With CCW-culling, counter clockwise faces are culled while clockwise faces are shown (order of the vertices when seen from the current viewpoint).

The normals are not involved; they're only used to light non-culled faced.

Illco

Share this post


Link to post
Share on other sites
I tried that and none of it worked. Infact, it made things worse depending on whether I used hardware or software vertex processing. I did manage to fix the problem, though. The problem was here:

D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1.0f, 0.0f, 100.0f);


I used replaced the 0.0f with 0.01f because I wanted my model to be able to get really close to the camera before it stops being drawn. I did look up the function on msdn, but it didn't really explain why using zero causes back faces to show through front faces.

I had to turn off culling as well, because one on the models had wings and other components that I think only had one side to them and I needed no culling to only see one side.

I added a zoom function and it seems that if I move the camera past the object, the thing flips around and heads the other way. I guess I'd either need to move the object instead of the camera or adjust the point the camera is aimed at. It's an exportor/viewer that I'm trying to build.

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!