Jump to content
  • Advertisement
Sign in to follow this  
Hawkblood

#ifndef not working

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

Ok. I have decided to try my hand at DX11. I'm starting from scratch here because the "empty project" provided by the SDK has a butt-load of crap that I don't want to use right now (just want to learn the basics). Until now I've been using only one .cpp file and all others were .h files. Each class had 2 .h files, one for the header info and the other for the functions. I know this is bad practice, but it was the only way I could control the compile order. I WANT TO CORRECT THIS! So here is my project as it stands:

Main.cpp:

 

 

globals.h:

#ifndef GLOBALS_H
#define GLOBALS_H
#include <windows.h>  
#include <windowsx.h>

void Init3D(HWND hWnd);
void GameLoop(void);
void RenderFrame(void);
void ExitProgram(void);


float SCREEN_WIDTH =float(GetSystemMetrics( SM_CXSCREEN ));
float SCREEN_HEIGHT = float(GetSystemMetrics( SM_CYSCREEN ));


#include "Graphics.h"

#endif


Graphics.h:

#include <d3d11.h>
#include <d3dx11.h>
#include <d3dx10.h>
#pragma comment (lib, "C:/Program Files (x86)/Microsoft DirectX SDK (June 2010)/Lib/x86/d3d11.lib")
#pragma comment (lib, "C:/Program Files (x86)/Microsoft DirectX SDK (June 2010)/Lib/x86/d3dx11.lib")
#pragma comment (lib, "C:/Program Files (x86)/Microsoft DirectX SDK (June 2010)/Lib/x86/d3dx10.lib")

IDXGISwapChain *swapchain;             // the pointer to the swap chain interface
ID3D11Device *dev;                     // the pointer to our Direct3D device interface
ID3D11DeviceContext *devcon;           // the pointer to our Direct3D device context

void InitD3D(HWND hWnd);     // sets up and initializes Direct3D
void CleanD3D(void);         // closes Direct3D and releases memory


Graphics.cpp:

#include "globals.h"

void InitD3D(HWND hWnd)
{
    // create a struct to hold information about the swap chain
    DXGI_SWAP_CHAIN_DESC scd;

    // clear out the struct for use
    ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));

    // fill the swap chain description struct
    scd.BufferCount = 1;                                    // one back buffer
    scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;     // use 32-bit color
    scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;      // how swap chain is to be used
    scd.OutputWindow = hWnd;                                // the window to be used
    scd.SampleDesc.Count = 4;                               // how many multisamples
    scd.Windowed = TRUE;                                    // windowed/full-screen mode

    // create a device, device context and swap chain using the information in the scd struct
    D3D11CreateDeviceAndSwapChain(NULL,
                                  D3D_DRIVER_TYPE_HARDWARE,
                                  NULL,
                                  NULL,
                                  NULL,
                                  NULL,
                                  D3D11_SDK_VERSION,
                                  &scd,
                                  &swapchain,
                                  &dev,
                                  NULL,
                                  &devcon);
}
void CleanD3D()
{
    // close and release all existing COM objects
    swapchain->Release();
    dev->Release();
    devcon->Release();
}

The problem is that the compiler says that the stuff in globals.h is already defined:

Error	1	error LNK2005: "float SCREEN_WIDTH" (?SCREEN_WIDTH@@3MA) already defined in Grapgics.obj	C:\Empty DX11 Project1\main.obj	Empty DX11 Project1
Error	2	error LNK2005: "struct ID3D11DeviceContext * devcon" (?devcon@@3PAUID3D11DeviceContext@@A) already defined in Grapgics.obj	C:\Empty DX11 Project1\main.obj	Empty DX11 Project1
Error	3	error LNK2005: "struct ID3D11Device * dev" (?dev@@3PAUID3D11Device@@A) already defined in Grapgics.obj	C:\Empty DX11 Project1\main.obj	Empty DX11 Project1
Error	4	error LNK2005: "struct IDXGISwapChain * swapchain" (?swapchain@@3PAUIDXGISwapChain@@A) already defined in Grapgics.obj	C:\Empty DX11 Project1\main.obj	Empty DX11 Project1
Error	5	error LNK2005: "float SCREEN_HEIGHT" (?SCREEN_HEIGHT@@3MA) already defined in Grapgics.obj	C:\Empty DX11 Project1\main.obj	Empty DX11 Project1
Error	6	error LNK1169: one or more multiply defined symbols found	C:\Empty DX11 Project1\Release\DX11Test.exe	Empty DX11 Project1

Doesn't the "#ifndef" stuff work? Am I using it wrong? HOW DO I GET IT TO "DEFINE" ONLY ONCE?




			
				


	Edited  by Hawkblood
	
	

			
		

Share this post


Link to post
Share on other sites
Advertisement

I can't seem to get main.cpp to copy onto the post. Here is another attempt:

#include "globals.h"
LRESULT WINAPI WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);  
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpCmdLine,int nShow)
{
	MSG msg;
	WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_VREDRAW|CS_HREDRAW|CS_OWNDC, 
		WndProc, 0, 0, hInstance, NULL, NULL, (HBRUSH)(COLOR_WINDOW+1), 
		NULL, "DX11_CLASS", NULL}; 
	RegisterClassEx(&wc);
	HWND hMainWnd = CreateWindow("DX11_CLASS", 
		"DirectX 11 Bare Bones", 
		WS_EX_TOPMOST | WS_POPUP, 0, 0, int(SCREEN_WIDTH), int(SCREEN_HEIGHT), 
		NULL, NULL, hInstance, NULL);
	ShowWindow(hMainWnd, nShow);
	UpdateWindow(hMainWnd);
	Init3D(hMainWnd);
	while(GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	ExitProgram();
	return(0);
} 

LRESULT WINAPI WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
	switch(msg)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		return(0);

	case WM_PAINT: // <— ADD THIS BLOCK
		// drawing code goes here…
		GameLoop();
		ValidateRect(hwnd, NULL);
		return(0);

	case WM_CHAR:

		switch(wParam){
			case VK_ESCAPE:
				PostMessage(hwnd,WM_QUIT,0,0);
				break;
		}
		break;

	}

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

void Init3D(HWND hWnd){
//will be calling Graphics class to initialize 
}
void GameLoop(void){
	//check DX device
	//frame move
	//render
	RenderFrame();
}
void RenderFrame(void){
}
void ExitProgram(void){
// call Graphics class to clear device objects
}

I HAD TO BREAK IT UP IN CHUNKS FOR IT TO SHOW ON THE POST. WTF!

?

?

?

 

 

 

?

Edited by Hawkblood

Share this post


Link to post
Share on other sites

Ok. I declared them in globals.h and defined them in Graphics.cpp within void Init3D(HWND hWnd)

I get this:

Error	1	error LNK2005: "float SCREEN_WIDTH" (?SCREEN_WIDTH@@3MA) already defined in Grapgics.obj	C:\Empty DX11 Project1\main.obj	Empty DX11 Project1
Error	2	error LNK2005: "struct ID3D11DeviceContext * devcon" (?devcon@@3PAUID3D11DeviceContext@@A) already defined in Grapgics.obj	C:\Empty DX11 Project1\main.obj	Empty DX11 Project1
Error	3	error LNK2005: "struct ID3D11Device * dev" (?dev@@3PAUID3D11Device@@A) already defined in Grapgics.obj	C:\Empty DX11 Project1\main.obj	Empty DX11 Project1
Error	4	error LNK2005: "float SCREEN_HEIGHT" (?SCREEN_HEIGHT@@3MA) already defined in Grapgics.obj	C:\Empty DX11 Project1\main.obj	Empty DX11 Project1
Error	5	error LNK2005: "struct IDXGISwapChain * swapchain" (?swapchain@@3PAUIDXGISwapChain@@A) already defined in Grapgics.obj	C:\Empty DX11 Project1\main.obj	Empty DX11 Project1
Error	6	error LNK1169: one or more multiply defined symbols found	C:\Empty DX11 Project1\Release\DX11Test.exe	Empty DX11 Project1

Which, to me, looks the same....... Also, I can't find the article you linked me to. The link just goes to a list of articles. I searched through them and didn't find the one you were pointing me to.

Share this post


Link to post
Share on other sites
Sorry, had some issues with the editor, the link should be fixed now. Can we see your current code?

Share this post


Link to post
Share on other sites

Use headers for declarations only and define in source files.

 

Declare this way:

// Keyword "extern" basically means "declare something that's defined somewhere else".
extern float SCREEN_WIDTH;
extern float SCREEN_HEIGHT;

extern IDXGISwapChain *swapchain;
extern ID3D11Device *dev;
extern ID3D11DeviceContext *devcon;

Define this way:

float SCREEN_WIDTH = float(GetSystemMetrics(SM_CXSCREEN));
float SCREEN_HEIGHT = float(GetSystemMetrics(SM_CYSCREEN));

// Always initialize your variables, in this case a pointer to null.
IDXGISwapChain *swapchain = nullptr;
ID3D11Device *dev = nullptr;
ID3D11DeviceContext *devcon = nullptr;

Also, you forgot a header guard in the "Graphics.h".

Edited by Guns

Share this post


Link to post
Share on other sites

I hope I corrected the issues with "main.cpp" that kept me from posting the code. Here is the attempt:

main.cpp:

#include "stdafx.h"
#include "globals.h"

LRESULT WINAPI WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);  
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpCmdLine,int nShow)
{
	MSG msg;
	WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_VREDRAW|CS_HREDRAW|CS_OWNDC, 
		WndProc, 0, 0, hInstance, NULL, NULL, (HBRUSH)(COLOR_WINDOW+1), 
		NULL, "DX11_CLASS", NULL}; 
	RegisterClassEx(&wc);
	HWND hMainWnd = CreateWindow("DX11_CLASS", 
		"DirectX 11 Bare Bones", 
		WS_EX_TOPMOST | WS_POPUP, 0, 0, int(SCREEN_WIDTH), int(SCREEN_HEIGHT), 
		NULL, NULL, hInstance, NULL);
	ShowWindow(hMainWnd, nShow);
	UpdateWindow(hMainWnd);
	Init3D(hMainWnd);
	while(GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	ExitProgram();
	return(0);
} 
LRESULT WINAPI WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
	switch(msg)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		return(0);
	case WM_PAINT: // <— ADD THIS BLOCK
		// drawing code goes here…
		GameLoop();
		ValidateRect(hwnd, NULL);
		return(0);
	case WM_CHAR:
		switch(wParam){
			case VK_ESCAPE:
				PostMessage(hwnd,WM_QUIT,0,0);
				break;
		}
		break;
	}

	return(DefWindowProc(hwnd, msg, wParam, lParam));
}
void Init3D(HWND hWnd){
//will be calling Graphics class to initialize 
	Graphics.InitD3D(hWnd,SCREEN_WIDTH,SCREEN_HEIGHT);
}
void GameLoop(void){
	//check DX device
	//frame move
	//render
	RenderFrame();
}
void RenderFrame(void){
	Graphics.devcon->ClearRenderTargetView(Graphics.backbuffer, D3DXCOLOR(0.0f, 0.2f, 0.4f, 1.0f));



	Graphics.swapchain->Present(0, 0);
}
void ExitProgram(void){
// call Graphics class to clear device objects
	Graphics.CleanD3D();
}

stdafx.h:

#include <windows.h>  
#include <windowsx.h>

void Init3D(HWND hWnd);
void GameLoop(void);
void RenderFrame(void);
void ExitProgram(void);


#include "Graphics.h"

Graphics.h:

#include <d3d11.h>
#include <d3dx11.h>
#include <d3dx10.h>
#pragma comment (lib, "C:/Program Files (x86)/Microsoft DirectX SDK (June 2010)/Lib/x86/d3d11.lib")
#pragma comment (lib, "C:/Program Files (x86)/Microsoft DirectX SDK (June 2010)/Lib/x86/d3dx11.lib")
#pragma comment (lib, "C:/Program Files (x86)/Microsoft DirectX SDK (June 2010)/Lib/x86/d3dx10.lib")

struct GRAPHICS{
	IDXGISwapChain *swapchain;             // the pointer to the swap chain interface
	ID3D11Device *dev;                     // the pointer to our Direct3D device interface
	ID3D11DeviceContext *devcon;           // the pointer to our Direct3D device context

	ID3D11RenderTargetView *backbuffer;


	void InitD3D(HWND hWnd,float SW,float SH);     // sets up and initializes Direct3D
	void CleanD3D(void);         // closes Direct3D and releases memory
};

Graphics.cpp:

#include "stdafx.h"


void GRAPHICS::InitD3D(HWND hWnd,float SW,float SH)
{
    // create a struct to hold information about the swap chain
    DXGI_SWAP_CHAIN_DESC scd;

    // clear out the struct for use
    ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));

    // fill the swap chain description struct
    scd.BufferCount = 1;                                    // one back buffer
    scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;     // use 32-bit color
    scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;      // how swap chain is to be used
    scd.OutputWindow = hWnd;                                // the window to be used
    scd.SampleDesc.Count = 4;                               // how many multisamples
    scd.Windowed = TRUE;                                    // windowed/full-screen mode

    // create a device, device context and swap chain using the information in the scd struct
    D3D11CreateDeviceAndSwapChain(NULL,
                                  D3D_DRIVER_TYPE_HARDWARE,
                                  NULL,
                                  NULL,
                                  NULL,
                                  NULL,
                                  D3D11_SDK_VERSION,
                                  &scd,
                                  &swapchain,
                                  &dev,
                                  NULL,
                                  &devcon);

	// get the address of the back buffer
	ID3D11Texture2D *pBackBuffer;
	swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
	// use the back buffer address to create the render target
	dev->CreateRenderTargetView(pBackBuffer, NULL, &backbuffer);
	pBackBuffer->Release();
	// set the render target as the back buffer
	devcon->OMSetRenderTargets(1, &backbuffer, NULL);

	D3D11_VIEWPORT viewport;
	ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
	viewport.TopLeftX = 0;
	viewport.TopLeftY = 0;
	viewport.Width = SW;
	viewport.Height = SH;
	devcon->RSSetViewports(1, &viewport);

}
void GRAPHICS::CleanD3D()
{
    // close and release all existing COM objects
    swapchain->Release();
	backbuffer->Release();
    dev->Release();
    devcon->Release();
}

globals.h:

#include <windows.h>  
#include <windowsx.h>

float SCREEN_WIDTH =float(GetSystemMetrics( SM_CXSCREEN ));
float SCREEN_HEIGHT = float(GetSystemMetrics( SM_CYSCREEN ));

GRAPHICS Graphics;

I modified the project so that I wouldn't get the errors. Now my concern is "how will this screw up my project?"

Edited by Hawkblood

Share this post


Link to post
Share on other sites
You'd need to amend globals.h to be like so:
#include <windows.h>  
#include <windowsx.h>

extern float SCREEN_WIDTH;
extern float SCREEN_HEIGHT;

extern GRAPHICS Graphics;
And to add a globals.cpp (or to another file such as main.cpp):
#include "globals.h"

float SCREEN_WIDTH = float(GetSystemMetrics( SM_CXSCREEN ));
float SCREEN_HEIGHT = float(GetSystemMetrics( SM_CYSCREEN ));

GRAPHICS Graphics;
You'll probably need to #include "graphics.h" in globals.h too.

Share this post


Link to post
Share on other sites

First, I would recommend that you NOT declare functions in stdafx.h. Any time you change anything in stdafx.h, you'll likely have to recompile the entire project.

 

I.e., these forward declarations belong in a header (e.g., main.h - which you don't appear to have) for main.cpp, where those functions are defined.

void Init3D(HWND hWnd);
void GameLoop(void);
void RenderFrame(void);
void ExitProgram(void);

If, for instance, you just want to add an exit code and change ExitProgram(void) to ExitProgram(int returnCode), you'll have to recompile every cpp file that includes stdafx.h, whether ExitProgram is called in that cpp file or not.

 

In general, header files describe what can be found in an associated code file. E.g., graphics.h describes what can be found in graphics.cpp; commonStuff.h would describe what's in commonStuff.cpp, etc.

Edited by Buckeye

Share this post


Link to post
Share on other sites


First, I would recommend that you NOT declare functions in stdafx.h. Any time you change anything in stdafx.h, you'll likely have to recompile the entire project.

That's not a real concern right now, but I moved them to main.cpp anyway....

 

@rip-off

I tried that. I got lots of errors. So far the only place I need any kind of global variables is in main.cpp, so I made a "main.h" and placed all those variables and function definitions in that.

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.

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!