Basically when placed in the same file this works fine, but if placed in separate files (and I have tested this) just after Init() is called, the pointer to ID3D10* device's value is suddenly 0x00000000. If it's all in the same file, the device pointer has a memory address all the way through. I'm really stumped here. Also wasn't quite sure whether this was a gamedev or stackoverflow question so sorry if it's in the wrong place. SORRY IN ADVANCE FOR THE AMOUNT OF CODE!
file that makes the calls:
#include <d3d10.h>
#include <d3dx10.h>
#include "direct3D.h"
#include "game.h"
#include "cube.h"
Cube* cube1;
void test();
//called once
void Initialise(HWND hWnd)
{
initD3D(hWnd);
init_pipeline();
test();
//cube1->Init();
Init();
}
Direc3D.cpp
// include the basic windows header files and the Direct3D header files
#include <d3d10.h>
#include <d3dx10.h>
#include "direct3D.h"
#include "Globals.h"
// this function initializes and prepares Direct3D for use
void initD3D(HWND hWnd)
{
DXGI_SWAP_CHAIN_DESC scd;
ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));
scd.BufferCount = 1;
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
scd.BufferDesc.Width = SCREEN_WIDTH;
scd.BufferDesc.Height = SCREEN_HEIGHT;
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
scd.OutputWindow = hWnd;
scd.SampleDesc.Count = 1;
scd.SampleDesc.Quality = 0;
scd.Windowed = TRUE;
scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
// create a device class and swap chain class using the information in the scd struct
D3D10CreateDeviceAndSwapChain(NULL,
D3D10_DRIVER_TYPE_HARDWARE,
NULL,
0,
D3D10_SDK_VERSION,
&scd,
&swapchain,
&device);
// create a texture for the depth buffer
D3D10_TEXTURE2D_DESC zbd;
ZeroMemory(&zbd, sizeof(zbd));
zbd.Width = SCREEN_WIDTH; // set the width of the depth buffer
zbd.Height = SCREEN_HEIGHT; // set the height of the depth buffer
zbd.ArraySize = 1; // we are only creating one texture
zbd.SampleDesc.Count = 1; // no multi-sampling
zbd.Format = DXGI_FORMAT_D32_FLOAT; // one 32-bit float per pixel
zbd.BindFlags = D3D10_BIND_DEPTH_STENCIL; // texture is to be used as a depth buffer
ID3D10Texture2D* pDepthBuffer;
device->CreateTexture2D(&zbd, NULL, &pDepthBuffer); // create the texture
// create the depth buffer
D3D10_DEPTH_STENCIL_VIEW_DESC dsvd;
ZeroMemory(&dsvd, sizeof(dsvd));
dsvd.Format = DXGI_FORMAT_D32_FLOAT; // one 32-bit float per pixel
dsvd.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2D; // depth buffer is a 2D texture
device->CreateDepthStencilView(pDepthBuffer, &dsvd, &dsv); // create the depth buffer
pDepthBuffer->Release(); // release the texture once the depth buffer is made
// get the address of the back buffer and use it to create the render target
ID3D10Texture2D* pBackBuffer;
swapchain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)&pBackBuffer);
device->CreateRenderTargetView(pBackBuffer, NULL, &rtv);
pBackBuffer->Release();
// set the back buffer as the render target
device->OMSetRenderTargets(1, &rtv, dsv);
D3D10_VIEWPORT viewport; // create a struct to hold the viewport data
ZeroMemory(&viewport, sizeof(D3D10_VIEWPORT)); // clear out the struct for use
viewport.TopLeftX = 0; // set the left to 0
viewport.TopLeftY = 0; // set the top to 0
viewport.Width = SCREEN_WIDTH; // set the width to the window's width
viewport.Height = SCREEN_HEIGHT; // set the height to the window's height
viewport.MinDepth = 0; // the closest an object can be on the depth buffer is 0.0
viewport.MaxDepth = 1; // the farthest an object can be on the depth buffer is 1.0
device->RSSetViewports(1, &viewport); // set the viewport
}
// this is the function used to render a single frame
void render_frame()
{
// clear the window to a deep blue and clear the depth buffer to 1.0f
device->ClearRenderTargetView(rtv, D3DXCOLOR(0.0f, 0.2f, 0.4f, 1.0f));
device->ClearDepthStencilView(dsv, D3D10_CLEAR_DEPTH, 1.0f, 0);
// select which input layout we are using
device->IASetInputLayout(pVertexLayout);
// select which primtive type we are using
device->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// select which vertex buffer and index buffer to display
UINT stride = sizeof(VERTEX);
UINT offset = 0;
device->IASetVertexBuffers(0, 1, &pBuffer, &stride, &offset);
device->IASetIndexBuffer(iBuffer, DXGI_FORMAT_R32_UINT, 0);
D3DXMATRIX matRotate, matView, matProjection, matFinal;
// increase the time varaible and send to the effect
static float Time = 0.0f; Time += 0.001f;
// create a rotation matrix
D3DXMatrixRotationY(&matRotate, Time);
// create a view matrix
D3DXMatrixLookAtLH(&matView,
&D3DXVECTOR3(0.0f, 9.0f, 24.0f), // the camera position
&D3DXVECTOR3(0.0f, 0.0f, 0.0f), // the look-at position
&D3DXVECTOR3(0.0f, 1.0f, 0.0f)); // the up direction
// create a projection matrix
D3DXMatrixPerspectiveFovLH(&matProjection,
(float)D3DXToRadian(45), // the horizontal field of view
(FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT, // aspect ratio
1.0f, // the near view-plane
100.0f); // the far view-plane
// combine the matrices and render
matFinal = matRotate * matView * matProjection;
pTransform->SetMatrix(&matFinal._11);
pPass->Apply(0);
device->DrawIndexed(36, 0, 0);
// display the rendered frame
swapchain->Present(0, 0);
}
// this function sets up the pipeline for rendering
void init_pipeline()
{
// load the effect file
D3DX10CreateEffectFromFile(L"effect.fx", 0, 0,
"fx_4_0", 0, 0,
device, 0, 0,
&pEffect, 0, 0);
// get the technique and the pass
pTechnique = pEffect->GetTechniqueByIndex(0);
pPass = pTechnique->GetPassByIndex(0);
pPass->GetDesc(&PassDesc);
// get the Transform effect variable
pTransform = pEffect->GetVariableByName("Transform")->AsMatrix();
// create the input element descriptions
D3D10_INPUT_ELEMENT_DESC Layout[] =
{
// first input element: position
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D10_APPEND_ALIGNED_ELEMENT,
D3D10_INPUT_PER_VERTEX_DATA, 0},
// second input element: color
{"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D10_APPEND_ALIGNED_ELEMENT,
D3D10_INPUT_PER_VERTEX_DATA, 0}
};
// use the input element descriptions to create the input layout
device->CreateInputLayout(Layout,
2,
PassDesc.pIAInputSignature,
PassDesc.IAInputSignatureSize,
&pVertexLayout);
}
// this is the function that cleans up Direct3D and COM
void cleanD3D()
{
swapchain->SetFullscreenState(FALSE, NULL); // switch to windowed mode
//pBuffer->Release(); // close and release the vertex buffer
pVertexLayout->Release(); // close and release the input layout object
swapchain->Release(); // close and release the swap chain
rtv->Release(); // close and release the render target view
device->Release(); // close and release the 3D device
}
void Init()
{
// create eight vertices to represent the corners of the cube
VERTEX OurVertices[] =
{
{D3DXVECTOR3(-1.0f, 1.0f, -1.0f), D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)},
{D3DXVECTOR3(1.0f, 1.0f, -1.0f), D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)},
{D3DXVECTOR3(-1.0f, -1.0f, -1.0f), D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)},
{D3DXVECTOR3(1.0f, -1.0f, -1.0f), D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)},
{D3DXVECTOR3(-1.0f, 1.0f, 1.0f), D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)},
{D3DXVECTOR3(1.0f, 1.0f, 1.0f), D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)},
{D3DXVECTOR3(-1.0f, -1.0f, 1.0f), D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)},
{D3DXVECTOR3(1.0f, -1.0f, 1.0f), D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)},
};
// create the vertex buffer
D3D10_BUFFER_DESC bd;
bd.Usage = D3D10_USAGE_DYNAMIC;
bd.ByteWidth = sizeof(VERTEX) * 8;
bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
bd.MiscFlags = 0;
device->CreateBuffer(&bd, NULL, &pBuffer);
void* pVoid; // the void pointer
pBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &pVoid); // map the vertex buffer
memcpy(pVoid, OurVertices, sizeof(OurVertices)); // copy the vertices to the buffer
pBuffer->Unmap();
// create the index buffer out of DWORDs
DWORD OurIndices[] =
{
0, 1, 2, // side 1
2, 1, 3,
4, 0, 6, // side 2
6, 0, 2,
7, 5, 6, // side 3
6, 5, 4,
3, 1, 7, // side 4
7, 1, 5,
4, 5, 0, // side 5
0, 5, 1,
3, 7, 2, // side 6
2, 7, 6,
};
// create the index buffer
// D3D10_BUFFER_DESC bd; // redefinition
bd.Usage = D3D10_USAGE_DYNAMIC;
bd.ByteWidth = sizeof(DWORD) * 36;
bd.BindFlags = D3D10_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
bd.MiscFlags = 0;
device->CreateBuffer(&bd, NULL, &iBuffer);
// void* pVoid; // redefinition
iBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &pVoid); // map the index buffer
memcpy(pVoid, OurIndices, sizeof(OurIndices)); // copy the indices to the buffer
iBuffer->Unmap();
}
Direct3D.h
#ifndef DIRECT3D_H
#define DIRECT3D_H
// global declarations
static ID3D10Device* device;
static ID3D10Buffer* pBuffer;
static ID3D10Buffer* iBuffer; // the pointer to the index buffer
static ID3D10RenderTargetView* rtv; // the pointer to the render target view
static ID3D10DepthStencilView* dsv; // the pointer to the depth stencil view
static IDXGISwapChain* swapchain; // the pointer to the swap chain class
static ID3D10Effect* pEffect;
static ID3D10EffectTechnique* pTechnique;
static ID3D10EffectPass* pPass;
static ID3D10InputLayout* pVertexLayout;
static ID3D10EffectMatrixVariable* pTransform; // the pointer to the effect variable interface
static D3D10_PASS_DESC PassDesc;
// function prototypes
void initD3D(HWND hWnd);
void render_frame();
void init_pipeline();
void cleanD3D();
void Init();
#endif
cube.cpp
#include "cube.h"
#include "globals.h"
#include "Direct3D.h"
// include the Direct3D Library file
#pragma comment (lib, "d3d10.lib")
#pragma comment (lib, "d3dx10.lib")
Cube::Cube() : GameObject()
{
}
Cube::~Cube()
{
pBuffer->Release(); // why does this only work when put here? because it's created here? I thnk so, why not iBuffer though?
}
void Cube::Draw()
{
render_frame();
}
void Cube::Init()
{
// create eight vertices to represent the corners of the cube
VERTEX OurVertices[] =
{
{D3DXVECTOR3(-1.0f, 1.0f, -1.0f), D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)},
{D3DXVECTOR3(1.0f, 1.0f, -1.0f), D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)},
{D3DXVECTOR3(-1.0f, -1.0f, -1.0f), D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)},
{D3DXVECTOR3(1.0f, -1.0f, -1.0f), D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)},
{D3DXVECTOR3(-1.0f, 1.0f, 1.0f), D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)},
{D3DXVECTOR3(1.0f, 1.0f, 1.0f), D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)},
{D3DXVECTOR3(-1.0f, -1.0f, 1.0f), D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)},
{D3DXVECTOR3(1.0f, -1.0f, 1.0f), D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)},
};
// create the vertex buffer
D3D10_BUFFER_DESC bd;
bd.Usage = D3D10_USAGE_DYNAMIC;
bd.ByteWidth = sizeof(VERTEX) * 8;
bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
bd.MiscFlags = 0;
device->CreateBuffer(&bd, NULL, &pBuffer);
void* pVoid; // the void pointer
pBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &pVoid); // map the vertex buffer
memcpy(pVoid, OurVertices, sizeof(OurVertices)); // copy the vertices to the buffer
pBuffer->Unmap();
// create the index buffer out of DWORDs
DWORD OurIndices[] =
{
0, 1, 2, // side 1
2, 1, 3,
4, 0, 6, // side 2
6, 0, 2,
7, 5, 6, // side 3
6, 5, 4,
3, 1, 7, // side 4
7, 1, 5,
4, 5, 0, // side 5
0, 5, 1,
3, 7, 2, // side 6
2, 7, 6,
};
// create the index buffer
// D3D10_BUFFER_DESC bd; // redefinition
bd.Usage = D3D10_USAGE_DYNAMIC;
bd.ByteWidth = sizeof(DWORD) * 36;
bd.BindFlags = D3D10_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
bd.MiscFlags = 0;
device->CreateBuffer(&bd, NULL, &iBuffer);
// void* pVoid; // redefinition
iBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &pVoid); // map the index buffer
memcpy(pVoid, OurIndices, sizeof(OurIndices)); // copy the indices to the buffer
iBuffer->Unmap();
}
cube.h
#ifndef CUBE_H
#define CUBE_H
#include "gameObject.h"
class Cube : GameObject
{
private:
//VERTEX* OurVertices;
public:
Cube();
~Cube();
void Draw();
void Init();
};
#endif
If I call Init() from game.cpp, the code works fine, if I call cube->init(), just as this function is entered (not when the other one is left), the device pointer suddenly has an address of 0x00000000. Thanks in advance for any help you can give.
Both functions are identical - copy pasted.