Jump to content

  • Log In with Google      Sign In   
  • Create Account

Kjell Andersson

Member Since 28 Nov 1999
Offline Last Active Apr 24 2016 11:19 AM

Posts I've Made

In Topic: Exporting mesh vertex group to text.

10 March 2016 - 12:09 PM

The following code provides you with vertices and face indices from a D3DXMesh. You will have to write the code that saves it to file yourself, but that should be easy.

LPD3DXMESH m_pD3DMesh;

void MeshXWrapper::GetMeshData(int *pMeshVertexCount, dVector3 **ppMeshVertices,
                               int *pMeshIndexCount, int **ppMeshIndices)
{
    LPDIRECT3DVERTEXBUFFER9 pVB = NULL;
    m_pD3DMesh->GetVertexBuffer(&pVB);

    struct MY_FVF {
        float x;
        float y;
        float z;
    };

    void *pbVertexData;
    if (SUCCEEDED(pVB->Lock(0, 0, &pbVertexData, D3DLOCK_READONLY))) {
        DWORD numBytesPerVertex = m_pD3DMesh->GetNumBytesPerVertex();

        int numVertices = m_pD3DMesh->GetNumVertices();
        *ppMeshVertices = new dVector3[numVertices];
        unsigned char *pVBDataPos = (unsigned char*)pbVertexData;
        for (int i=0; i < numVertices; i++) {
            (*ppMeshVertices)[i][0] = ((MY_FVF*)pVBDataPos)->x;
            (*ppMeshVertices)[i][1] = ((MY_FVF*)pVBDataPos)->y;
            (*ppMeshVertices)[i][2] = ((MY_FVF*)pVBDataPos)->z;
            (*ppMeshVertices)[i][3] = 0;
            pVBDataPos += numBytesPerVertex;
        }
        pVB->Unlock();
        *pMeshVertexCount = m_pD3DMesh->GetNumVertices();
    }


    // Index buffer

    LPDIRECT3DINDEXBUFFER9 pIB;
    m_pD3DMesh->GetIndexBuffer(&pIB);
    D3DINDEXBUFFER_DESC indexDesc;
    pIB->GetDesc(&indexDesc);

    LPVOID pbIndexData;
    if (SUCCEEDED(m_pD3DMesh->LockIndexBuffer(D3DLOCK_READONLY, &pbIndexData))) {
        *pMeshIndexCount = indexDesc.Size / sizeof(unsigned short);
        *ppMeshIndices = new int[*pMeshIndexCount];
        for (int i=0; i<(*pMeshIndexCount)/3; i++) {
            unsigned short i0 = ((unsigned short*)pbIndexData)[i*3+0];
            unsigned short i1 = ((unsigned short*)pbIndexData)[i*3+1];
            unsigned short i2 = ((unsigned short*)pbIndexData)[i*3+2];

            (*ppMeshIndices)[i*3+0] = i0;
            (*ppMeshIndices)[i*3+1] = i1;
            (*ppMeshIndices)[i*3+2] = i2;
        }
        m_pD3DMesh->UnlockIndexBuffer();
    }

    pIB->Release();
    pVB->Release();
}


In Topic: IOTD broken

27 February 2016 - 10:46 AM

Oh, forgot to mention that it was the IOTD game I meant. Silly me. But it seems to be working now again so it's all right.


In Topic: Dumping every frame to an image file

07 February 2016 - 06:08 AM

This is the code that I use to take screenshots in-app. Note that if run in windowed mode it captures the entire desktop and cuts out the window area. This means that if some other window is put in front of your window it will capture that data as well.

LPDIRECT3DSURFACE9 CaptureScreen()
{
    UINT width;
    UINT height;
    if (IsFullscreen()) {
        width = GetDisplayWidth();
        height = GetDisplayHeight();
    }
    else {
        width = GetSystemMetrics(SM_CXSCREEN);
        height = GetSystemMetrics(SM_CYSCREEN);
    }

    LPDIRECT3DSURFACE9 pCaptureSurface;
    HRESULT hr = GetD3DDevice()->CreateOffscreenPlainSurface(width, height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pCaptureSurface, NULL);
    if (FAILED(hr)) {
        SAFE_RELEASE(pCaptureSurface);
        return NULL;
    }

    hr = GetD3DDevice()->GetFrontBufferData(0, pCaptureSurface);
    if (FAILED(hr)) {
        SAFE_RELEASE(pCaptureSurface);
        return NULL;
    }

    return pCaptureSurface;
}

bool TakeScreenshot(const std::wstring& filename)
{
	LPDIRECT3DSURFACE9 pCaptureSurface = GetGraphicsDevice()->CaptureScreen();
	HRESULT hr = E_FAIL;
	if (pCaptureSurface != NULL) {
		D3DXIMAGE_FILEFORMAT imageFileFormat = D3DXIFF_JPG;
		std::wstring fileExtention = GXFile::GetFileExtention(filename);
		if (GXString::CompareNoCase(fileExtention.c_str(), L"bmp")) {
			imageFileFormat = D3DXIFF_BMP;
		}
		else if (GXString::CompareNoCase(fileExtention.c_str(), L"png")) {
			imageFileFormat = D3DXIFF_PNG;
		}

		if (GetGraphicsDevice()->IsFullscreen()) {
			hr = D3DXSaveSurfaceToFile(filename.c_str(), imageFileFormat, pCaptureSurface, NULL, NULL);
			if (FAILED(hr)) {
				GXLOG_WARN_F(L"Failed to save fullscreen screenshot to %s", filename.c_str());
			}
		}
		else {
			// Calculate the rectangle within the screen that the window is currently located.
			// I.e. 0,0 is top left of screen for all screens even on multi-monitor setups.
			RECT rcWindow;
			GetClientRect(m_hWnd, &rcWindow);
			POINT topPoint = {rcWindow.left, rcWindow.top};
			POINT bottomPoint = {rcWindow.right, rcWindow.bottom};
			ClientToScreen(m_hWnd, &topPoint);
			ClientToScreen(m_hWnd, &bottomPoint);
			rcWindow.left = topPoint.x;
			rcWindow.top = topPoint.y;
			rcWindow.right = bottomPoint.x;
			rcWindow.bottom = bottomPoint.y;
			for (unsigned int i = 0; i < m_displays.size(); i++) {
				RECT rcDest;
				if (IntersectRect(&rcDest, &m_displays[i].rect, &rcWindow)) {
					rcWindow.left -= m_displays[i].rect.left;
					rcWindow.top -= m_displays[i].rect.top;
					rcWindow.right -= m_displays[i].rect.left;
					rcWindow.bottom -= m_displays[i].rect.top;
					break;
				}
			}
			hr = D3DXSaveSurfaceToFile(filename.c_str(), imageFileFormat, pCaptureSurface, NULL, &rcWindow);
			if (FAILED(hr)) {
				GXLOG_WARN_F(L"Failed to save windowed screenshot to %s", filename.c_str());
			}
		}
		SAFE_RELEASE(pCaptureSurface);
	}
	return SUCCEEDED(hr);
}


In Topic: Blinn-Phong artifact in shader

09 October 2015 - 02:17 PM

Thanks!

I kind of liked the scattering of specular around the rim before multiplying with NdotL, but I guess that should not be part of the Blinn calculations but rather some subsurface scattering effect.


In Topic: Shader variable register mapping in DirectX9

03 October 2015 - 08:55 AM

Great input that I should work towards a cbuffer friendly interface!


PARTNERS