Jump to content
  • Advertisement

eonerf

Member
  • Content Count

    5
  • Joined

  • Last visited

Community Reputation

100 Neutral

About eonerf

  • Rank
    Newbie
  1. Hi, I was wondering if it was possible to produce some sort of DirectX9 and C++ equivalent of this XNA program that could load models on the fly. I am mainly looking for a pointer more than anything else as it is not something I have to implement for my Uni assignment, I am just more curious than anything else
  2. eonerf

    [DX9] HLSL Problem

    It's working now . Thanks for your help guys
  3. Hi, I have been converting a Toon-Shader from XNA 4.0 into DirectX 9 C++ (the XNA source code can be found here). I seem to have got most of the DirectX code in place but instead of seeing cel-shading, the mesh is completely rendered black. I suspect this might be due to the inverse transpose of the world matrix but I might be completely wrong since my DirectX programming isn't brilliant Here's the code I have got so far: Mesh.cpp #include <Windows.h> #include <mmsystem.h> #include <d3dx9.h> #pragma warning( disable : 4996 ) // disable deprecated warning #include <strsafe.h> #pragma warning( default : 4996 ) //----------------------------------------------------------------------------- // Global variables //----------------------------------------------------------------------------- LPDIRECT3D9 g_pD3D = NULL; // Used to create the D3DDevice LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; // Our rendering device LPD3DXMESH g_pMesh = NULL; // Our mesh object in sysmem D3DMATERIAL9* g_pMeshMaterials = NULL; // Materials for our mesh LPDIRECT3DTEXTURE9* g_pMeshTextures = NULL; // Textures for our mesh DWORD g_dwNumMaterials = 0L; // Number of mesh materials LPDIRECT3DTEXTURE9 g_pTexture = NULL; D3DXMATRIXA16 matWorld; D3DXMATRIXA16 matView; D3DXMATRIXA16 matProj; LPD3DXEFFECT anEffect; D3DXHANDLE hTech; //----------------------------------------------------------------------------- // Name: InitD3D() // Desc: Initializes Direct3D //----------------------------------------------------------------------------- HRESULT InitD3D( HWND hWnd ) { // Create the D3D object. if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) ) return E_FAIL; // Set up the structure used to create the D3DDevice. Since we are now // using more complex geometry, we will create a device with a zbuffer. D3DPRESENT_PARAMETERS d3dpp; ZeroMemory( &d3dpp, sizeof( d3dpp ) ); d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; d3dpp.EnableAutoDepthStencil = TRUE; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; // Create the D3DDevice if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice ) ) ) { return E_FAIL; } // Turn on the zbuffer g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE ); // Turn on ambient lighting g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0xffffffff ); return S_OK; } //----------------------------------------------------------------------------- // Name: InitGeometry() // Desc: Load the mesh and build the material and texture arrays //----------------------------------------------------------------------------- HRESULT InitGeometry() { LPD3DXBUFFER pD3DXMtrlBuffer; // Load the mesh from the specified file if( FAILED( D3DXLoadMeshFromX( L"Tiger.x", D3DXMESH_SYSTEMMEM, g_pd3dDevice, NULL, &pD3DXMtrlBuffer, NULL, &g_dwNumMaterials, &g_pMesh ) ) ) { // If model is not in current folder, try parent folder if( FAILED( D3DXLoadMeshFromX( L"..\\Tiger.x", D3DXMESH_SYSTEMMEM, g_pd3dDevice, NULL, &pD3DXMtrlBuffer, NULL, &g_dwNumMaterials, &g_pMesh ) ) ) { MessageBox( NULL, L"Could not find tiger.x", L"Meshes.exe", MB_OK ); return E_FAIL; } } // We need to extract the material properties and texture names from the // pD3DXMtrlBuffer D3DXMATERIAL* d3dxMaterials = ( D3DXMATERIAL* )pD3DXMtrlBuffer->GetBufferPointer(); g_pMeshMaterials = new D3DMATERIAL9[g_dwNumMaterials]; if( g_pMeshMaterials == NULL ) return E_OUTOFMEMORY; g_pMeshTextures = new LPDIRECT3DTEXTURE9[g_dwNumMaterials]; if( g_pMeshTextures == NULL ) return E_OUTOFMEMORY; for( DWORD i = 0; i < g_dwNumMaterials; i++ ) { // Copy the material g_pMeshMaterials = d3dxMaterials.MatD3D; // Set the ambient color for the material (D3DX does not do this) g_pMeshMaterials.Ambient = g_pMeshMaterials.Diffuse; g_pMeshTextures = NULL; if( d3dxMaterials.pTextureFilename != NULL && lstrlenA( d3dxMaterials.pTextureFilename ) > 0 ) { // Create the texture if( FAILED( D3DXCreateTextureFromFileA( g_pd3dDevice, d3dxMaterials.pTextureFilename, &g_pMeshTextures ) ) ) { // If texture is not in current folder, try parent folder const CHAR* strPrefix = "..\\"; CHAR strTexture[MAX_PATH]; strcpy_s( strTexture, MAX_PATH, strPrefix ); strcat_s( strTexture, MAX_PATH, d3dxMaterials.pTextureFilename ); // If texture is not in current folder, try parent folder if( FAILED( D3DXCreateTextureFromFileA( g_pd3dDevice, strTexture, &g_pMeshTextures ) ) ) { MessageBox( NULL, L"Could not find texture map", L"Meshes.exe", MB_OK ); } } } } //With this method you load your effect file D3DXCreateEffectFromFile(g_pd3dDevice, L"Toon.fx", NULL, NULL, 0, NULL, &anEffect, NULL); // Done with the material buffer pD3DXMtrlBuffer->Release(); return S_OK; } //----------------------------------------------------------------------------- // Name: Cleanup() // Desc: Releases all previously initialized objects //----------------------------------------------------------------------------- VOID Cleanup() { if( g_pMeshMaterials != NULL ) delete[] g_pMeshMaterials; if( g_pMeshTextures ) { for( DWORD i = 0; i < g_dwNumMaterials; i++ ) { if( g_pMeshTextures ) g_pMeshTextures->Release(); } delete[] g_pMeshTextures; } if( g_pMesh != NULL ) g_pMesh->Release(); if( g_pd3dDevice != NULL ) g_pd3dDevice->Release(); if( g_pD3D != NULL ) g_pD3D->Release(); if( anEffect!= NULL ) anEffect->Release(); } //----------------------------------------------------------------------------- // Name: SetupMatrices() // Desc: Sets up the world, view, and projection transform matrices. //----------------------------------------------------------------------------- VOID SetupMatrices() { // Set up world matrix D3DXMatrixRotationY( &matWorld, timeGetTime() / 1000.0f ); g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld ); // Set up our view matrix. A view matrix can be defined given an eye point, // a point to lookat, and a direction for which way is up. Here, we set the // eye five units back along the z-axis and up three units, look at the // origin, and define "up" to be in the y-direction. D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f ); D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f ); D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f ); D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec ); g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView ); // For the projection matrix, we set up a perspective transform (which // transforms geometry from 3D view space to 2D viewport space, with // a perspective divide making objects smaller in the distance). To build // a perpsective transform, we need the field of view (1/4 pi is common), // the aspect ratio, and the near and far clipping planes (which define at // what distances geometry should be no longer be rendered). D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 4, 1.0f, 1.0f, 100.0f ); g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj ); } //----------------------------------------------------------------------------- // Name: Render() // Desc: Draws the scene //----------------------------------------------------------------------------- VOID Render() { UINT numberOfPasses; // Clear the backbuffer and the zbuffer g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 0, 0, 255 ), 1.0f, 0 ); // Begin the scene if( SUCCEEDED( g_pd3dDevice->BeginScene() ) ) { // Setup the world, view, and projection matrices SetupMatrices(); anEffect->SetMatrix("World", &matWorld); anEffect->SetMatrix("View", &matView); anEffect->SetMatrix("Projection", &matProj); // Get Inverse Transpose of World Matrix D3DXMATRIX iTWM; D3DXMatrixInverse(&iTWM, 0, &matWorld); D3DXMatrixTranspose(&iTWM, &iTWM); anEffect->SetMatrix("WorldInverseTranspose", &iTWM); anEffect->SetTechnique("Toon"); if( SUCCEEDED(anEffect->Begin(&numberOfPasses, NULL))) { for(UINT i = 0; i < numberOfPasses; i++) { anEffect->BeginPass(i); for (DWORD j = 0; j < g_dwNumMaterials; j++) { anEffect->SetTexture("Texture", g_pMeshTextures[j]); anEffect->CommitChanges(); g_pMesh->DrawSubset(j); } anEffect->EndPass(); anEffect->End(); } // End the scene g_pd3dDevice->EndScene(); } } // Present the backbuffer contents to the display g_pd3dDevice->Present( NULL, NULL, NULL, NULL ); } //----------------------------------------------------------------------------- // Name: MsgProc() // Desc: The window's message handler //----------------------------------------------------------------------------- LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_DESTROY: Cleanup(); PostQuitMessage( 0 ); return 0; } return DefWindowProc( hWnd, msg, wParam, lParam ); } //----------------------------------------------------------------------------- // Name: WinMain() // Desc: The application's entry point //----------------------------------------------------------------------------- INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT ) { UNREFERENCED_PARAMETER( hInst ); // Register the window class WNDCLASSEX wc = { sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L, GetModuleHandle( NULL ), NULL, NULL, NULL, NULL, L"D3D Tutorial", NULL }; RegisterClassEx( &wc ); // Create the application's window HWND hWnd = CreateWindow( L"D3D Tutorial", L"D3D Tutorial 06: Meshes", WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, NULL, NULL, wc.hInstance, NULL ); // Initialize Direct3D if( SUCCEEDED( InitD3D( hWnd ) ) ) { // Create the scene geometry if( SUCCEEDED( InitGeometry() ) ) { // Show the window ShowWindow( hWnd, SW_SHOWDEFAULT ); UpdateWindow( hWnd ); // Enter the message loop MSG msg; ZeroMemory( &msg, sizeof( msg ) ); while( msg.message != WM_QUIT ) { if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } else { Render(); } } } } UnregisterClass( L"D3D Tutorial", wc.hInstance ); return 0; } Toon.fx //--------------------------- BASIC PROPERTIES ------------------------------ // The world transformation float4x4 World; // The view transformation float4x4 View; // The projection transformation float4x4 Projection; // The transpose of the inverse of the world transformation, // used for transforming the vertex's normal float4x4 WorldInverseTranspose; //--------------------------- DIFFUSE LIGHT PROPERTIES ------------------------------ // The direction of the diffuse light float3 DiffuseLightDirection = float3(1, 0, 0); // The color of the diffuse light float4 DiffuseColor = float4(1, 1, 1, 1); // The intensity of the diffuse light float DiffuseIntensity = 1.0; //--------------------------- TOON SHADER PROPERTIES ------------------------------ // The color to draw the lines in. Black is a good default. float4 LineColor = float4(0, 0, 0, 1); // The thickness of the lines. This may need to change, depending on the scale of // the objects you are drawing. float LineThickness = .03; //--------------------------- TEXTURE PROPERTIES ------------------------------ // The texture being used for the object texture Texture; // The texture sampler, which will get the texture color sampler2D textureSampler = sampler_state { Texture = (Texture); MinFilter = Linear; MagFilter = Linear; AddressU = Clamp; AddressV = Clamp; }; //--------------------------- DATA STRUCTURES ------------------------------ // The structure used to store information between the application and the // vertex shader struct AppToVertex { float4 Position : POSITION0; // The position of the vertex float3 Normal : NORMAL0; // The vertex's normal float2 TextureCoordinate : TEXCOORD0; // The texture coordinate of the vertex }; // The structure used to store information between the vertex shader and the // pixel shader struct VertexToPixel { float4 Position : POSITION0; float2 TextureCoordinate : TEXCOORD0; float3 Normal : TEXCOORD1; }; //--------------------------- SHADERS ------------------------------ // The vertex shader that does cel shading. // It really only does the basic transformation of the vertex location, // and normal, and copies the texture coordinate over. VertexToPixel CelVertexShader(AppToVertex input) { VertexToPixel output; // Transform the position float4 worldPosition = mul(input.Position, World); float4 viewPosition = mul(worldPosition, View); output.Position = mul(viewPosition, Projection); // Transform the normal output.Normal = normalize(mul(input.Normal, WorldInverseTranspose)); // Copy over the texture coordinate output.TextureCoordinate = input.TextureCoordinate; return output; } // The pixel shader that does cel shading. Basically, it calculates // the color like is should, and then it discretizes the color into // one of four colors. float4 CelPixelShader(VertexToPixel input) : COLOR0 { // Calculate diffuse light amount float intensity = dot(normalize(DiffuseLightDirection), input.Normal); if(intensity < 0) intensity = 0; // Calculate what would normally be the final color, including texturing and diffuse lighting float4 color = tex2D(textureSampler, input.TextureCoordinate) * DiffuseColor * DiffuseIntensity; color.a = 1; // Discretize the intensity, based on a few cutoff points if (intensity > 0.95) color = float4(1.0,1,1,1.0) * color; else if (intensity > 0.5) color = float4(0.7,0.7,0.7,1.0) * color; else if (intensity > 0.05) color = float4(0.35,0.35,0.35,1.0) * color; else color = float4(0.1,0.1,0.1,1.0) * color; return color; } // The vertex shader that does the outlines VertexToPixel OutlineVertexShader(AppToVertex input) { VertexToPixel output = (VertexToPixel)0; // Calculate where the vertex ought to be. This line is equivalent // to the transformations in the CelVertexShader. float4 original = mul(mul(mul(input.Position, World), View), Projection); // Calculates the normal of the vertex like it ought to be. float4 normal = mul(mul(mul(input.Normal, World), View), Projection); // Take the correct "original" location and translate the vertex a little // bit in the direction of the normal to draw a slightly expanded object. // Later, we will draw over most of this with the right color, except the expanded // part, which will leave the outline that we want. output.Position = original + (mul(LineThickness, normal)); return output; } // The pixel shader for the outline. It is pretty simple: draw everything with the // correct line color. float4 OutlinePixelShader(VertexToPixel input) : COLOR0 { return LineColor; } // The entire technique for doing toon shading technique Toon { // The first pass will go through and draw the back-facing triangles with the outline shader, // which will draw a slightly larger version of the model with the outline color. Later, the // model will get drawn normally, and draw over the top most of this, leaving only an outline. pass Pass1 { VertexShader = compile vs_1_1 OutlineVertexShader(); PixelShader = compile ps_2_0 OutlinePixelShader(); CullMode = CW; } // The second pass will draw the model like normal, but with the cel pixel shader, which will // color the model with certain colors, giving us the cel/toon effect that we are looking for. pass Pass2 { VertexShader = compile vs_1_1 CelVertexShader(); PixelShader = compile ps_2_0 CelPixelShader(); CullMode = CCW; } } Thanks in advance.
  4. I've solved it! You were right, it was just a case of setting the size of the vertices by declaring '_vertices.resize(_numVertices);' in my GenerateVertices method. I feel a bit silly but thanks for pointing out the obvious as I had been stuck on this for a day
  5. This is the actual error message which I think points to one of Visual Studio's include files. As for the Vectors, they are being allocated in this manner: vector<COLORED_TEXTURED_VERTEX> _vertices; vector<DWORD> _indices; The seperate variables used to calculate the total number of vertices, indicies, and number of cells in a row and column are declared and calculated in this way. The grid size is 256. DWORD _numVertices; DWORD _numTriangles; DWORD _gridSize; int _numCellRows; int _numCellCols; _gridSize =256; _numVertices = _gridSize * _gridSize; _numCellRows = _gridSize - 1; _numCellCols = _gridSize - 1; _numTriangles = _numCellRows * _numCellCols * 2; Then they are passed through two methods which generate the vertices and indices. void TerrainNode::GenerateVertices() { float width = (float)_numCellCols * _spacing; float depth = (float)_numCellRows * _spacing; float xOffset = -width * 0.5f; float zOffset = depth * 0.5f; float uIncrement = 1.0f / _numCellRows; float vIncrement = 1.0f / _numCellCols; // Set up the vertex array. For now, we set the y co-ordinate to 0 (we will adjust this when we // apply the height map int vertex = 0; for( float i = 0; i < _gridSize; ++i) { for (float j = 0; j < _gridSize; ++j) { _vertices[vertex].position.x = j * _spacing + xOffset; _vertices[vertex].position.z = -i * _spacing + zOffset; _vertices[vertex].position.y = 0.0f; _vertices[vertex].normal = D3DXVECTOR3(0.0f, 0.0f, 0.0f); _vertices[vertex].color = _colour; _vertices[vertex].tu = j * uIncrement; _vertices[vertex].tv = i * vIncrement; ++vertex; } } } void TerrainNode::GenerateIndices() { _indices.resize(_numTriangles * 3); int index = 0; for (DWORD i = 0; i< (DWORD)_numCellRows; ++i ) { for ( DWORD j = 0; j < (DWORD)_numCellCols; ++j ) { // First triangle _indices[index] = (i * _gridSize) + j; _indices[index + 1] = (i * _gridSize) + (j + 1); _indices[index + 2] = ((i+1) * _gridSize) + j; // Second triangle _indices[index + 3] = ((i+1) * _gridSize) + j; _indices[index + 4] = (i * _gridSize) + (j + 1); _indices[index + 5] = ((i+1) * _gridSize) + (j + 1); index += 6; } } }
  6. [font="Arial"]I am trying to to generate vertices and indices for a terrain grid and then add to their respective buffers before eventually using the DrawIndexedPrimitive method to draw the grid. However, when I debug the program I get an [/font]'Debug Assertion Failed' error message with the message 'Vector Subscript Out of Range - Line 932'. I have a feeling that there is a fault somewhere with my Vertex Buffer but can't figure what I am doing wrong. To provide more information about my code. I'm storing the verices in this struct: struct COLORED_TEXTURED_VERTEX { D3DXVECTOR3 position; // The position D3DXVECTOR3 normal; // The normal D3DCOLOR color; // The color FLOAT tu, tv; // The texture coordinates }; This is the method where I am creating and locking the vertex and index buffers: //pointer to vertex buffer if (FAILED(_renderDevice->CreateVertexBuffer(_numVertices * sizeof (COLORED_TEXTURED_VERTEX), 0,D3DFVF_COLORED_TEXTURED_VERTEX , D3DPOOL_MANAGED, &_pVB, 0))) { MessageBox(NULL, L"Failed to create the vertex buffer", L"TerrainNode::VertexBuffer", MB_OK); } //lock and write to vertex. COLORED_TEXTURED_VERTEX* v = 0; if (FAILED(_pVB->Lock(0,0,(void**)&v,0))) { MessageBox(NULL, L"Failed to lock the vertices",L"TerrainNode::VertexBuffer Locking", MB_OK); } for(DWORD i = 0; i < _numVertices; ++i) v = _vertices; _pVB->Unlock(); //pointer to a new index buffer if (FAILED(_renderDevice->CreateIndexBuffer(_numTriangles * 3 * sizeof(WORD),0, D3DFMT_INDEX32,D3DPOOL_MANAGED,&_pIB, 0))) { MessageBox(NULL, L"Failed to create the index buffer", L"TerrainNode::IndexBuffer", MB_OK); } //lock and write to index WORD* k = 0; if (FAILED(_pIB->Lock(0,0,(void**)&k,0))) { MessageBox(NULL,L"Failed to lock the indices",L"TerrainNode::IndexBuffer Locking", MB_OK); } for(DWORD i = 0; i < _numTriangles; ++i) k = (WORD)_indices; _pIB->Unlock(); Then this is the method I am using to try and render the grid. void TerrainNode::Render() { _renderDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME ); _renderDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ); _renderDevice->SetRenderState( D3DRS_LIGHTING, FALSE); _renderDevice->SetRenderState( D3DRS_ZENABLE, TRUE ); _renderDevice->SetStreamSource( 0, _pVB, 0, sizeof(COLORED_TEXTURED_VERTEX) ); _renderDevice->SetFVF( D3DFVF_COLORED_TEXTURED_VERTEX ); _renderDevice->SetIndices(_pIB); _renderDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, _numVertices, 0, _numTriangles); } Any help will be greatly appreciated!
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!