the experts can't agree on anything :(

  • (2 Pages)
  • +
  • 1
  • 2

24 Replies - 4256 Views - Last Post: 04 November 2015 - 08:25 AM Rate Topic: -----

#1 herc65   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 11
  • Joined: 01-November 15

the experts can't agree on anything :(

Posted 01 November 2015 - 09:27 PM

I looked into learning C by reading some 2015 online articles about it and the comments on those articles made by active developers. After only about three hours of doing that I've reached the inescapable conclusion that nobody agrees on anything when it comes to C. At one extreme, some developers think C is the gold standard for "bare-metal" programming; at the other extreme, people want to stop C being used at all because it's supposedly a security sieve. Some developers swear by high-level languages such as Java and C++ while others plug relatively underused alternatives to C such as Ada and Haskell.

My initial training in programming was Python (and nobody can agree whether learning Python as your first language is a wonderful thing or a horrible thing or something in between). My initial examination of C makes me think that it's different from Python only in its subtleties; I have yet to get into material that helps me figure out what people mean by "bare-metal" and how C and assembly language are supposedly twin siblings. I also have no idea whether, as some people assert, it's impossible to write secure code in C or, as others assert, it's simply a matter of good programming practice rather than sloppiness. And then there's the question of whether, as some people assert, C is good only for coding embedded systems and device drivers, or, as others assert, you can create ANY application in C and have it work just as well as something in a higher-level language.

Can someone help me sort out a newcomer's confusion?

Is This A Good Question/Topic? 0
  • +

Replies To: the experts can't agree on anything :(

#2 modi123_1   User is online

  • Suitor #2
  • member icon



Reputation: 15357
  • View blog
  • Posts: 61,571
  • Joined: 12-June 08

Re: the experts can't agree on anything :(

Posted 01 November 2015 - 10:27 PM

Quote

I have yet to get into material that helps me figure out what people mean by "bare-metal" and how C and assembly language are supposedly twin siblings.


The wiki pages are pretty clear 'why'.

Quote

By design, C provides constructs that map efficiently to typical machine instructions, and therefore it has found lasting use in applications that had formerly been coded in assembly language, including operating systems, as well as various application software for computers ranging from supercomputers to embedded systems.

https://en.wikipedia...ing_language%29


Quote

An assembly language (or assembler language[1]) is a low-level programming language for a computer, or other programmable device, in which there is a very strong (generally one-to-one) correspondence between the language and the architecture's machine code instructions.

https://en.wikipedia...sembly_language

They both have near one-to-one mapping to machine instruction.


Quote

I also have no idea whether, as some people assert, it's impossible to write secure code in C or, as others assert, it's simply a matter of good programming practice rather than sloppiness.


That can be said for many programming languages.

Specific examples:
http://www.cprogramm...ial/secure.html
https://www.sans.org...programming-388

Quote

And then there's the question of whether, as some people assert, C is good only for coding embedded systems and device drivers, or, as others assert, you can create ANY application in C and have it work just as well as something in a higher-level language.

Both are right to various degrees.
Was This Post Helpful? 2
  • +
  • -

#3 jjl   User is offline

  • Engineer
  • member icon

Reputation: 1271
  • View blog
  • Posts: 4,998
  • Joined: 09-June 09

Re: the experts can't agree on anything :(

Posted 01 November 2015 - 10:54 PM

It basically comes down to this

People who like fluff vs people that dont

Fluff in this case being pre-canned tools, abstractions, OOP, etc..

People who write C code typically write all of their own tools, giving them great control over their software. No body is right in this argument, all code boils down to machine level instructions in the end. C however is closer to that translation, which is where the team "bare metal" programming comes into play.

For all those Java guys that say that C is obsolute, remind them that their precious JVMs are written in C/C++ ;)/>

This same grudge match happened years and years ago when C was introduced, but rather than Java, Python, etc.. VS C, it was assembly, fortran VS C.

C is typically the language of choice in embedded systems and/or microcontroller development due to it being closer to the hardware and having a small binary size (microcontrollers have limited memory), however compilers for other languages are getting better and better.

This post has been edited by jjl: 01 November 2015 - 10:59 PM

Was This Post Helpful? 1
  • +
  • -

#4 jon.kiparsky   User is offline

  • Beginner
  • member icon


Reputation: 11688
  • View blog
  • Posts: 19,858
  • Joined: 19-March 11

Re: the experts can't agree on anything :(

Posted 01 November 2015 - 11:41 PM

Quote

At one extreme, some developers think C is the gold standard for "bare-metal" programming; at the other extreme, people want to stop C being used at all because it's supposedly a security sieve.


There's no real disagreement here. If C is what you need, then yes, you should use it. On the other hand, for most applications you want a high-level language which provides better application security. If I'm writing web code, I have no need to address machine memory directly, and managing memory by hand is a huge cost in time - not to mention, it's really easy to screw it up, and I want to spend my time developing more features and not ensuring that I've seen to each and every possible memory leak and security hole. Basically, high-level languages make it easier to develop more features in less time with better security. If you can use them, you should use them. On the other hand, if what you want to do requires low-level access to the machine then you roll up your sleeves and do it the hard way.

Quote

And then there's the question of whether, as some people assert, C is good only for coding embedded systems and device drivers, or, as others assert, you can create ANY application in C and have it work just as well as something in a higher-level language.


You CAN, yes. The question is, do you want to? In most cases, you're going to have to develop so many bits and pieces that already exist in some other language, you might as well just go ahead and use one of those languages.

Quote

My initial examination of C makes me think that it's different from Python only in its subtleties


Well, no. Python has as primitives some rather advanced data structures - lists, dictionaries, and sets come built in. Python has the ability to be object-oriented, and C cannot. Python also has first-class functions, which C does not. Python's loops loop over elements, where C's loops loop over indices.
All of these things can be written in C (as they were, for example, to implement python) but they're not part of C until you add them.

Quote

I have yet to get into material that helps me figure out what people mean by "bare-metal" and how C and assembly language are supposedly twin siblings


"Bare-metal" essentially means that C can address memory directly, which high-level languages (by definition) cannot do. As already observed, C is basically a thinly-veiled abstraction layer for assembly language.

I would suggest you spend a little time learning to write C - for example, using Zeb Shaw's "Learn C the Hard Way". This will probably help you greatly in unravelling your confusion.
Was This Post Helpful? 4
  • +
  • -

#5 jjl   User is offline

  • Engineer
  • member icon

Reputation: 1271
  • View blog
  • Posts: 4,998
  • Joined: 09-June 09

Re: the experts can't agree on anything :(

Posted 01 November 2015 - 11:56 PM

Quote

You CAN, yes. The question is, do you want to? In most cases, you're going to have to develop so many bits and pieces that already exist in some other language, you might as well just go ahead and use one of those languages.


Because it give you job security ;)
Was This Post Helpful? 0
  • +
  • -

#6 CTphpnwb   User is online

  • D.I.C Lover
  • member icon

Reputation: 3825
  • View blog
  • Posts: 13,941
  • Joined: 08-August 08

Re: the experts can't agree on anything :(

Posted 02 November 2015 - 05:43 AM

Remember that while C provides you with low level access, that access means that when you screw up, you can easily screw up in a big way. Higher level languages manage memory for you, so there are generally fewer memory leaks and buffer over runs, both of which can be security issues. Of course, even high level languages in the wrong hands can be security nightmares (search on SQL injection for example), so you always need to be vigilant. Just more so with C.
Was This Post Helpful? 1
  • +
  • -

#7 jon.kiparsky   User is offline

  • Beginner
  • member icon


Reputation: 11688
  • View blog
  • Posts: 19,858
  • Joined: 19-March 11

Re: the experts can't agree on anything :(

Posted 02 November 2015 - 08:38 AM

View PostCTphpnwb, on 02 November 2015 - 07:43 AM, said:

Of course, even high level languages in the wrong hands can be security nightmares (search on SQL injection for example), so you always need to be vigilant


It's worth pointing out, in passing, that "high-level" does not mean "better" or anything of that sort. For example, PHP and ML are both high-level languages which are both almost completely useless. It's a technical term which refers to the degree to which a program written in a language is abstracted from the actual machine it runs on. That level of abstraction for C is almost non-existent, whereas for high-level languages, it's very complete.
Was This Post Helpful? 0
  • +
  • -

#8 herc65   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 11
  • Joined: 01-November 15

Re: the experts can't agree on anything :(

Posted 02 November 2015 - 10:21 AM

One person in this thread brought up the "reinventing the wheel" issue I've seen mentioned elsewhere--how you can code anything at all in C, even graphics-intensive applications, as long as you don't mind creating a whole bunch of your own libraries. I guess people coding in C for an employer or client could find that problematic because of how much resources it would chew up, but wouldn't it be nice to have total control over your own software, if you could have it? Even using cpp for compiling you give up some control.

By the way, is _C for Python Programmers_ a good C newb book? (I know there are C tutorials on this website.)
Was This Post Helpful? 0
  • +
  • -

#9 jon.kiparsky   User is offline

  • Beginner
  • member icon


Reputation: 11688
  • View blog
  • Posts: 19,858
  • Joined: 19-March 11

Re: the experts can't agree on anything :(

Posted 02 November 2015 - 11:03 AM

View Postherc65, on 02 November 2015 - 12:21 PM, said:

wouldn't it be nice to have total control over your own software, if you could have it?


Control implies responsibility. I would rather delegate responsibility for the things which are not my core concern. Unless you're selling a CMS, you don't want to be maintaining a CMS.
Was This Post Helpful? 1
  • +
  • -

#10 BBeck   User is offline

  • Here to help.
  • member icon


Reputation: 792
  • View blog
  • Posts: 1,886
  • Joined: 24-April 12

Re: the experts can't agree on anything :(

Posted 02 November 2015 - 11:05 AM

*
POPULAR

Welcome to the wonderful world of programming where we can't agree on anything except maybe to disagree! You eventually learn to ignore everyone else and do what you want to do which means you'll eventually likely fall into one camp or the other.

I like C++ better than C. C is what I was taught in college. I'm not really dead set against it, but after I learned C# and got very comfortable with OOP, I have no desire to go back and don't really see any worth while advantage in doing so. But there might be some places where C++ is not an option or where the minor overhead of OOP is a problem because the entire system only has 64 K of memory. In the future, as hardware becomes more powerful, I would expect even that becomes less of an issue.

But C++ is basically the same thing as C. It's just C with OOP. I know it's a different standard, but at the end of the day it's still basically just C with OOP.

C++ is every bit as close to the metal as C although there's a little overhead for objects.

The only time you're really at the metal is with machine code and Assembly. The only way to get deeper than machine code is with a soldering iron. You are basically at the electronic level with machine code. You are literally flipping the switches in the guts of the computer to make the magic happen. It helps a lot here if you are familiar with machine code and Assembler.

Machine code looks basically like this:

0004 0012
0012 0001 
0007 0100



This is "pseudo code" which means it's an example and not actual machine code and I totally made up these numbers rather than digging in to the documents that Intel publishes with the actual codes. Not to mention that machine code can probably more accurately be thought of as binary numbers rather than these decimal numbers we prefer to look at. But this gives you the idea.

But the first value might be an instruction with the number that follows being a value or parameter. For this example, 0004 might mean "Put the value that comes next into the AX register". (It helps here if you know what a register is, but it's basically a picoscopic piece of memory deep inside the CPU.) So, the first instruction places the value 12 in the AX register.

Then the second line may have the code 0012 mean to add the value that comes next to whatever is currently in the AX register. So, it would add 1 to the 12 currently in the AX register.

The final line might mean that code value 0007 tells the CPU to put whatever value is in the AX register into the memory address that follows which in this case is 0100. So, if you look in the memory location 0100 you will find the value 13 after this "program" runs.

Believe it or not this is how Call of Duty and movies streamed on Netflix actually work.

No one codes this way.

First of all, if you really want to go this low level, Assembler is the way to go. Assembly Language is the exact same thing except it uses mnemonics to make the code easier to read. Notice how 0012 was used twice and once it was a value and the other time it was an instruction. Likewise, are you going to be able to remember that 0007 is an instruction to add a value to the AX register?

Assembler looks something like this:
AX       0012
ADD      AX, 0001 
STORE    AX, 0100



Again, this is not actual Assembler but enough to give you the idea. I think you can see that this is maybe a little more readable but it is the exact same thing. You run this code through an Assembler or compiler and it converts this to the exact same thing we had in machine code. After it's compiled it is the exact same machine codes. And it's one for one. Every Assembler instruction translates exactly to one machine code. AX 0012 might mean to put the value 12 into the AX register exactly like it did in machine code but remembering that AX does that rather than remembering the numeric code 0004 tends to make the code a lot more readable to humans. Likewise ADD AX, 0001 might mean to add the value 1 to whatever is in the AX register just like it did in machine code. But again, it's easier to read the code at a glance.

This is why you never find anyone that does machine code. Assembler is easier to understand and does the exact same thing once it is compiled into machine code. The compiled machine code will not in any way be any different than if you had of written it in machine code in the first place.

You also won't find anyone doing machine code except hobbyists and such. I love Assembler. It's probably my favorite language, but I don't have any real use for it because C++ is roughly the same thing.

I'll just skip C here because I don't see it as substantially different than C++.

In C++, the code would look more like:

MyNumber =12;
MyNumber++;



Now, this C++ example is not exact. It doesn't specify any registers. In C++, you never work directly with the registers. And you don't necessarily have to work directly with memory addresses. We've totally lost the 1 to 1 with machine code we had. We are no longer "at the metal". When this code compiles it is going to have to compile down to machine code. And in this case it might compile down to basically what we saw before, but there will be quite a bit more instructions. In Assembler it might ... well let's just look at the real thing:

I wrote this C++ program in Visual Studio 2013 and then broke out the disassembler while in Debug mode to look at the Assembly version of the machine code that VS generated from my C++ code:

C++ code:
int main()
{
	int MyNumber;

	MyNumber = 12;
	MyNumber++;

	return 0;
}



Machine Code (Assembler really):
int main()
{
00DF1380  push        ebp  
00DF1381  mov         ebp,esp  
00DF1383  sub         esp,0CCh  
00DF1389  push        ebx  
00DF138A  push        esi  
00DF138B  push        edi  
00DF138C  lea         edi,[ebp-0CCh]  
00DF1392  mov         ecx,33h  
00DF1397  mov         eax,0CCCCCCCCh  
00DF139C  rep stos    dword ptr es:[edi]  
	int MyNumber;

	MyNumber = 12;
00DF139E  mov         dword ptr [MyNumber],0Ch  
	MyNumber++;
00DF13A5  mov         eax,dword ptr [MyNumber]  
00DF13A8  add         eax,1  
00DF13AB  mov         dword ptr [MyNumber],eax  

	return 0;
00DF13AE  xor         eax,eax  
}
00DF13B0  pop         edi  
00DF13B1  pop         esi  
00DF13B2  pop         ebx  
00DF13B3  mov         esp,ebp  
00DF13B5  pop         ebp  
00DF13B6  ret  



The lines on the far left that are all hexadecimal numeric are the memory addresses on my computer where the machine codes live. You can see that some of them are only one byte which means it's one code with no value following it. For example at the end you have "pop edi". EDI is one of the registers and it only needs one code to tell it to pop whatever value is next on the stack into the EDI register. In my pseudo-code I said it's one instruction followed by one value, but in the real world the instruction determines how many values will follow it. So, there might be no value following the instruction or a 16 bit value followed by a 64 bit value. You'll notice from the gaps between lines of instruction that it varies quite a bit in terms of the number of bytes for each line of machine code.

All that pushing and popping stuff is dealing with the stack and passing values as parameters as well as returning the state of the computer back to the way it was before you started messing with it. We can ignore all the pushing and popping for now.

The 3rd to last line is "mov esp,ebp". Both ESP and EBP are registers, It's telling the CPU to move the value from one to the other.

So getting to the point, you can see that my previous example translated to:
	MyNumber = 12;
00DF139E  mov         dword ptr [MyNumber],0Ch  
	MyNumber++;
00DF13A5  mov         eax,dword ptr [MyNumber]  
00DF13A8  add         eax,1  
00DF13AB  mov         dword ptr [MyNumber],eax  




So, MyNumber at that point is already assigned a memory address off the heap. I believe 0C in hex is the value 12. So, it's just saying move the value 12 into that memory location. That's it. Very short and sweet although there was quite a bit of setup machine code to get to that point.

MyNumber++ (add one to MyNumber) translates to:
00DF13A5  mov         eax,dword ptr [MyNumber]  
00DF13A8  add         eax,1  
00DF13AB  mov         dword ptr [MyNumber],eax  



That's, "move the value (12) that is in the memory address we call "MyNumber" into the EAX register". The next line says, "add one to the value that is in the EAX register". (Notice the AX. I believe EAX is a 64 bit register and AX is a 32 bit register which is half of the EAX register... or is it 32 bit and 16 bit...it's been a long time since I've done Assembler). Then it moves the value from the EAX register to overwrite the original value in the memory location we call "My Number".

As you can see, it is not one for one. Some C++ commands are going to translate into a lot of machine code.

But if you had of written the machine code yourself, you probably could not have added 1 to MyNumber any more efficiently than that. And that gets back to why no one except hobbyists use Assembler anymore pretty much.

I got it straight from someone at Microsoft that I know for a fact has the job of disassembling Microsoft's C++ code for a major MS product that it's near impossible to write more efficient machine code than Visual Studio C++ can. They've had a lot of years to optimize that compiler and it is apparently very good at its job.

I've written Windows GUI apps in Assembler for the fun of it. And I can tell you that I can see no point in using Assembler other than the education of being able to read the disassembly to see what C++ is really doing behind the scenes and understanding how the computer itself works. Every programmer should learn Assembler at some point, but I don't see any reason why anyone would want to use it the real world. And I say that with Assembler being my favorite language. And I say it because C++ is for all practical purposes the same thing.

No C++ is not one for one with machine code or Assembler. But the C++ compiler is so good at writing machine code that it will be next to impossible to hand code better machine code than it can.

You are still very close to the metal here. With a language like Python (especially if it goes through an interpreter or is managed code) it's a much higher level where it's pretty easy to write FAR more efficient machine code than what you're getting. That's not true with C++. With C++ you are still at a very low level and almost manipulating the hardware yourself still, but it's more readable code and most importantly there's next to no advantage to go one step lower to Assembler not to mention that you can find examples of how to code things in C++ all day long on Google and you'll find very few if any examples of how to solve problems in Assembler in an Internet search. 99 times out of 100, you'll have to resort to C++ examples in order to solve your Assembly language questions these days. I love Assembler, but it just makes far more sense to let the C++ compiler write your machine code for you because it is really really really good at the job. You have such low level control that you can almost make it write the exact machine code you want. And if there is a very rare case where you can actually write more efficient machine code, it doesn't matter unless it is in a loop where it repeats millions of times because if it takes 2 nano seconds instead of 3 no human is ever going to notice or care, but if that code loops a few billion times it might be the difference between 1 second and 5 seconds or a video game frame rate of 30 FPS vs 180 FPS. So, in those very rare instances you can actually write inline Assembler into your C++ code. So, you can write one function - that is heavily used - in Assembler yourself and then call it from C++ if you really feel the need to have different Assembler code than what C++ generated. It's the best of all worlds. And that gets back to there just not being a good reason to use Assembler for anything anymore.

Now I would probably have to write another post that is as long as this one to explain how low level C++ really is and how just about no other language out there comes anywhere as close to being as efficient or as low level (I consider C the same thing as C++). When you start writing Windows apps and DirectX video games in C++, you'll quickly realize how low level it is and how it does almost nothing for you. Using libraries helps a lot with that, but even then it's a different experience. You lose efficiency when you go to higher level languages like C#, Java, or Python, but it's a lot easier to get work done because those languages do so much for you, which is why not everyone wants to code in C++. And computers run so fast these days, that you don't need to be nearly as efficient as was once required.

This post has been edited by BBeck: 02 November 2015 - 12:45 PM

Was This Post Helpful? 5
  • +
  • -

#11 no2pencil   User is offline

  • Professor Snuggly Pants
  • member icon

Reputation: 6824
  • View blog
  • Posts: 31,470
  • Joined: 10-May 07

Re: the experts can't agree on anything :(

Posted 02 November 2015 - 11:17 AM

View Postherc65, on 02 November 2015 - 01:21 PM, said:

One person in this thread brought up the "reinventing the wheel" issue I've seen mentioned elsewhere--how you can code anything at all in C, even graphics-intensive applications, as long as you don't mind creating a whole bunch of your own libraries.

Sometimes the best way to understand how the vehicle moves is by examining the wheels. If you don't understand the wheels, then you are turning a blind eye to important parts of the process. There are also times that the wheel could use some fine-tuning. But one should be a master of the wheel by that point.

Just because something is, doesn't mean that it's the final best solution. If you truly wish to learn about a technology at it's lowest level, you are going to need to spend time in C, & that probably means doing something that's been done a way a thousand times, for decades & that isn't a bad thing. Case in point, Linux was first suggested by Linus Torvalds in 1991 & version 1.0 was released I believe in 1992. How much has processing changed from the 16 bit to the 32 / 64 bit architecture? I read somewhere recently that there is less than 2% of Linus'es code left in the Linux Kernel, & it gets something like thousands of lines added per day. I've not fact-checked any of that, but I think that kind of speaks the point of reinventing the wheel. For those whom are dealing with the wheel... you have to know it.
Was This Post Helpful? 2
  • +
  • -

#12 BBeck   User is offline

  • Here to help.
  • member icon


Reputation: 792
  • View blog
  • Posts: 1,886
  • Joined: 24-April 12

Re: the experts can't agree on anything :(

Posted 02 November 2015 - 12:08 PM

*
POPULAR

Let me point out the difference between low level and high level.

Here's a program I wrote in C++ for DirectX 11 where I wrote every line of code you see:

Main.cpp
#include <windows.h>
#include "WindowsSys.h"
#include "Game.h"


//=====================================================================================================================
//  wWinMain()
//
//	Purpose: 
//		This is where the code begins.
//
//  Notes:
//		There is an enormous amount of code required just to start a blank DX application window that doesn't do anything.
//	And all Windows programs must start with WinMain as the application entry point.  Technically this is our application 
//	here, but we want to follow object oriented design principles and so we encapsulate and obfuscate everything in various
//	classes that do all the work. That makes this function the conductor of this symphony. It calls each piece and maintains
//	the event loop that keeps everything running.
//
//		It may not be readily apparent, but the Game1.InitializeDX() is actually calling the Initialize method of the DirectX11Game
//	class to initialize DX and then run Game1's initialize method.
//
//		In practice, this code should not be altered at all unless you just want to tweak something. All code for the application
//	should be in or called from the Game object Game1.
//
//=====================================================================================================================
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPWSTR cmdLine, int cmdShow)	//<--Code Begins Here.
{
	int ReturnValue = -1;					//-1 is a failure.
	WindowsSys Windows(hInstance);			//Declare an instance of the Windows encapsulation class.
	Game Game1;								//Declare an instance of the Game class which is where the programmer adds code. Could be named something besides Game1.
	float TimeDelta;						//The game clock.
	UNREFERENCED_PARAMETER(prevInstance);	//These parameters were part of Windows in the 1990's and are unused but still there for "backwards compatibility".
    UNREFERENCED_PARAMETER(cmdLine);		//These parameters were part of Windows in the 1990's and are unused but still there for "backwards compatibility".


	//Start by calling the Windows encapsulation class to get Windows to give us a process and a window to work in. 
	//If we have no process and window to run in then we have to shutdown.
	//DirectX11Game is keeping track of the screen size for everybody.
	if (Windows.Initialize(cmdShow, Game1.GetScreenWidth(), Game1.GetScreenHeight()))
	{
		if(Game1.InitializeDX(hInstance, Windows.WindowHandle))		//Initialize DirectX11 and call our Intialize and LoadContent methods.
		{	
			while(Windows.msg.message != WM_QUIT)					//Keep going forever until Windows sends a quit event.
			{
				if(PeekMessage(&Windows.msg, 0, 0, 0, PM_REMOVE))	//Handle Windows Event Messages.
				{
					TranslateMessage(&Windows.msg);
					DispatchMessage(&Windows.msg);
				}
				Game1.Timer.Update();								//Update the game timer to reflect the time since the last frame.
				TimeDelta = Game1.Timer.MilliSecondsSinceLastFrame();
				// Update and Draw
				Game1.Update(TimeDelta);							//Call our Game's Update method.
				if(Game1.DeviceContextIsDefined())					//Make sure we actually have a DX device context to draw with.
				{
					Game1.Draw(TimeDelta);							//Call our Game's Draw method.
				}
				else
				{
					//This should never happen unless no graphics device can be found or something pretty major went wrong.
					//If it does however, its time to crash the program gracefully since we can't draw.
					PostQuitMessage(0);	//Send a Windows event to shut down this program.
				}
			}

			Game1.Shutdown();	//Shutdown DirectX and cleanup before letting the window shutdown.

			Windows.ShutDown();	//Do cleanup of the window.

			ReturnValue = static_cast<int>(Windows.msg.wParam);
		}
	}

	return ReturnValue;
}
//=====================================================================================================================




Main.h
I did not feel the need to make a header file for main. But that's the beauty of C++ because you can do things however you want.

DirectX11.cpp
#include"DirectX11Game.h"
#include<D3Dcompiler.h>


//=====================================================================================================================
//  Constructor
//
//	Purpose: 
//		Initialize basic values for the DXGame object.
//
//  Notes:
//		The feature level sets which version of DX to use. DX 11.1 seems to be the most recent here but we won't use any
//	features that are not available in DX 11.0 for these tutorials.
//
//		More information can be found on the DriverType at:https://msdn.microsoft.com/en-us/library/windows/desktop/ff476328(v=vs.85).aspx
//
//=====================================================================================================================
DirectX11Game::DirectX11Game() 
{
	DriverType = D3D_DRIVER_TYPE_HARDWARE;
	GraphicsCardFeatureLevel = D3D_FEATURE_LEVEL_11_1; 
	GraphicsDevice = nullptr;
	GraphicsDeviceContext = nullptr;
	SwapChain = nullptr;
	BackBuffer = nullptr;
	ScreenWidth = 1280;			//Width of the display resolution of the computer monitor.
	ScreenHeight = 720;			//Height of the display resolution of the computer monitor.
}
//=====================================================================================================================


//=====================================================================================================================
//  Destructor
//
//	Purpose: 
//		Cleanup of any class specific code.
//
//  Notes:
//		Not used, but you are welcome to use it if you like.
//
//=====================================================================================================================
DirectX11Game::~DirectX11Game()
{
}
//=====================================================================================================================


//=====================================================================================================================
//  DirectX11Game::InitializeDX()
//
//	Purpose: 
//		
//	Input:
//		HINSTANCE hInstance - A Windows handle to our process. Mostly brought in here to allow the DXGame object to remember it if needed.
//		HWND hWnd - A Windows handle to our window.
//
//	Output:
//		bool - Returns true if DirectX initialized properly without problems.
//
//  Notes:
//		Creates the Graphics Device and Device Context
//		Creates the Swap Chain
//		Assigns memory to the Swap Chain back buffer
//		Uses the back buffer to create a render target
//		Assigns memory to the Depth Stencil
//		Assigns depth stencil to the Graphics Device
//		Sets the view port and render target for the Graphics Device Context
//		Runs Game class's startup code
//
//=====================================================================================================================
bool DirectX11Game::InitializeDX(HINSTANCE hInstance, HWND hWnd)
{
	bool Initialized = false;						//Return value - must be true if properly initialized.
    ID3D11Texture2D* BackBufferTexture;				//The back buffer.
    HRESULT hr;										//Used to determine if DX functions succeeded or not.

	WindowHandle = hWnd;							//The object will have the window's handle for latter use.
	WindowInstanceHandle = hInstance;				//The object will have the window's instance handle for latter use.
	

	if (CreateDeviceAndSwapChain())
	{
		if(SUCCEEDED(SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&BackBufferTexture)))
		{
			if(SUCCEEDED(GraphicsDevice->CreateRenderTargetView(BackBufferTexture, 0, &BackBuffer)))
			{
				if(CreateDepthStencilTexture())
				{
					D3D11_DEPTH_STENCIL_VIEW_DESC DepthStencilViewDescription = SetDepthStencilViewDesc();
					if(SUCCEEDED(hr = GraphicsDevice->CreateDepthStencilView(DepthStencilTexture, &DepthStencilViewDescription, &DepthStencilView)))
					{
						CreateViewPort();
						if (Keyboard.Initialize(WindowInstanceHandle, WindowHandle))	//Don't bother going further if DirectInput doesn't initialize.
						{
							Initialized = InitializeGameClass();
						}
					}
					else DXTRACE_ERR("Failed to create depth stencil view!", hr);
				}
				else DXTRACE_MSG("Failed to create the depth stencil texture!");
			}
			else DXTRACE_MSG("Failed to create the render target ViewMatrix!");
			if(BackBufferTexture) BackBufferTexture->Release();		//BackBufferTexture pointer no longer needed.
		}
		else DXTRACE_MSG("Failed to get the swap chain back buffer!");
	}
	
	return Initialized;
}
//=====================================================================================================================


//=====================================================================================================================
//  DirectX11Game::CreateViewPort()
//
//	Purpose: 
//		
//	Input:
//		None.
//
//	Output:
//		None
//
//  Notes:
//		This method merely sets the render target to draw to the backbuffer(screen). And it sets the viewport. Keep in mind 
//	that this can be a region of the screen rather than the whole screen. So, with 4 render targets you can have 4 different
//	displays on the same screen. For our example here, we're just working with 1 render target, 1 view port, and 1 computer
//	monitor, but this can be expanded to do a lot more.
//
//=====================================================================================================================
void DirectX11Game::CreateViewPort()
{
	D3D11_VIEWPORT DXViewPort;						//Conceptually, a viewport is a two dimensional(2D) rectangle into which a 3D scene is projected.In Direct3D, the rectangle exists as coordinates within a Direct3D surface that the system uses as a rendering target.


	GraphicsDeviceContext->OMSetRenderTargets(1, &BackBuffer, DepthStencilView);	//Sets rendering(drawing) to the current back buffer maintained by this object.
	
	DXViewPort.Width = static_cast<float>(ScreenWidth);
	DXViewPort.Height = static_cast<float>(ScreenHeight);
	DXViewPort.MinDepth = 0.0f;
	DXViewPort.MaxDepth = 1.0f;
	DXViewPort.TopLeftX = 0.0f;
	DXViewPort.TopLeftY = 0.0f;

	GraphicsDeviceContext->RSSetViewports(1, &DXViewPort);
}
//=====================================================================================================================


//=====================================================================================================================
//  DirectX11Game::SetDepthStencilViewDesc()
//
//	Purpose: 
//		To return a depth stencil view description data structure to describe how the depth stencil should be setup.
//
//	Input:
//		None.
//
//	Output:
//		D3D11_DEPTH_STENCIL_VIEW_DESC - Object that describes the depth stencil.
//
//  Notes:
//		This method is actually very straight forward. It creates a depth stencil view description object. It zeros out the
//	memory being used to initialize the memory. Then it sets the parameters of this object and returns the data structure.
//
//		The depth stencil is used primarily to determine an object's depth in the scene being drawn so that the objects can
//	correctly be drawn in any order and yet closer objects will still be drawn on top of objects further away. 
//
//		I've gone ahead here and changed the code from no anti-aliasing to anti-aliasing. Turn off anti-aliasing if your
//	graphics card has a problem with it. Aliasing is the "stair step" effect you see on lines and edges of objects when
//	drawn. Anti-aliasing basiclly blurs these edges.
//
//=====================================================================================================================
D3D11_DEPTH_STENCIL_VIEW_DESC DirectX11Game::SetDepthStencilViewDesc()
{
	D3D11_DEPTH_STENCIL_VIEW_DESC DepthStencilViewDescription;

	ZeroMemory(&DepthStencilViewDescription, sizeof(DepthStencilViewDescription));
	DepthStencilViewDescription.Format = DepthStencilTextureDescription.Format;
	//DepthStencilViewDescription.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;	//No anti-aliasing
	DepthStencilViewDescription.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;	//Anti-aliasing
	DepthStencilViewDescription.Texture2D.MipSlice = 0;

	return DepthStencilViewDescription;
}
//=====================================================================================================================


//=====================================================================================================================
//  DirectX11Game::InitializeGameClass()
//
//	Purpose: 
//		To run the programmer's custom initialization code at startup.
//
//	Input:
//		None.
//
//	Output:
//		bool - true if no errors occured.
//
//  Notes:
//		This method calls into the Game class that inheriets from this class which allows the programmer to include their own
//	code to initialize and load art assets. The timer object is also initialized to start the clock so that we can know
//	how much time has passed between each frame.
//	
//		All of the method that this method calls out to return false if there was a failure or error. So, if everything returns
//	true, this method will return true also to indicate that everything initialized properly.
//
//=====================================================================================================================
bool DirectX11Game::InitializeGameClass()
{
	bool Initialized = false;						//Return value - must be true if properly initialized.

	if (Initialize())		//Call Game class's Initialize method to do programmer defined initialization.
	{
		if (LoadContent())	//Call Game class's LoadContent method to load programmer defined game assets.
		{
			if (Timer.Initialize()) Initialized = true;	//Initialize the Game Timer and we're good.
		}
	}
	return Initialized;
}
//=====================================================================================================================


//=====================================================================================================================
//  DirectX11Game::CreateDepthStencilTexture()
//
//	Purpose: 
//		To create a 2D texture (memory buffer) to be ussed for the depth stencil.
//
//	Input:
//		None.
//
//	Output:
//		bool - true if no errors occured.
//
//  Notes:
//		This method creates a 2D texture that will be used as the depth stencil. This buffer of memory has to be the exact same
//	size as the display screen which means it has to be the same size as the back and front buffers. Each "pixel" in this buffer
//	matches up with a pixel in the back buffer. In this buffer it is not storing the color for the object on the screen but rather
//	the depth in the scene away from the camera of the matching pixel in the back buffer. This allows the graphics card to know
//	whether the pixel it is about to draw for a given object on the back buffer is an object in front of or in back of the color
//	pixel of the object that has already been drawn.
//
//		So, in other words it stores the distance of an object when it draws that object and every other object it draws after
//	that gets tested in the depth stencil to determine whether it is closer or further away than the object already drawn on a 
//	pixel by pixel basis. So, objects that are behind an object already drawn will not get drawn and objects in front of the object
//	already drawn will get drawn on top of the objects already drawn.
//
//		I set this up for anti-aliasing because you will probably prefer to have anti-aliasing on. However, I left the code
//	needed to turn anti-aliasing off if you would rather use that (presumably because your graphics card doesn't handle 
//	anti-aliasing although I can't imagine anyone has ever made a DX11 graphics card that doesn't do at least some level of 
//	anti-aliasing. However, I've heard there are not many examples out there showing how to do anti-aliasing, so I wanted to 
//	go ahead and show how that can be done here. Like a lot of things with DX programming, this is personal preference if 
//	your graphics card can do it.
//
//=====================================================================================================================
bool DirectX11Game::CreateDepthStencilTexture()
{
	bool CreatedTextureForDepthStencil = false;		//Fail unless we succeed.


	ZeroMemory(&DepthStencilTextureDescription, sizeof(DepthStencilTextureDescription));	//Initialize memory for this object so that we don't get surprises and so we know what the initial values are when debugging.
	DepthStencilTextureDescription.Width =  ScreenWidth;
	DepthStencilTextureDescription.Height = ScreenHeight;
	DepthStencilTextureDescription.MipLevels = 1;
	DepthStencilTextureDescription.ArraySize = 1;
	DepthStencilTextureDescription.Format =  DXGI_FORMAT_D24_UNORM_S8_UINT;
	//DepthStencilTextureDescription.SampleDesc.Count = 1;		//No anti-aliasing
	DepthStencilTextureDescription.SampleDesc.Count = 8;		//Anti-aliasing
	//DepthStencilTextureDescription.SampleDesc.Quality = 0;	//No anti-aliasing
	DepthStencilTextureDescription.SampleDesc.Quality = 4;		//Anti-aliasing
	DepthStencilTextureDescription.Usage = D3D11_USAGE_DEFAULT;
	DepthStencilTextureDescription.BindFlags = D3D11_BIND_DEPTH_STENCIL;
	DepthStencilTextureDescription.CPUAccessFlags = 0;
	DepthStencilTextureDescription.MiscFlags = 0;
		
	if(SUCCEEDED(GraphicsDevice->CreateTexture2D(&DepthStencilTextureDescription, NULL, &DepthStencilTexture)))
	{
		CreatedTextureForDepthStencil  = true;
	}
	

	return CreatedTextureForDepthStencil;
}
//=====================================================================================================================


//=====================================================================================================================
//  DirectX11Game::CreateDeviceAndSwapChain()
//
//	Purpose: 
//		To create the Device, Device Context, and Swap Chain. Basically, initializes DX.
//
//	Input:
//		None.
//
//	Output:
//		bool - true if no errors occured.
//
//  Notes:
//		This method is the core of starting up DX. This one method, by calling D3D11CreateDeviceAndSwapChain, almost single handedly
//	initializes DX. Three of the most important parts of DX are setup here in this one call: the Device, the Device Context, and the
//	swap chain.
//
//		I have to admit that I'm still basically trying to understand exactly what a device and a device context are. Here is MS's
//	documentation on the matter:
//	https://msdn.microsoft.com/en-us/library/windows/desktop/ff476880(v=vs.85).aspx
//
//		Basicaly, the best explanation I've heard comes from MS and is that a device is basically used to put together the resources
//	that the graphics card uses such as textures and vertex buffers. And a device context is what actually does the work. At least,
//	that's my current understanding of the matter.
//	
//		Regardless, the combination of the device and device context ARE DirectDraw3D/DirectX. This is the COM object that is
//	DirectX and that does all the drawing.
//
//		The swapchain consists of the front buffer and one or more back buffers. The front buffer is the area of memory where
//	the graphics card looks to determine what color every pixel on your computer screen will be drawn with. By drawing all the 
//	pixels on the computer screen in the correct color, you get the image on your computer screen. All the front buffer contains
//	is a color for every pixel to be drawn on the screen (I say screen but you could be drawing picture in picture or multiple 
//	cameras which would each need their own swap chain.) But it is 1 to 1 with each value in the front buffer representing nothing
//	but a color for a pixel on the screen. Whatever is in the front buffer IS what's on your computer screen.
//
//		You could theoretically draw to the front buffer, but we don't. The primary reason is that if you do, you get what is called
//	screen tearing. You can google that to get some great example images of what that is. But basically it means that when something 
//	changes between frames part of the screen still has the image for the previous frame and part of the screen has the image for the
//	new frame and you can see the line where they don't agree with one another.
//
//		So, instead we create an identical buffer called the back buffer which we draw to instead. Then we do a SUPER fast change between 
//	frames all at once to flip the buffers. Actually, the difference between the front buffer and the back buffer is just which one the 
//	pointer points to. Flipping the back buffer and front buffer is called "presenting" and all that happens is that between frames the 
//	back buffer pointer is changed to point to the front buffer memory and the front buffer pointer is changed to point to the back buffer 
//	memory. Then the new frame is presented to the video display all at once without any tearing. And changing two memory pointers is super 
//	fast not to mention that this can be coordinated with the drawing so that it occurs between screen refreshes. The screen refresh rate 
//	is also set here if you like. 1/60th of a second is pretty standard.
//
//		Two buffers is called double buffering. But you can have even more back buffers if needed for some reason. The front buffer
//	and all the back buffers is what is known as the "swap chain".
//
//		If D3D11CreateDeviceAndSwapChain succeeds then it returns a pointer to the Device, Device Context, and swap chain. If it fails
//	then DirectX is not going to be able to draw anything to the screen and we probably might as well close the application and call it
//	quits. This method returns false if such a catostrophic failure occurs.
//
//		This isn't really designed to work with multiple graphics cards or even multiple monitors. So, you're pretty much on your own
//	modding this code to make it handle that. It pretty much goes with the first graphics port it finds.
//
//=====================================================================================================================
bool DirectX11Game::CreateDeviceAndSwapChain()
{
	bool DriverFound = false;	//Assume we fail unless everything goes right.
	unsigned int Driver = 0;
	unsigned int NumberOfDriverTypes;
	unsigned int NumberOfFeatureLevels;
	unsigned int DeviceCreationFlags = NULL;

    D3D_DRIVER_TYPE DriverTypes[] =
    {
        D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP,
        D3D_DRIVER_TYPE_REFERENCE, D3D_DRIVER_TYPE_SOFTWARE		//The driver types we want to support. Usually only the hardware driver.
    };
    
    D3D_FEATURE_LEVEL FeatureLevels[] =
    {
		D3D_FEATURE_LEVEL_11_1,
        D3D_FEATURE_LEVEL_11_0 //,
        //D3D_FEATURE_LEVEL_10_1,
        //D3D_FEATURE_LEVEL_10_0								//The different versions of DX hardware we want to support.
    };


	NumberOfDriverTypes = ARRAYSIZE(DriverTypes);
    NumberOfFeatureLevels = ARRAYSIZE(FeatureLevels);

    DXGI_SWAP_CHAIN_DESC swapChainDesc;
    ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));		//Initialize the memory by zero'ing it all out.
    swapChainDesc.BufferCount = 1;
    swapChainDesc.BufferDesc.Width = ScreenWidth;
    swapChainDesc.BufferDesc.Height = ScreenHeight;
    swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
    swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
    swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swapChainDesc.OutputWindow = WindowHandle;	//Connect DirectX to the window so that DX can draw in the application's window.
    swapChainDesc.Windowed = true;	//Create windowed or full screen.
    //swapChainDesc.SampleDesc.Count = 1;		//No anti-aliasing
	swapChainDesc.SampleDesc.Count = 8;			//Anti-aliasing
    //swapChainDesc.SampleDesc.Quality = 0;		//No anti-aliasing
	swapChainDesc.SampleDesc.Quality = 4;		//Anti-aliasing
	swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;	//Allow full screen switching;

#ifdef _DEBUG
    DeviceCreationFlags |= D3D11_CREATE_DEVICE_DEBUG;	//If you're debugging, you might want a little extra info as to what went wrong.
#endif

	do
	{
        if(SUCCEEDED(D3D11CreateDeviceAndSwapChain(0, DriverTypes[Driver], 0, DeviceCreationFlags, FeatureLevels, NumberOfFeatureLevels,
			D3D11_SDK_VERSION, &swapChainDesc, &SwapChain, &GraphicsDevice, &GraphicsCardFeatureLevel, &GraphicsDeviceContext)))
        {
            DriverType = DriverTypes[Driver];
            DriverFound = true;					//We can now draw to the screen. Exit after finding the first working graphics driver type.
        }
		++Driver;
	}
	while (Driver < NumberOfDriverTypes && !DriverFound);

	if(!DriverFound) DXTRACE_MSG("Failed to create the Direct3D device!");

	return DriverFound;
}
//=====================================================================================================================


//=====================================================================================================================
//  DirectX11Game::DeviceContextIsDefined()
//
//	Purpose: 
//		Allows the programmer to ask this object whether there is currently a valid Device Context created.
//
//	Input:
//
//	Output:
//		bool - true there is a GraphicsDeviceContext defined.
//
//  Notes:
//		GraphicsDeviceContext is an interface to the DX COM object that allows us to manipulate the graphics card. If DX is not
//	properly initialized we will not have a pointer to this interface. We don't want to make calls to DX if it is not properly
//	initialized.
//
//=====================================================================================================================
bool DirectX11Game::DeviceContextIsDefined(void)
{
	return GraphicsDeviceContext != NULL;
}
//=====================================================================================================================


//=====================================================================================================================
//  DirectX11Game::Initialize()
//
//	Purpose: 
//		Mostly just a place holder to make the Game object that inherits from this class have an Initialize() method of its own.
//
//	Input:
//		None.
//
//	Output:
//		bool - never fail.
//
//  Notes:
//		This is a virtual method to make the child object that inherits from this object implement an initialization method.
//
//===================================================================================================================== 
bool DirectX11Game::Initialize()
{
    return true;
}
//=====================================================================================================================


//=====================================================================================================================
//  DirectX11Game::LoadContent()
//
//	Purpose: 
//		Mostly just a place holder to make the Game object that inherits from this class have a LoadContent() method of its own.
//
//	Input:
//		None.
//
//	Output:
//		bool - never fail.
//
//  Notes:
//		This is a virtual method to make the child object that inherits from this object implement a load content method.
//
//===================================================================================================================== 
bool DirectX11Game::LoadContent()
{
    return true;
}
//=====================================================================================================================


//=====================================================================================================================
//  DirectX11Game::UnloadContent()
//
//	Purpose: 
//		Mostly just a place holder to make the Game object that inherits from this class have an UnloadContent() method of its own.
//
//	Input:
//		None.
//
//	Output:
//		None.
//
//  Notes:
//		This is a virtual method to make the child object that inherits from this object implement an UnloadContent method.
//
//===================================================================================================================== 
void DirectX11Game::UnloadContent()
{

}
//=====================================================================================================================


//=====================================================================================================================
//  DirectX11Game::GetScreenWidth()
//
//	Purpose: 
//		Return the screen resolution.
//
//	Input:
//		None.
//
//	Output:
//		unsigned int - Width of the current display resolution.
//
//  Notes:
//		
//
//=====================================================================================================================
unsigned int DirectX11Game::GetScreenWidth()
{
	return ScreenWidth;
}
//=====================================================================================================================


//=====================================================================================================================
//  DirectX11Game::GetScreenHeight()
//
//	Purpose: 
//		Return the screen resolution.
//
//	Input:
//		None.
//
//	Output:
//		unsigned int - Height of the current display resolution.
//
//  Notes:
//		
//
//=====================================================================================================================
unsigned int DirectX11Game::GetScreenHeight()
{
	return ScreenHeight;
}
//=====================================================================================================================


//=====================================================================================================================
//  DirectX11Game::Shutdown()
//
//	Purpose: 
//		To cleanly shut down DirectX and our application.
//
//	Input:
//		None.
//
//	Output:
//		None.
//
//  Notes:
//		The first thing this method does is call the Game object that inherits from this class's UnloadContent() method to
//	free up any memory used for art assets by that object. Then it basically just shuts down DX and releases any memory 
//	associated with DX.
//
//===================================================================================================================== 
void DirectX11Game::Shutdown()
{
	UnloadContent();

	Keyboard.Shutdown();	//Release DirectInput and the keyboard device.
	GraphicsDeviceContext->ClearState();
	if(DepthStencilTexture) DepthStencilTexture->Release();
	if(DepthStencilView) DepthStencilView->Release();
    if(BackBuffer) BackBuffer->Release();
    if(SwapChain) 
	{
		SwapChain->SetFullscreenState(FALSE, NULL);
		SwapChain->Release();
	}

	if(GraphicsDeviceContext) GraphicsDeviceContext->Release();
    if(GraphicsDevice) GraphicsDevice->Release();    

    BackBuffer = NULL;
    SwapChain = NULL;
    GraphicsDeviceContext = NULL;
    GraphicsDevice = NULL;
}
//===================================================================================================================== 



DirectX11Game.h
#pragma once

#include<d3d11.h>
#include<d3dx11.h>
#include<DxErr.h>
#include "GameTimer.h"
#include "KeyboardClass.h"
#pragma comment(lib, "dxerr.lib")
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "d3dx11.lib")
#pragma comment(lib, "d3dcompiler.lib")


//Predefined colors made to match XNA that you can use or not use.
const float RGBABlue[4] = {0.0f,0.0f,1.0f,1.0f}; 
const float RGBABlack[4] = {0.0f,0.0f,0.0f,1.0f}; 
const float RGBAWhite[4] = {1.0f,1.0f,1.0f,1.0f}; 
const float RGBAGreen[4] = {0.0f,0.5019607843137255f,0.0f,1.0f}; 
const float RGBARed[4] = {1.0f,0.0f,0.0f,1.0f}; 
const float RGBAYellow[4] = {1.0f,1.0f,0.0f,1.0f}; 
const float RGBACornFlowerBlue[4] = {0.392156862745098f,0.5843137254901961f,0.9294117647058824f,1.0f}; 

//=====================================================================================================================
//  DirectX11Game
//
//	Purpose: 
//		To encapsulate DirectDraw3D(DirectX) initialization/shutdown and obfuscate it so that we can forget about it.
//
//  Notes:
//		This class allows DirectX to mostly be obfuscated away so that the programmer doesn't have to deal with anything 
//	that is required to startup DX and get it properly initialized or to shut down DX when it is time to close the application.
//
//		In order to write a "game" the programmer is expected to create a game object that inherits from this class which will
//	hook it in to this whole system. The main code will call this object to initialize DX and this code will call the game
//	object that contains all the code for the game.
//
//		This is very basic bare bones code not designed to handle every feature of every graphics card. You may want to expand
//	on this code a little bit to do things like checking whether the graphics card supports anti-aliasing or not before turning
//	anti-aliasing on. However, by making a few minor adjustments such as matching the screen resolution to your own, this should
//	give you the code needed to start every DX project you might want to do and run it on your computer. Other than anti-aliasing
//	this is mostly all required code to make DX run. This is by far the longest class in this bare bones code.
//	
//=====================================================================================================================
class DirectX11Game
{
    public:
        DirectX11Game();
        virtual ~DirectX11Game();

        bool InitializeDX(HINSTANCE hInstance, HWND hWnd);
		void CreateViewPort();
		D3D11_DEPTH_STENCIL_VIEW_DESC SetDepthStencilViewDesc();
		bool InitializeGameClass();
		unsigned int GetScreenWidth();
		unsigned int GetScreenHeight();
        void Shutdown();
		bool CreateDeviceAndSwapChain();
		bool DeviceContextIsDefined();
		virtual bool Initialize();
        virtual bool LoadContent();
        virtual void UnloadContent();
        virtual void Update(float dt) = 0;
        virtual void Draw(float) = 0;

		GameTimer Timer;
    protected:
        HINSTANCE WindowInstanceHandle;
        HWND WindowHandle;
		KeyboardClass Keyboard;
        D3D_DRIVER_TYPE DriverType;
        D3D_FEATURE_LEVEL GraphicsCardFeatureLevel;
		ID3D11DeviceContext* GraphicsDeviceContext;
        ID3D11Device* GraphicsDevice;
        IDXGISwapChain* SwapChain;
        ID3D11RenderTargetView* BackBuffer;
		ID3D11DepthStencilView* DepthStencilView;
		ID3D11Texture2D* DepthStencilTexture;
		D3D11_TEXTURE2D_DESC DepthStencilTextureDescription;
		bool CreateDepthStencilTexture();
		bool SetDepthStencil(void);
		unsigned int ScreenWidth;
		unsigned int ScreenHeight;
};
//=====================================================================================================================




WindowsSys.CPP
#include "WindowsSys.h"


//=====================================================================================================================
//  Constructor
//
//	Purpose: Sets class member initial values.
//
//	Inputs:
//		hInstance - a number called a "handle" in Windows that represents "this" instance of the program in a Windows enviroment 
//			where multiple instances could be running.
//
//  Notes:
//		
//		Windows considers a window a "class". This is not really the same thing as a C++ class. See the following for more details:
//			https://msdn.microsoft.com/en-us/library/windows/desktop/ff381397(v=vs.85).aspx
//
//
//=====================================================================================================================
WindowsSys::WindowsSys(HINSTANCE hInstance)
{
	ApplicationClassName = L"MyClass";			//This is a "Windows Class" not a C++ class. This names the window internally for Windows.
	ApplicationName = L"My Game";				//The text that appears in the Window header if in windowed mode instead of full screen.
	InstanceHandle = hInstance;					//Record the assigned Window handle number for use later. This value is assigned to this app at startup.
	memset(&msg, 0, sizeof(msg));			//Windows Event.
	memset(&wndClass, 0, sizeof(wndClass));		//A window "class" has to be defined before a Windows window is created. (See WIN32 programming.)

    wndClass.cbSize = sizeof(WNDCLASSEX) ;		//Number of bytes used for this window.
    wndClass.style = CS_HREDRAW | CS_VREDRAW;	//Style of window borders when running in windowed mode instead of full screen. https://msdn.microsoft.com/en-us/library/windows/desktop/ms633574(v=vs.85).aspx#class_styles
    wndClass.lpfnWndProc = WndProc;				//A pointer to the WndProc callback procedure that handles Windows event messages.
    wndClass.hInstance = InstanceHandle;		//A handle to the instance that contains the window procedure for the class. 
    wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);	//Sets the cursor to be the standard arrow if the cursor is visible.
    wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);	//Sets the Windows background color which shouldn't matter since we're drawing over the top of it.
    wndClass.lpszMenuName = NULL;				//We don't want a menu at the top of our window.
    wndClass.lpszClassName = ApplicationClassName;	//A windows class is totally different than a C++ class. Name it whatever you want.
}
//=====================================================================================================================


//=====================================================================================================================
//  Destructor
//
//	Purpose: Does any necessary cleanup for the class before shutting down.
//
//	Inputs:
//
//  Notes:
//		
//		Not used but could be if you wanted to.
//
//=====================================================================================================================
WindowsSys::~WindowsSys(void)
{
}
//=====================================================================================================================


//=====================================================================================================================
//  WindowsSys::Initialized()
//
//	Purpose: 
//		To create a windows process to run in and a window to draw in.
//
//	Inputs:
//		int cmdShow - This is actually a parameter passed in from Windows itself at startup. It is a flag that says whether the main 
//			application window will be minimized, maximized, or shown normally.
//
//	Outputs:
//		bool - Returns true if the Windows process and window to draw in were successfully created.
//
//  Notes:
//		I believe RegisterClassExW() creates the Windows process and CreateWindowExW() creates the window we draw in. Even
//	if we run DX in full screen mode you still have to have a process and a "window" to draw to.
//		
//
//=====================================================================================================================
bool WindowsSys::Initialize(int cmdShow, unsigned int ScreenWidth, unsigned int ScreenHeight)
{
	bool ReturnValue = false;		//Report that initialization failed unless it was successful.
	RECT rc = {0, 0, ScreenWidth, ScreenHeight};	//Set screen resolution.
	GetWindowRect(GetDesktopWindow(), &rc);	//Resets the window size to the desktop's screen resolution. Comment out to use the hard coded size.


	//Attempt to register the window with Windows and don't continue unless it succeeds.
	if(RegisterClassExW(&wndClass))
	{
		AdjustWindowRect(&rc, WS_VISIBLE, FALSE);	//Calculates the required size of the window rectangle, based on the desired client-rectangle size. The second parameter is basically unused and can be almost anything.
		//Create the window.
		WindowHandle = CreateWindowExW(WS_EX_APPWINDOW, ApplicationClassName, ApplicationName, WS_OVERLAPPEDWINDOW,
									CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top,
									NULL, NULL, InstanceHandle, NULL);

		//If CreateWindowExW() succeeded it will have returned a window handle number, otherwise we have not window to work in and need to shutdown.
		if(WindowHandle)
		{
			ShowWindow(WindowHandle, cmdShow);	//Show the window on the screen.
			ShowCursor(false);					//Hide the cursor, if you want.
			ReturnValue = true;					//Report that we have successfully created a window for our program to draw in.
		}
	}
	
	return ReturnValue;
}
//=====================================================================================================================


//=====================================================================================================================
//  CALLBACK WndProc()
//
//	Purpose: 
//		To allow us to interact with the program.
//
//	Inputs:
//		HWND WindowHandle - Windows handle that points to this window.
//		UINT message - Windows event to be processed.
//		WPARAM wParam - Windows event parameter.
//		LPARAM lParam - Windows event parameter.
//
//	Outputs:
//		LRESULT - Always returns 0.
//
//  Notes:
//		If you are not familiar with Windows programming, this may be very alien to you. Windows is event-driven. If you 
//	don't know what that means go look it up because it's necessary to understand this procedure.
//
//		This is the event processor. It allows you to write code to process Windows events using what is called a "CALLBACK"
//	procedure. You're basically hooking your process here in to the Windows event loop with the CALLBACK procedure. The switch
//	statement allows you to write event handlers for any possible Windows event including those you create.
//
//		For DX, we don't really use this. You may never add code to this because for game programming we don't usually
//	deal with most Windows events or use this event loop. Of course we have to handle WM_DESTROY and WM_CLOSE that tell our 
//	program it's time to close. And you may or may not want to handle keyboard input here. I've chosen to use the depricated
//	DirectInput in order to handle keyboard events in the KeyboardClass. But I chose to add an event handler to shutdown any
//	time the escape key is pressed here. 
//
//		I originally included a WM_PAINT handler to draw the window because this is standard to pretty much all Windows programs,
//	but have experimented with dropping it completly out since we use DirectX to draw in our window's client area instead of GDI.
//	Not including it seems to have no ill effect.
//
//=====================================================================================================================
LRESULT CALLBACK WndProc(HWND WindowHandle, UINT message, WPARAM wParam, LPARAM lParam)
{
    //PAINTSTRUCT paintStruct;	//Standard for any Windows program except we don't use Windows to draw the screen and so don't use this.
    //HDC hDC;	//Device context to draw in. Basically unused.

    switch(message)
    {
        //case WM_PAINT:	//Redraw the window any time something draws over it.
        //    hDC = BeginPaint(WindowHandle, &paintStruct);
        //    EndPaint(WindowHandle, &paintStruct);
        //    break;

        case WM_DESTROY:	//If a message to destroy the program is received, close it down cleanly.
            PostQuitMessage(0);	//Post a message back to the Windows event loop that we're ready to have our process terminated.
            break;

		case WM_CLOSE:	//If a message to close the program is received, close it down cleanly.
			PostQuitMessage(0);	//Post a message back to the Windows event loop that we're ready to have our process terminated.
            break;

		case WM_KEYDOWN:
			switch(wParam)
			{
				case VK_ESCAPE:	//Always close the program if the Escape key is pressed. This is my personal preference.
					PostQuitMessage(0);	//Post a message back to the Windows event loop that we're ready to have our process terminated.
					break;
			}
			break;

        default:
			//If we don't have events of our own to process, pass the events on to the default Windows event processor.
            return DefWindowProcW(WindowHandle, message, wParam, lParam);
    }

    return 0;
}
//=====================================================================================================================


//=====================================================================================================================
//  WindowsSys::ShutDown()
//
//	Purpose: 
//		To do any Windows level cleanup before our application closes down.
//
//	Inputs:
//		
//	Outputs:
//
//  Notes:
//		This is all just standard shutdown for a Windows program.
//
//=====================================================================================================================
void WindowsSys::ShutDown(void)
{
	ShowCursor(true);					//Turn the cursor back on, if it was off.
	ChangeDisplaySettings(NULL, 0);		//Straighten up display settings, if in full screen.
	DestroyWindow(WindowHandle);		//Remove the window handle from use.
	WindowHandle = NULL;

	UnregisterClassW(ApplicationClassName, InstanceHandle);	//Shutdown our Windows process.
}
//=====================================================================================================================



WindowsSys.h
#pragma once
#include <windows.h>


//=====================================================================================================================
//  WindowsSys
//
//	Purpose: 
//		To encapsulate our Windows process and interaction with the Windows OS.
//
//  Notes:
//		This class allows Windows to mostly be obfuscated away so that the programmer doesn't have to deal with anything 
//	that is Windows specific. It should handle almost all interaction with the Windows OS for the entire program. There
//	is relatively little to handle though because we are using the DX API instead of calls to the OS the vast majority of
//	the time. So, mostly this merely asks Windows to give us a process to run in and a window to draw in which we then hijack
//	and use DirectX to draw on instead of letting Windows draw to the window. And then we close the process and window down
//	when it's time to close the program.
//
//=====================================================================================================================
class WindowsSys
{
	public:
		WindowsSys(HINSTANCE hInstance);	//Constructor.
		~WindowsSys(void);					//Destructor.
		bool Initialize(int cmdShow, unsigned int ScreenWidth, unsigned int ScreenHeight);		//Initialization method should be called at startup.
		void ShutDown(void);				//Cleanup method should be called when the program is closing.
    
	HWND WindowHandle;			//Windows uses handles to keep track of windows.
	MSG msg;					//A Windows event message. Events are the heart of event-driven programming.
	WNDCLASSEXW wndClass;		//A Windows "class" is basically a Windows application. This is not the same thing as a C++ class.
	HINSTANCE InstanceHandle;	//A number that Windows calls a "handle" that uniquely identifies "this" instance of the application.
	LPCWSTR ApplicationClassName;	//The name of the window we are running in which the user is never going to know about. 
	LPCWSTR ApplicationName;	//Mostly only used as the text that will appear in the header of the Window IF running in windowed mode instead of full screen.
};
//=====================================================================================================================


//=====================================================================================================================
//  CALLBACK WndProc()
//
//	Purpose: 
//		To allow us to interact with the program.
//
//	Inputs:
//		HWND WindowHandle - Windows handle that points to this window.
//		UINT message - Windows event to be processed.
//		WPARAM wParam - Windows event parameter.
//		LPARAM lParam - Windows event parameter.
//
//	Outputs:
//		LRESULT - Always returns 0.
//
//  Notes:
//		The window's callback procedure allows us to handle Windows events in our program. For the most part, the only
//	event we care about is the shutdown event which happens when you do something like clicking on the window's close button.
//	
//		It has to be static because you're telling Windows that you want it to jump to this area in memory (this procedure)
//	when it's ready for us to handle Windows events.
//
//=====================================================================================================================
static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//=====================================================================================================================




KeyboardClass.CPP
#include "KeyboardClass.h"


//=====================================================================================================================
//  Constructor
//
//	Purpose: 
//		Initialize basic values for the Keyboard object.
//
//  Notes:
//		Not used.
//
//=====================================================================================================================
KeyboardClass::KeyboardClass(void)
{
}
//=====================================================================================================================


//=====================================================================================================================
//  Destructor
//
//	Purpose: 
//		Cleanup any memory for the Keyboard object when destroying this object.
//
//  Notes:
//		Not used.
//
//=====================================================================================================================
KeyboardClass::~KeyboardClass(void)
{
}
//=====================================================================================================================


//=====================================================================================================================
//  KeyboardClass::Initialize()
//
//	Purpose: 
//		To initialize DirectInput and this class.
//
//	Input:
//		HINSTANCE hInstance - Windows handle for this application.
//		HWND hWnd - Windows handle for our application's window.
//
//	Output:
//		bool - Object initialized correctly. 
//
//  Notes:
//		This method initializes DirectInput8 much like initializing DirectX. Return false if we can't communicate with the
//	keyboard. 
//
//=====================================================================================================================
bool KeyboardClass::Initialize(HINSTANCE hInstance, HWND hWnd)
{
	bool KeyboardDeviceCreatedAndAquired = false;

	if (SUCCEEDED(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, 
		IID_IDirectInput8W, (void**) &DirectInputObject, NULL)))
	{
		if(SUCCEEDED(DirectInputObject->CreateDevice(GUID_SysKeyboard, &KeyboardDevice, NULL)))
		{
			if(SUCCEEDED(KeyboardDevice->SetDataFormat(&c_dfDIKeyboard)))
			{
				if(SUCCEEDED(KeyboardDevice->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE))) //If non-Exclusive you have to reaquire the device when the window regains focus.
				{
					if(SUCCEEDED(KeyboardDevice->Acquire()))
					{
						KeyboardDeviceCreatedAndAquired = true;
					}
				}
			}
		}
	}

	return KeyboardDeviceCreatedAndAquired;
}
//=====================================================================================================================


//=====================================================================================================================
//  KeyboardClass::Update()
//
//	Purpose: 
//		To record any changes with the keys pressed.
//
//	Input:
//		None.
//
//	Output:
//		bool - false if there is a catastrophic keyboard error such as your dog eating the keyboard in the middle of your game.
//
//  Notes:
//		Basically records keys currently being pressed and returns true unless their was a catastrophic keyboard error.
//
//=====================================================================================================================
bool KeyboardClass::Update(void)
{
	bool DeviceStateRetrieved = false;

	if(SUCCEEDED(KeyboardDevice->GetDeviceState(sizeof(KeyBuffer), (LPVOID)&KeyBuffer)))
	{
		DeviceStateRetrieved = true;
	}

	return DeviceStateRetrieved;
}
//=====================================================================================================================


//=====================================================================================================================
//  KeyboardClass::KeyPressed()
//
//	Purpose: 
//		Tests whether a given keyboard key is currently depressed.
//
//	Input:
//		Key - integer representing the key you want to test.
//
//	Output:
//		bool - true if the key being tested is currently depressed.
//
//  Notes:
//		Hex 80 is 1000 0000 binary.		
//
//=====================================================================================================================
bool KeyboardClass::KeyPressed(int Key)
{
	bool KeyWasPressed = false;

	if(KeyBuffer[Key] & 0x80)	//This is a bitwise AND operation to allow you to specify whether this key is pressed.
	{
		KeyWasPressed = true;
	}
	return KeyWasPressed;
}
//=====================================================================================================================


//=====================================================================================================================
//  KeyboardClass::Shutdown()
//
//	Purpose: 
//		Cleanly shutdown keyboard control when the application shuts down.
//
//	Input:
//		None.
//
//	Output:
//		None.
//
//  Notes:
//		Because we are using DirectInput, DirectInput must be shutdown properly.
//
//=====================================================================================================================
void KeyboardClass::Shutdown(void)
{
	KeyboardDevice->Unacquire();
	KeyboardDevice->Release();
	KeyboardDevice = NULL;
	DirectInputObject->Release();
	DirectInputObject = NULL;
}
//=====================================================================================================================



KeyboardClass.h
#pragma once
#pragma comment(lib, "dinput8.lib")
#pragma comment(lib, "dxguid.lib")
#define DIRECTINPUT_VERSION 0x0800	//Used by #include <dinput.h> and therefore must go first.
#include <dinput.h>



//=====================================================================================================================
//  KeyboardClass
//
//	Purpose: 
//		To handle keyboard input from the user and obfuscate this from the programmer.
//
//  Notes:
//		As messed up as it is, Microsoft didn't bother to give us a way to handle keyboard input in DirectX! Instead, you 
//	are left trying to handle it some other way. I have no idea what MS was thinking on this one. Your options are to handle
//	keyboard input through the Windows event loop or to use some other API such as DirectInput. XInput is used to support the
//	XBox360 controller, but somehow they forgot to include keyboard support in that API.
//
//		We are using DirectInput, which is from DirectX8!!! (can you say "The 90's called and they want their API back!"?)
//	Granted, not a lot has changed with keyboards since DX8 was released November 2000, but still - we're going back to DX8
//	here? DX1 was only released 5 years prior to that. (Notice it has taken us 13 years to get from DX9 to DX11.)
//
//		Ok. Enough of my rant. The reason we are using DirectInput as opposed to the Windows event loop is that DirectInput
//	actualy lets you bypass Windows and get the input directly from the keyboard without hoping that Windows tells you about
//	the keyboard event in a timely manner. I mean, Windows will "probably" let you know in a timely manner, but why not cut
//	out the middle man. DirectInput gives you a lot more control over the situation albeit maybe this isn't a huge problem
//	either way.
//		
//		DirectInput also handles mouse and game controllers but we're only using it for the keyboard. Notice that we don't
//	have to add a Game Controller class to support the 360 controller, we merely have to #include <XInput.h> in our Game class. 
//	Who woulda thought that setting up the keyboard would be more difficult than setting up the 360 controller for a PC app.
//
//=====================================================================================================================
class KeyboardClass
{
	public:
		KeyboardClass(void);
		~KeyboardClass(void);
		bool Initialize(HINSTANCE hInstance, HWND hWnd);
		bool Update(void);
		bool KeyPressed(int Key);
		void Shutdown(void);
	private:
		LPDIRECTINPUT2W DirectInputObject;
		LPDIRECTINPUTDEVICEW KeyboardDevice;

		char KeyBuffer[256];
};
//=====================================================================================================================




GameTimer.CPP
#include "GameTimer.h"


//=====================================================================================================================
//  Constructor
//
//	Purpose: 
//		Initialize basic values for the GameTimer object.
//
//  Notes:
//		Not used unless you want to use it.
//
//=====================================================================================================================
GameTimer::GameTimer()
{
}
//=====================================================================================================================


//=====================================================================================================================
//  Destructor
//
//	Purpose: 
//		Shutdown anything created by this object and release any associated memory.
//
//  Notes:
//		Not used unless you want to use it.
//
//=====================================================================================================================
GameTimer::~GameTimer()
{
}
//=====================================================================================================================


//=====================================================================================================================
//  GameTimer::Initialize()
//
//	Purpose: 
//		
//	Input:
//		None.
//
//	Output:
//		bool - Returns true if the timer was setup correctly.
//
//  Notes:
//		Setup the game timer.
//		
//=====================================================================================================================
bool GameTimer::Initialize()
{
	bool GameTimerSetupProperly = false;
	
	QueryPerformanceFrequency((LARGE_INTEGER*)&Frequency); // Check to see if this system supports high performance timers.
	if(Frequency != 0)
	{
		TicksPerMS = (float)(Frequency / 1000);	// Find out how many times the frequency counter ticks every millisecond.
		QueryPerformanceCounter((LARGE_INTEGER*)&StartTime);

		GameTimerSetupProperly = true;
	}
	
	return GameTimerSetupProperly;
}
//=====================================================================================================================


//=====================================================================================================================
//  GameTimer::Update()
//
//	Purpose: 
//		To make the clock tick.
//
//	Input:
//		None.
//
//	Output:
//		None. But it updates MSSinceLastFrame for this object.
//
//  Notes:
//		This method calls the QueryPerformanceCounter function from the Windows API to get the system clock to calculate
//	how long it's been since the last time the timer object has been Updated. This is in "ticks" not anything directly 
//	related to seconds and so we have to convert the number of ticks since the last update to the number of milliseconds
//	since the last update. A millisecond is one thousandth of one second (0.001). There are 1,000 milliseconds in every 
//	second. Milliseconds seems to be a good unit to use for the time of a single draw frame.
//
//		This is where all the work is done for the clock and so it has to be called every frame.
//
//=====================================================================================================================
void GameTimer::Update()
{
	INT64 CurrentTime;
	float TimeDelta;


	QueryPerformanceCounter((LARGE_INTEGER*)&CurrentTime);	//From the Windows API.
	TimeDelta = (float)(CurrentTime - StartTime);	//Change in time since last frame measured in ticks.
	MSSinceLastFrame = TimeDelta / TicksPerMS;	//Convert time delta to milliseconds
	StartTime = CurrentTime;		// Restart the timer.

	return;
}
//=====================================================================================================================


//=====================================================================================================================
//  GameTimer::MilliSecondsSinceLastFrame()
//
//	Purpose: 
//		Queries the result of the timer's Update().
//
//	Input:
//		None.
//
//	Output:
//		float - Milliseconds since the last draw frame occured.
//
//  Notes:
//		This is allowing the Draw() and Update() methods for the game to have matching time values rather than requering
//	the clock for each with probably different results not to mention that it would no longer measure time between frames
//	but rather time between the Update() and the Draw(). 
//
//=====================================================================================================================
float GameTimer::MilliSecondsSinceLastFrame()
{
	return MSSinceLastFrame;
}
//=====================================================================================================================




GameTimer.h
#pragma once
#include <windows.h>

//=====================================================================================================================
//  GameTimer
//
//	Purpose: 
//		To act as the game clock to keep everything running at a constant speed inspite of diffences in CPU capability.
//
//  Notes:
//		Without this class or some sort of timer, the game would run as fast as the CPU is capable of running which not only
//	may change from computer to computer, but also may change from moment to moment depending on what other processes are
//	running in the background or what happens between draw frames.
//
//		This code acts as a clock to allow the programmer to ask "How much time has elapsed since the last frame?". By using 
//	the amount of time that has occured since the last time an Update() or Draw() call has been made (which is the last frame)
//	the program can calculate how much game objects need to be updated based on the amount of time that has passed.
//
//		So for example, without a timer, if you just tell a vehicle to move forward 1 meter it's speed would be completely 
//	dependent on how fast the CPU wants to run. That could be 1 meter per second or 1,000 meters per second depending on
//	how many frames the CPU can process in one second. With a timer, you can calculate the frames being drawn each second
//	and if you want the vehicle to move 1 meter per second you can multiply the speed of 1 meter by the percentage of one
//	second that has elapsed since the last frame was drawn. This will cause the vehicle to move 1 meter per second regardless
//	of how fast or slow the CPU and graphics card are.
//
//		The DirectX11Game class has a GameTimer member and thus "owns" this object. Since the Game class inherits from 
//	DirectX11Game, the Game class also "owns" this object and can reference it as it's own member.
//
//=====================================================================================================================
class GameTimer
{
	public:
		GameTimer();
		~GameTimer();

		bool Initialize();
		void Update();
		float MilliSecondsSinceLastFrame();

	private:
		INT64 Frequency;
		float TicksPerMS;
		INT64 StartTime;
		float MSSinceLastFrame;
};
//=====================================================================================================================




SceneObject.CPP
#include "SceneObjectClass.h"


//=====================================================================================================================
//  Constructor
//
//	Purpose: 
//		Initialize basic values for the SceneObjectClass object.
//
//  Notes:
//		Initialize variables to empty values.
//
//=====================================================================================================================
SceneObjectClass::SceneObjectClass(void)
{
	VertexBuffer = NULL;
	VerticesInMesh = 0;
	IndexBuffer = NULL;
	IndicesInMesh = 0;

	WorldMatrix = XMMatrixIdentity();
}
//=====================================================================================================================


//=====================================================================================================================
//  Destructor
//
//	Purpose: 
//		Do any cleanup before close down.
//
//  Notes:
//		Not used.
//
//=====================================================================================================================
SceneObjectClass::~SceneObjectClass(void)
{
}
//=====================================================================================================================


//=====================================================================================================================
//  SceneObjectClass::Transform()
//
//	Purpose: 
//		To allow the object to orbit, skew, or be moved at runtime. Mostly used to move.
//
//	Input:
//		CXMMATRIX TransformationMatrix - A matrix containing a transformation to be applied to the object's world matrix.
//
//	Output:
//		None.
//
//  Notes:
//		This provides an easy way to move, skew, or make this object orbit the origin by exposing changes to this object's world 
//	matrix while not directly exposing the object's world matrix as part of abstraction and obfuscation. 
//
//		This is an extremely powerful and yet simultaneously simple method.
//
//=====================================================================================================================
void SceneObjectClass::Transform(CXMMATRIX TransformationMatrix)
{
	WorldMatrix *= TransformationMatrix;
}
//=====================================================================================================================


//=====================================================================================================================
//  SceneObjectClass::TransformAtOrigin()
//
//	Purpose: 
//		To allow the object to be rotated and scaled properly.
//
//	Input:
//		CXMMATRIX TransformationMatrix - A matrix containing a transformation to be applied to the object's world matrix.
//
//	Output:
//		None.
//
//  Notes:
//		The problem with the Transform() method is that it makes it impossible to rotate the object, which is one of the primary
//	purposes of the transform. Instead, rotations cause the object to orbit the origin. This is a common rotation problem. In
//	order to solve the problem, you have to move the object to the origin, rotate it or scale it there, then move it back. This
//	is all done in between draw frames and so the viewer will never see that it was moved to the origin at all.
//
//		It must be done this way because you are actually rotating the vertices of the object around the origin. So, objects
//	away from the origin will orbit the origin instead of rotating around their center. You have to align the object's center to
//	the origin in order to rotate or scale around the object's center. Scaling is especially a mess if applied without doing this.
//
//		The method is pretty straight forward if not as straight forward as the Transform() method. It uses DX's XMMatrixDecompose
//	method to decompose the object's world matrix to get the object's position in 3D space. None of the other outputs are actually
//	used but they are required parameters and this is an easy way to get the object's position without knowing any matrix algebra.
//	The next thing is to build a translation matrix from the negative of the position we just obtained; this translation matrix is 
//	combined with the object's world matrix in order to move the object by the exact opposite amount of it's current position.
//	Think of the position as an arrow pointing from the origin to the position of the object. By reversing the direction of the 
//	arrow you have an arrow pointing from the objects position to the origin. By moving there, we move the object to the origin
//	but we have not altered our position value. Next we combine the transformation with the object's orientation and scale at the
//	origin. And then we move the object back to it's original position by reversing the process we did to move it to the origin.
//
//=====================================================================================================================
void SceneObjectClass::TransformAtOrigin(CXMMATRIX TransformationMatrix)
{
	XMVECTOR Position;					//Used to remember the original position of the object in the scene.
	XMVECTOR QuaternionOrientation;		//A quaternion that holds the objecj's orientation needed to decompose the object's world matrix.
	XMVECTOR Scale;						//Scale factor of the object decomposed from the object's world matrix.


	XMMatrixDecompose(&Scale, &QuaternionOrientation, &Position, WorldMatrix);
	WorldMatrix *= XMMatrixTranslationFromVector(-Position);
	WorldMatrix *= TransformationMatrix;
	WorldMatrix *= XMMatrixTranslationFromVector(Position);
}
//=====================================================================================================================


//=====================================================================================================================
//  SceneObjectClass::DefineMesh()
//
//	Purpose: 
//		To create an object to be drawn.
//
//	Input:
//		ID3D11Device* GraphicsDevice - Interface to DX.
//		ID3D11DeviceContext* GraphicsDeviceContext - Interface to DX.
//		int NumberOfVertices - Number of vertices in the vertex array.
//		SCENEOBJECTVERTEX* VertexList - Array of vertices. Allows you to make any object you want since you just pass it a buffer.
//		int NumberOfIndices - Number of indices in the index array.
//		unsigned int* Indices - Array of indices which specify what order to draw the vertices in.
//
//	Output:
//		bool - returns true if the object was created without problems.
//
//  Notes:
//		These objects are nothing but visable meshes without any collision detection or anything else. This method basically
//	takes a vertex buffer and stores it so it can be drawn in the scene.
//
//		A vertex buffer is created to hold the vertices of the object by first using a buffer description object. These buffers
//	can be used for different purposes and can be reconfigured to serve those purposes. The buffer description lets the graphics
//	card know how the data is to be used. The buffer might contain vertex data, or it might contain index data, or it might
//	contain texture data, or it might contain something else entirely.
//
//		DirectX and the graphics card are allowed to move these buffers around in memory and so there's no way to know exactly
//	where they are or be sure they will be there when you come back. We have to map the buffer to get a connection to it. In 
//	this case we create the buffer, map to the empty buffer, fill it with the vertex data passed in as a parameter, and then 
//	unmap the buffer. If it fails the method returns false. If the vertex buffer is created without a problem it does basically
//	the same thing to create the index buffer except we do not map into the buffer. If you are merely creating the data and 
//	then plan to leave it unchanged, you don't need to map the buffer but can instead use a D3D11_SUBRESOURCE_DATA object to
//	set the initial data in the buffer when you create it, which is in many ways more simple. But you do this with the 
//	CPUAccessFlags set to write only, promising you won't mess with the buffer after it is set which allows the graphics card
//	to be a bit more agressive in how it handles the buffer since it doesn't have to worry about you going in and changing the
//	buffer while it's working with the buffer.
//
//		The vertex buffer is created with the CPUAccessFlags set to allow you to come back and modify the buffer later which
//	requires that you map to the buffer in order to change the data in it.
//
//=====================================================================================================================
bool SceneObjectClass::DefineMesh(ID3D11Device* GraphicsDevice, 
							ID3D11DeviceContext* GraphicsDeviceContext,
							int NumberOfVertices, SCENEOBJECTVERTEX* VertexList, int NumberOfIndices, unsigned int* Indices)
{
	D3D11_BUFFER_DESC VertexBufferDescription;				//The settings for the vertex buffer.
	D3D11_BUFFER_DESC IndexBufferDescription;				//The settings for the index buffer.
	D3D11_SUBRESOURCE_DATA IndicesInitializationData;		//How a sub-resource is to be 
	bool MeshBuffersCreatedAndLoaded = false;				//flag to indicate if something went wrong.


	if (VertexBuffer == NULL)	//Don't try and create a vertex buffer for the object if it's already created.
	{
		VerticesInMesh = NumberOfVertices;											//We might want this info later so remember it.
		ZeroMemory(&VertexBufferDescription, sizeof(VertexBufferDescription));		//Initialize memory to zeros.
		VertexBufferDescription.Usage = D3D11_USAGE_DYNAMIC;						//Read-write access type for CPU and GPU
		VertexBufferDescription.ByteWidth = sizeof(SCENEOBJECTVERTEX) * NumberOfVertices;	//Total size of the vertex buffer.
		VertexBufferDescription.BindFlags = D3D11_BIND_VERTEX_BUFFER;				//Buffer is a vertex buffer.
		VertexBufferDescription.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;			//Allow CPU to write in buffer.
	
		if(SUCCEEDED(GraphicsDevice->CreateBuffer(&VertexBufferDescription, NULL, &VertexBuffer)))	//Create the vertex buffer or stop if it fails.
		{
			D3D11_MAPPED_SUBRESOURCE MappedSubResource;		//Used to connect us to the buffer so that we can modify it.
			if(SUCCEEDED(GraphicsDeviceContext->Map(VertexBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &MappedSubResource)))  //Map the buffer but stop if we can't.
			{
				memcpy(MappedSubResource.pData, VertexList, sizeof(SCENEOBJECTVERTEX) * VerticesInMesh);	//Copy the vertices into the buffer.
				GraphicsDeviceContext->Unmap(VertexBuffer, NULL); //Unmap the buffer.

				IndicesInMesh = NumberOfIndices;											//We might want this info later so remember it.
				ZeroMemory(&IndexBufferDescription, sizeof(IndexBufferDescription));		//Initialize the memory of the buffer description.
				IndexBufferDescription.Usage = D3D11_USAGE_DEFAULT;							//Requires read and write access.
				IndexBufferDescription.ByteWidth = sizeof(unsigned int) * IndicesInMesh;	//Size of the index buffer in bytes.
				IndexBufferDescription.BindFlags = D3D11_BIND_INDEX_BUFFER;					//This is an index buffer, not something else.
				IndexBufferDescription.CPUAccessFlags = 0;									//No CPU access will be necessary once the data is written.
				IndexBufferDescription.MiscFlags = 0;										//Unused.

				IndicesInitializationData.pSysMem = Indices;		//Connect data used to feed into the buffer.
				IndicesInitializationData.SysMemPitch = 0;			//Not used because this buffer is not a texture. 
				IndicesInitializationData.SysMemSlicePitch = 0;		//Not used because this buffer is not a texture.

				if(SUCCEEDED(GraphicsDevice->CreateBuffer(&IndexBufferDescription, &IndicesInitializationData, &IndexBuffer)))	//Create the index buffer or stop if it cannot.
				{
					MeshBuffersCreatedAndLoaded = true;		//Report back that the object was created successfully.
				}
			}
		}
	}

	return MeshBuffersCreatedAndLoaded;
}
//=====================================================================================================================


//=====================================================================================================================
//  SceneObjectClass::Draw()
//
//	Purpose: 
//		To draw the object on the screen each frame.
//
//	Input:
//		ID3D11DeviceContext* GraphicsDeviceContext - Interface to DX.
//		CXMMATRIX View - The view matrix containing the camera position and orientation.
//		CXMMATRIX Projection - The projection matrix containing how to project the 3D world on to a 2D screen.
//		ShaderClass Shader - The shader we are using to draw.
//		XMFLOAT3 DiffuseLightDirection - 3D vector pointing in the direction the light is shining in.
//		XMFLOAT4 AmbientLightColor - Light color applied to everything including shadow.
//		XMFLOAT4 DiffuseLightColor - Light color of our light source.
//
//	Output:
//		None.
//
//  Notes:
//		By the time you get to the draw method, everything is already done for this object. You just simply tell the shader
//	what the parameters are that we want to use when drawing this object, connect DX to the correct vertex buffer and index
//	buffer, tell it we want to draw this as a triangle list, etc. and then tell it to draw! We're done til next frame.
//
//		If you use something other than a triangle list you may have to change how you defined the triangles in the vertex 
//	buffer.
//		
//=====================================================================================================================
void SceneObjectClass::Draw(ID3D11DeviceContext* GraphicsDeviceContext, CXMMATRIX View, CXMMATRIX Projection, ShaderClass Shader, XMFLOAT3 DiffuseLightDirection, XMFLOAT4 AmbientLightColor, XMFLOAT4 DiffuseLightColor)
{
    UINT Stride = sizeof(SCENEOBJECTVERTEX);	//Stride is the size of 1 vertex in memory.
    UINT Offset = 0;	//Required input parameter not used. Can be used to store multiple meshes in one vertex buffer.


	Shader.Settings(GraphicsDeviceContext, WorldMatrix, View, Projection, DiffuseLightDirection, AmbientLightColor, DiffuseLightColor);
	GraphicsDeviceContext->IASetVertexBuffers(0, 1, &VertexBuffer, &Stride, &Offset);	//Select which vertex buffer to display.
	GraphicsDeviceContext->IASetIndexBuffer(IndexBuffer, DXGI_FORMAT_R32_UINT, 0);
	GraphicsDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);	//Select which primtive type we are using.

	GraphicsDeviceContext->DrawIndexed(IndicesInMesh, 0, 0);
}
//=====================================================================================================================


//=====================================================================================================================
//  SceneObjectClass::Shutdown()
//
//	Purpose: 
//		To do release the vertex and index buffers and anything else this class uses.
//
//	Input:
//		None.
//
//	Output:
//		None.
//
//  Notes:
//		This should be called before the object is destroyed and this is important. We don't want DX wasting memory we are
//	no longer using.
//		
//=====================================================================================================================
void SceneObjectClass::Shutdown(void)
{
	if (IndexBuffer !=NULL)
	{
		IndexBuffer->Release();
		IndexBuffer = NULL;
	}
	IndicesInMesh = 0;
	if (VertexBuffer != NULL)
	{
		VertexBuffer->Release();	//Destroy the vertex buffer and release it's memory.
		VertexBuffer = NULL;
	}
	VerticesInMesh = 0;
}
//=====================================================================================================================




SceneObject.h
#pragma once
#include <d3d11.h>
#include <d3dx11.h>
#include "ShaderClass.h"


//=====================================================================================================================
//	SCENEOBJECTVERTEX is our vertex structure we're using. You can define a vertex pretty much any way you like and include
//	or not include any information you like it it, but the graphics card needs to know what every byte in the vertex means.
//	Position is the only thing absolutely required in a vertex. The vertex color is attached to each vertex and can change
//	from vertex to vertex the way our shader is setup. You might not use that if you were using textures to determine color.
//	The vertex normal is the direction the vertex faces as a 3D vector. The UV coordinates are used for textures which are
//	not done in this example, but I wanted to stick with a consistent vertex format for awhile to make things less confusing
//	and I plan on introducing textures in the next tutorial. Unused space in a vertex like this is wasteful but it won't 
//	hurt anything for these tutorials.
//=====================================================================================================================
struct SCENEOBJECTVERTEX{XMFLOAT3 Position; XMFLOAT2 UV; XMFLOAT3 Normal; XMFLOAT4 Color;};	//Describes the structure of our vertices.


//=====================================================================================================================
//  SceneObjectClass
//
//	Purpose: 
//		To encapsulate most of the code needed to draw an object into the scene.
//
//  Notes:
//		This class makes it relatively easy to create multiple objects and put them in the scene including some simple 
//	animation of these objects. By allowing a vertex and index array to be passed in when creating the object, it gives
//	complete control of the shape of the object and allows for any shape you wish to create.
//
//		Without this class you would have to repreat nearly identical code for every object in the scene. With it, putting
//	an object in the scene is pretty much as easy as specifiyng what the vertices and indices of the object are.
//
//		If you are not familiar with vertices and indices, vertices are the corners of your triangle. 3 vertices make a
//	triangle and all the graphics card does is draw triangles. You can make some extremly sophisticated triangles using
//	DirectX. But even very complex shaped objects are made up of triangles 100% of the time. A vertex can contain many
//	different types of data and we define what we want in our SCENEOBJECTVERTEX structure above. Position is the only
//	piece of data always required and specifies the position of the 3D vertex in space.
//
//		A triangle list is used for the vertex buffer which means every 3 vertices in the buffer make 1 triangle. The 
//	rasterizer stage of the graphics card between the shader's vertex and pixel shader takes those 3 vertices and shades
//	in the shape of a triangle beween them. The color of each pixel in that shaded in region is determined by the pixel
//	shader.
//
//		The index buffer is a list that gives the order that each vertex is to be drawn in. This not only allows them to 
//	be specified out of order, but also allows for vertices to be reused which can be much more efficient if you have a
//	lot of identical vertices. But the vertices have to be complely identical which means not just their positions are
//	identical.
//
//		You may want to create some of your own objects using your own shapes beyond what is in this tutorial. But you
//	will discover very soon that building these objects by hand is beyond tedious. You'll be looking for a better way after
//	you've created a couple objects that way. Even simple cubes are enormously difficult to create this way. Now imagine
//	creating objects with a more typical 3,000 vertices in them this way. Not fun. In future tutorials I will create a
//	"model" class that will read data created in Blender (or some other 3D modeling program) in order to specify the 
//	object and so this class is something we'll be getting rid of in the future unlike pretty much all the other classes
//	here which we will likely be using with minimum modification for a long time to come. But this class is something we
//	will expand upon to make our model class which will be used more long term. Almost all the concepts here will be 
//	reused for that.
//
//		This class has two transform methods. The Transform() method allows you to move the object you've created here.
//	The TransformAtOrigin() method solves some major problems with the Transform() method such as rotations causing the
//	object to orbit rather than rotate around its own center and not scaling properly. But it is very inefficient to 
//	use to move the object although it should work if you did. That's why there is also a Transform() method along with
//	the fact that maybe you want the object to orbit the origin... probably not. You could also expose the object's 
//	world matrix more directly, but that would not be following OOP philosophy. It also might have made it less clear
//	that rotating an object at any place other than the origin will cause it to orbit. 
//
//=====================================================================================================================
class SceneObjectClass
{
	public:
		SceneObjectClass(void);
		~SceneObjectClass(void);
		bool DefineMesh(ID3D11Device* GraphicsDevice, ID3D11DeviceContext* GraphicsDeviceContext, int NumberOfVertices, SCENEOBJECTVERTEX* VertexList, int NumberOfIndices, unsigned int* Indices);
		void Transform(CXMMATRIX TransformationMatrix);
		void TransformAtOrigin(CXMMATRIX TransformationMatrix);
		void Draw(ID3D11DeviceContext* GraphicsDeviceContext, CXMMATRIX View, CXMMATRIX Projection, ShaderClass Effect, XMFLOAT3 DiffuseLightDirection, XMFLOAT4 AmbientLightColor, XMFLOAT4 DiffuseLightColor);
		void Shutdown(void);

	private:
		ID3D11Buffer* VertexBuffer;                 //The pointer to the vertex buffer
		ID3D11Buffer* IndexBuffer;					//The pointer to the index buffer.
		XMMATRIX WorldMatrix;						//The object's world matrix which holds the object's position, scale, and orientation.
		int VerticesInMesh;							//Number of vertices used in the mesh.
		int IndicesInMesh;							//Number of indices used in the index buffer.
};
//=====================================================================================================================





ShaderClass.CPP
#include "ShaderClass.h"


//=====================================================================================================================
//  Constructor
//
//	Purpose: 
//		Initialize basic values for the ShaderClass object.
//
//  Notes:
//		Not used.
//
//=====================================================================================================================
ShaderClass::ShaderClass(void)
{
}
//=====================================================================================================================


//=====================================================================================================================
//  Destructor
//
//	Purpose: 
//		
//
//  Notes:
//		Not used.
//
//=====================================================================================================================
ShaderClass::~ShaderClass(void)
{
}
//=====================================================================================================================


//=====================================================================================================================
//  ShaderClass::Initialize()
//
//	Purpose: 
//		To setup our shaders so that we can use them to draw to the screen.
//
//	Input:
//		ID3D11Device* GraphicsDevice - DirectX device COM interface
//		ID3D11DeviceContext* GraphicsDeviceContext - DirectX device context COM interface
//
//	Output:
//		bool - The shaders compiled and were setup properly if true.
//
//  Notes:
//		This is about half the code here. It takes the source code for the two shaders and compiles them. Then it tells DX
//	about them so that DX can use them. It then defines a vertex format. Then it defines two constant buffers to handle the
//	data that we are sending to these two shaders every frame. And it attaches all this to the graphic pipeline (graphics card)
//	to be used for drawing. You're pretty much ready to draw at that point.
//
//		The vertex format describes the "input layout". In other words it describes the structure of every vertex going in to
//	the vertex buffer. In our case, for this shader, we are going to define a vertex as a position, a texture coordinate,
//	a normal to describe what direction the vertex "faces", and a color for the vertex. Position is the only thing required
//	in order to have a vertex. We are not using textures yet, but I decided to throw it in for consistancy which is really
//	a waste of memory, but we'll want to include textures 99.9% of the time once we start doing them. Color might be useless
//	at that point since you'll take the color from the texture unless you want to do some sort of fancy trick with the color
//	(like make a black and white texture and use the vertex colors to control what color is in the white area without additional
//	textures). This is more of an example than anything, and you may want to optimize your vertex format to only include data
//	you actually use in the shader. If the shader doesn't care, then it's a waste to include it, but starting out including 
//	all four will be easier for now.
//
//		Each vertex element has a color format that describes how the data is laid out in that single element. The vertex buffer
//	is just a very long row of bytes that is not strongly typed at all. This vertex definition is what is typing it. So, you
//	have to break each element up into it's proper bytes. RGB is Red, Green, and Blue which can be combined to form any color.
//	In this case Position is defined as three 32 bit numbers. The colors there are totally irrelevant but it divides it nicely
//	into three 32 bit elements (X, Y, and Z). The Texture Coordinate is two elements (U & V). The normal is a 3D vector and
//	contains the X, Y, and Z values of the position of the arrow head. Oh hey! We actually have a color element! Go figure.
//	The vertex color is an RGBA which stands for red, green, blue, alpha. Alpha is transparency and represents what percentage
//	of the vertex color to use and what percentage to blend in with the background color to make it transparent. There are
//	different methods for representing RGBA and these are all 32 bit floating values where max value is 100% and min value is 0%.
//	By mixing the 3 colors you can create any imaginable color.
//
//=====================================================================================================================
bool ShaderClass::Initialize(ID3D11Device* GraphicsDevice, ID3D11DeviceContext* GraphicsDeviceContext)
{
	bool ShaderCompiledAndSetupProperly = false;	//Assume we've failed until we succeed.
    ID3D10Blob *VS, *PS;
	ID3DBlob *errMsg = NULL;

	
	if(SUCCEEDED(D3DX11CompileFromFile("PhongShader.hlsl", 0, 0, "VertexShaderMain", "vs_5_0", 0, 0, 0, &VS, 0, 0)))
	{
		if(SUCCEEDED(D3DX11CompileFromFile("PhongShader.hlsl", 0, 0, "PixelShaderMain", "ps_5_0", 0, 0, 0, &PS, 0, 0)))
		{ 
			if(SUCCEEDED(GraphicsDevice->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &VertexShader)))
			{
				if(SUCCEEDED(GraphicsDevice->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &PixelShader)))
				{
					// set the shader objects that will be used to render.
					GraphicsDeviceContext->VSSetShader(VertexShader, 0, 0);
					GraphicsDeviceContext->PSSetShader(PixelShader, 0, 0);

					// create the input layout object (vertex layout for the vertex buffer).
					D3D11_INPUT_ELEMENT_DESC InputElementDescription[] =
					{
						{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},		//Begins at offset 0 bytes.
						{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},		//Begins at offset 12 bytes.
						{"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0},		//Begins at offset 20 bytes.
						{"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 32, D3D11_INPUT_PER_VERTEX_DATA, 0},	//Begins at offset 32 bytes.
					};

					if(SUCCEEDED(GraphicsDevice->CreateInputLayout(InputElementDescription, 4, VS->GetBufferPointer(), VS->GetBufferSize(), &InputLayout)))
					{
						GraphicsDeviceContext->IASetInputLayout(InputLayout);
						if(AttachWVPMatricesToPipeline(GraphicsDevice)) 
						{
							if(AttachParametersToPipeline(GraphicsDevice))
							{
								ShaderCompiledAndSetupProperly = true;
							}
						}
					}
				}
			}
		}
	}
	return ShaderCompiledAndSetupProperly;
}
//=====================================================================================================================


//=====================================================================================================================
//  ShaderClass::Shutdown()
//
//	Purpose: 
//		To release all the resources associated with the shader when closing the application.
//
//	Input:
//		None.
//
//	Output:
//		None.
//
//  Notes:
//		This is all COM object stuff with DirectX so you merely call each object's Release() method.
//=====================================================================================================================
void ShaderClass::Shutdown(void)
{
	ParametersBuffer->Release();
	MatrixConstantBuffer->Release();
	InputLayout->Release();
	VertexShader->Release();
	PixelShader->Release();
}
//=====================================================================================================================


//=====================================================================================================================
//  ShaderClass::AttachWVPMatricesToPipeline()
//
//	Purpose: 
//		To release all the resources associated with the shader when closing the application.
//
//	Input:
//		ID3D11Device* GraphicsDevice - The DX COM object Device interface that allows us to talk to DX.
//
//	Output:
//		bool - false if the buffer was not created properly.
//
//  Notes:
//		This was mainly seperated from the Initialize() code because that section of the code was getting too long to read.
//	One of the last processes in initializing the shader is to attach the resources to the shader.
//
//		Here we're merely creating a constant buffer where the ByteWidth defines the size of the buffer as:
//			XMMATRIX WorldMatrix;
//			XMMATRIX ViewMatrix;
//			XMMATRIX ProjectionMatrix;
//
//		So this buffer is created to pass the shader these three matrices every draw frame in order to describe the object's
//	position and orientation in the scene, the camera's position and orientation in the scene, and the projection matrix with
//	the info to convert the 3D world into a 2D image that can be drawn on a 2D computer monitor.
//
//=====================================================================================================================
bool ShaderClass::AttachWVPMatricesToPipeline(ID3D11Device* GraphicsDevice)
{
	bool ConstantBufferForMVPMatricesAttached = false;
	D3D11_BUFFER_DESC MatrixConstantBufferDescription;


	ZeroMemory(&MatrixConstantBufferDescription, sizeof(MatrixConstantBufferDescription));
	MatrixConstantBufferDescription.Usage = D3D11_USAGE_DYNAMIC;
	MatrixConstantBufferDescription.ByteWidth = sizeof(MatrixBufferType);
	MatrixConstantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	MatrixConstantBufferDescription.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    MatrixConstantBufferDescription.MiscFlags = 0;
	MatrixConstantBufferDescription.StructureByteStride = 0;
	
	if(SUCCEEDED(GraphicsDevice->CreateBuffer(&MatrixConstantBufferDescription, NULL, &MatrixConstantBuffer)))
	{
		ConstantBufferForMVPMatricesAttached = true;
	}
	return ConstantBufferForMVPMatricesAttached;
}
//=====================================================================================================================


//=====================================================================================================================
//  ShaderClass::AttachParametersToPipeline()
//
//	Purpose: 
//		To create a constant buffer that will be used to pass all other parameters to the shader other than matrices.
//
//	Input:
//		ID3D11Device* GraphicsDevice - The DX COM object Device interface that allows us to talk to DX.
//
//	Output:
//		bool - false if the buffer was not created properly.
//
//  Notes:
//		This was mainly seperated from the Initialize() code because that section of the code was getting too long to read.
//	One of the last processes in initializing the shader is to attach the resources to the shader.
//
//		Here we're merely creating a constant buffer where the ByteWidth defines the size of the buffer as (in the header file):
//			XMFLOAT4 AmbientLightColor; 
//			XMFLOAT3 DiffuseLightDirection;
//			float Padding;	//Necessary because the buffer needs to be aligned to 4 floats and so a XMFLOAT3 needs an extra float value.
//			XMFLOAT4 DiffuseLightColor;
//			XMFLOAT4 CameraPosition;
//
//		The shaders use these parameters to set the lighting colors and direction that the light source is shining in. The
//	CameraPosition is used to calculate the specular reflection and is why there is a method here to return the camera position
//	taken from the view matrix as a vector. 
//
//=====================================================================================================================
bool ShaderClass::AttachParametersToPipeline(ID3D11Device* GraphicsDevice)
{
	bool ConstantBufferForParametersAttached = false;
	HRESULT hr;
	D3D11_BUFFER_DESC ParametersConstantBufferDescription;


	ZeroMemory(&ParametersConstantBufferDescription, sizeof(ParametersConstantBufferDescription));
	ParametersConstantBufferDescription.Usage = D3D11_USAGE_DYNAMIC;
	ParametersConstantBufferDescription.ByteWidth = sizeof(ParametersBufferType);
	ParametersConstantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	ParametersConstantBufferDescription.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
	ParametersConstantBufferDescription.MiscFlags = 0;
	ParametersConstantBufferDescription.StructureByteStride = 0;

	if(SUCCEEDED(hr = GraphicsDevice->CreateBuffer(&ParametersConstantBufferDescription, NULL, &ParametersBuffer)))
	{
		ConstantBufferForParametersAttached = true;
	}
	else
	{
		DXTRACE_ERR("Failed to create Parameter's buffer for the shader!", hr);
	}

	return ConstantBufferForParametersAttached;
}
//=====================================================================================================================


//=====================================================================================================================
//  ShaderClass::Settings()
//
//	Purpose: 
//		To pass the parameters from our application to the shader every draw frame.
//
//	Input:
//		ID3D11DeviceContext* GraphicsDeviceContext - The DX Com interface we use to call DX.
//		CXMMATRIX World	- Object's position, orientation, and scale in the scene.
//		CXMMATRIX View	- The camera's position and orientation.
//		CXMMATRIX Projection - Data to convert the 3D world into a 2D image.
//		XMFLOAT3 DiffuseLightDirection - Direction our global light source shines in.
//		XMFLOAT4 AmbientLightColor - Color of light everything will receive including shadows.
//		XMFLOAT4 DiffuseLightColor - Color of our light source.
//
//	Output:
//		bool - false if the buffer was not created properly.
//
//  Notes:
//		Mapping the buffers allows their contents to be changed.
//
//=====================================================================================================================
bool ShaderClass::Settings(ID3D11DeviceContext* GraphicsDeviceContext, 
						   CXMMATRIX World, CXMMATRIX View, CXMMATRIX Projection, 
						   XMFLOAT3 DiffuseLightDirection, XMFLOAT4 AmbientLightColor, XMFLOAT4 DiffuseLightColor)
{
	bool ConstantBuffersUpdated = false;		//Assume this method has failed until we succeed.
	MatrixBufferType* MatricesPointer;			//Data structure to hold all the matrices.
	ParametersBufferType* ParametersPointer;	//Data structure to hold al non-matrix parameters.
	HRESULT hr;									//DirectX likes to return it's results this way. We need it to get full detail error messages.
	D3D11_MAPPED_SUBRESOURCE MappedSubResource;


	if(SUCCEEDED(hr = GraphicsDeviceContext->Map(MatrixConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedSubResource)))
	{
		MatricesPointer = (MatrixBufferType*)MappedSubResource.pData;	//Re-"type" the buffer.
		MatricesPointer->WorldMatrix = XMMatrixTranspose(World);
		MatricesPointer->ViewMatrix = XMMatrixTranspose(View);
		MatricesPointer->ProjectionMatrix = XMMatrixTranspose(Projection);
		GraphicsDeviceContext->Unmap(MatrixConstantBuffer, 0 );
		
		// Now set the constant buffer in the vertex shader with the updated values.
		GraphicsDeviceContext->VSSetConstantBuffers(0, 1, &MatrixConstantBuffer);	//Assigned to Vertex Shader.

		if(SUCCEEDED(hr = GraphicsDeviceContext->Map(ParametersBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedSubResource)))
		{
			ParametersPointer = (ParametersBufferType*)MappedSubResource.pData;	//Re-"type" the buffer.
			ParametersPointer->AmbientLightColor = AmbientLightColor;
			ParametersPointer->DiffuseLightDirection = DiffuseLightDirection;
			ParametersPointer->Padding = 0.0f;
			ParametersPointer->DiffuseLightColor = DiffuseLightColor;
			ParametersPointer->CameraPosition = GetCameraPosition(View);
			GraphicsDeviceContext->Unmap(ParametersBuffer, 0);

			GraphicsDeviceContext->PSSetConstantBuffers(0, 1, &ParametersBuffer);	//Assigned to Pixel Shader.
			ConstantBuffersUpdated = true;
		}
	}
	else
	{
		DXTRACE_ERR("Failed to create World, View, Projection Matrices constant buffer!", hr);
	}


	return ConstantBuffersUpdated;
}
//=====================================================================================================================


//=====================================================================================================================
//  ShaderClass::GetCameraPosition()
//
//	Purpose: 
//		To extract the camera position from a given View matrix as a 3D vector.
//
//	Input:
//		CXMMATRIX ViewMatrix
//
//	Output:
//		XMFLOAT4 - A 3D (or actually 4D) vector describing the position of the camera plus an unused 'w' component.
//
//  Notes:
//		This was necessary because the Blinn Phong shader needs to know where the camera is positioned in order to calculate
//	the specular light correctly. It uses DX's XMMatrixDecompose() method to decompose a matrix into the position, orientation,
//	and scale information it contains.
//
//		This could probably be incorporated into the shader itself to be more efficient. We're basically submitting this 
//	information to the shader twice, once in the view matrix and then as a seperate camera position matrix. But this was 
//	easier.
//
//=====================================================================================================================
XMFLOAT4 ShaderClass::GetCameraPosition(CXMMATRIX ViewMatrix)
{
	XMVECTOR Position;				//Our position but must be converted when passes as a parameter.
	XMVECTOR QuaternionOrientation;	//We don't care but it's a required parameter.
	XMVECTOR Scale;					//We don't care but it's a required parameter.
	XMFLOAT4 CamerasPosition;		//The information we're looking for.
	XMVECTOR Determinant;			//Unused required parameter.
	XMMATRIX DeInversedViewMatrix;	//View matrices are always inversed, by definition. That has to be done to get useful info out of it.


	DeInversedViewMatrix = XMMatrixInverse(&Determinant, ViewMatrix);	//Convert View matrix to a "camera world" matrix.
	XMMatrixDecompose(&Scale, &QuaternionOrientation, &Position, DeInversedViewMatrix);	//Pull data out of the matrix to be used.
	XMStoreFloat4(&CamerasPosition, Position);	//Set the return value as a 3D(+w) position "vector".

	return CamerasPosition;
}
//=====================================================================================================================




ShaderClass.h
#pragma once
#include <d3d11.h>
#include <d3dx11.h>
#include <DirectXMath.h>
#include <DirectXColors.h>
#include <DirectXCollision.h>
#include <DxErr.h>

using namespace DirectX; 


struct MatrixBufferType
{
	XMMATRIX WorldMatrix;
	XMMATRIX ViewMatrix;
	XMMATRIX ProjectionMatrix;
};

struct ParametersBufferType
{
	XMFLOAT4 AmbientLightColor; 
	XMFLOAT3 DiffuseLightDirection;
	float Padding;	//Necessary because the buffer needs to be aligned to 4 floats and so a XMFLOAT3 needs an extra float value.
	XMFLOAT4 DiffuseLightColor;
	XMFLOAT4 CameraPosition;
};


//=====================================================================================================================
//  ShaderClass
//
//	Purpose: 
//		To manage the shaders used to draw images on the screen.
//
//  Notes:
//		Shaders are programs that do the work of drawing things on the screen. You always have at least a vertex shader and
//	a pixel shader. In DX, we write our shader programs in High Level Shader Language (HLSL) to tell the graphics card how
//	to function. There was a time when this was all hardwired into a graphics card and was not programmable at all. But those
//	days are long gone and now DX11 doesn't know how to draw anything unless you write a shader to tell it how. So, we're 
//	forced to learn the "intermediate to advanced" topic of shaders right off the top. (Although, the entire subject of C++
//	and DirectX is not exactly "beginner" stuff, so if you've made it this far, you'll be fine.
//
//		Inspite of all the hype around shaders, you really only need a couple of them to make an almost infinante number of 
//	games. The Blinn Phong shader is what we're going to use for just about everything for awhile.
//
//		This shader is all contained in the "PhongShader.hlsl" file which is source code for our shader that is compiled at 
//	runtime when the program starts. It first calls the "VertexShaderMain" function and then will call the "PixelShaderMain" 
//	function. But before it can use them it must compile them and tell DX about them. It also attaches two resources which are
//	constant buffers to the graphics pipeline. There's a lot of techno jargon there... The constant buffers are called that 
//	because they are visable anywhere inside the shader like global variables. We use them to pass data from our program into
//	the shader. In this case we have one buffer to pass the three matrix parameters which are the world, view, and projection
//	matrices. And we have another buffer to pass the regular parameters like light color and direction the light is shining in.
//	These parameters may change every draw frame and so the Settings() method allows these to be passed to the shaders on the
//	graphics card every frame.
//
//		The "graphics pipeline" is just industry jargon for the "processes that occur to put stuff on the screen". It's almost
//	synonomous with "the graphics card". It basically consists of loading buffers with data for the shaders and then running
//	the shaders to draw stuff on the screen each frame. Don't let this term intimidate you. If you master the graphics pipeline
//	you've pretty much mastered DirectX, or DirectDraw anyway. When people talk about the Graphics Pipeline they are usually
//	talking about the vertex and pixel shader and maybe other processes on the graphics card which are often optional such
//	as the tesselation shader. With DX11 we have a "programmable graphics pipeline" which just means that we can write shader
//	instead of the non-programmable graphics pipeline where you just told the graphics card what you wanted to draw and could
//	not program shaders to tell it how to carry out the drawing. "Graphics Pipeline" makes it sound like there is this whole long
//	complicated process you have to go through to draw stuff, which is not the case. You load a vertex buffer up with information
//	to describe an object and you tell the shaders to draw it. That's it. The rest is passing data to the graphics card to tell it
//	how to actually draw it and then running the shaders to do it. Because its all programmable there's almost an infinate number
//	of ways to carry this out. But the example here, will allow you to create an infinate number of games without going any further.
//	You'll probably want to add texturing to this and maybe a few other minor things, but this isn't as hard as it seems at first.
//	And terms like "graphics pipeline" just make it sound that much worse.
//
//=====================================================================================================================
class ShaderClass
{
	public:
		ShaderClass(void);
		~ShaderClass(void);
		bool Initialize(ID3D11Device* GraphicsDevice, ID3D11DeviceContext* GraphicsDeviceContext);
		bool Settings(ID3D11DeviceContext* GraphicsDeviceContext, CXMMATRIX World, CXMMATRIX View, CXMMATRIX Projection, XMFLOAT3 DiffuseLightDirection, XMFLOAT4 AmbientLightColor, XMFLOAT4 DiffuseLightColor);
		void Shutdown(void);
	private:
		ID3D11Buffer* MatrixConstantBuffer;
		ID3D11Buffer* ParametersBuffer;
		ID3D11InputLayout* InputLayout;            // the pointer to the input layout
		ID3D11VertexShader* VertexShader;               // the pointer to the vertex shader
		ID3D11PixelShader* PixelShader;                // the pointer to the pixel shader
		bool AttachWVPMatricesToPipeline(ID3D11Device* GraphicsDevice);
		bool AttachParametersToPipeline(ID3D11Device* GraphicsDevice);
		XMFLOAT4 ShaderClass::GetCameraPosition(CXMMATRIX ViewMatrix);
};
//=====================================================================================================================




Game.CPP
#include "Game.h"


Game::Game(void)
{
}


Game::~Game(void)
{
}


//=====================================================================================================================
//  Game::Initialize()
//
//	Purpose: 
//		To allow any code you want to run once at startup not associated with art assets.
//
//	Input:
//		None.
//
//	Output:
//		bool - The program will close if it returns false assuming a catastrophic error has occured.
//
//  Notes:
//		
//
//=====================================================================================================================
bool Game::Initialize()
{
	bool GameObjectInitializedProperly = false;		//Must be set to true to keep the program from closing.
	D3D11_VIEWPORT DXViewPort;						//Used to query the screen aspect ratio for the Projection matrix.
	UINT NumberOfViewPorts = 1;						//Required by RSGetViewports.


	GraphicsDeviceContext->RSGetViewports(&NumberOfViewPorts, &DXViewPort);		//Get a pointer to the viewport so we can ask it what it's aspect ratio is.
	Projection = XMMatrixPerspectiveFovRH(XM_PIDIV4, DXViewPort.Width/DXViewPort.Height, 0.1f, 1000.0f); //Create a RH Perspective Projection matrix.

	GameObjectInitializedProperly = Shader.Initialize(GraphicsDevice, GraphicsDeviceContext);	//Do any initialization required for the Shader class and fail if it fails.
		
	InFullScreenMode = false;	//Running in windowed mode makes debugging easier.

	CameraHeight = 1.68f;		//Roughly the average eye height in meters of an average man. Our camera will stay at this level to make it feel like we are in the scene.
	CameraFacingNormal = XMVectorSet(0.0f, -1.0f, 0.0f, 0.0f);	//Probably needs a rewrite but this is actually used as a 2D vector.
	CameraPosition = XMVectorSet(0.0f, 10.0f, 0.0f, 0.0f);		//Looking into the scene and positioned to the side.

	DiffuseLightDirection = XMFLOAT3(0.0f, -1.0f, 0.0f);	//3D Normal pointing in the direction the global scene light is shining in.
	XMStoreFloat3(&DiffuseLightDirection, XMVector3Normalize(XMLoadFloat3(&DiffuseLightDirection)));	//Normalize just incase the programmer forgets to. Set the length of the vector to 1.

	DiffuseLightColor = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f);	//Set the color of the scene light.
	AmbientLightColor = XMFLOAT4(0.0f, 0.0f, 0.07f, 1.0f);	//Light added to everything in the scene including shadow areas.

	return GameObjectInitializedProperly;
}
//=====================================================================================================================


//=====================================================================================================================
//  Game::LoadContent()
//
//	Purpose: 
//		To allow any code you want to run once at startup associated with art assets.
//
//	Input:
//		None.
//
//	Output:
//		bool - The program will close if it returns false assuming a catastrophic error has occured.
//
//  Notes:
//		Here we are creating all the objects in the scene. The switch statement makes it easy to manage this and add more
//	objects of your own. You merely define all the objects vertices it will need to be drawn and then list the index order
//	of every vertex to specify what order it will be drawn in. These examples merely count the number of vertices for the
//	index which is largely pointless. However, the design means you "could" reuse vertices or specify them out of order and
//	use the index buffer to specify what order to draw them in.
//
//		You'll quickly notice that the number of vertices you have to specify for even the most simple of objects is nearly
//	unacceptable. There are better ways, but we're learning the most straight forward way here which we will build on later.
//
//=====================================================================================================================
bool Game::LoadContent()
{
   	bool NoCatastrophicFailuresOccured = false;	//Close the program if even one mesh fails to initialize correctly.
	int x = 0;		//Which object.
	bool AllMeshesDefined = false;	//Flag to close the program if something goes wrong.


	//Define vertices and attempt to initialize mesh for each object. 
	do
	{
		x++;
		switch (x)
		{
		case 1:
			{
				SCENEOBJECTVERTEX GroundVertexList[6] =
				{
					{ XMFLOAT3(-10.0f, 0.0, 10.0f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(-10.0f, 0.0f, -10.0f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(10.0f, 0.0f, -10.0f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },

					{ XMFLOAT3(10.0f, 0.0f, -10.0f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(10.0f, 0.0f, 10.0f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(-10.0f, 0.0, 10.0f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) }
					

				};
				unsigned int GroundIndexList[6] = {0, 1, 2, 3, 4, 5};

				NoCatastrophicFailuresOccured = Ground.DefineMesh(GraphicsDevice, GraphicsDeviceContext, 6, GroundVertexList, 6, GroundIndexList);
				break;
			}
		case 2:
			{
				SCENEOBJECTVERTEX TriangleVertexList[3] =
				{
					{XMFLOAT3(0.0f, 0.5f, 0.0f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f)},
					{XMFLOAT3(0.45f, -0.5, 0.0f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f)}, 
					{XMFLOAT3(-0.45f, -0.5f, 0.0f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f)}
				};
				unsigned int TriangleIndexList[3] = {0, 1, 2};
				NoCatastrophicFailuresOccured = Triangle.DefineMesh(GraphicsDevice, GraphicsDeviceContext, 3, TriangleVertexList, 3, TriangleIndexList);
				Triangle.Transform(XMMatrixTranslation(1.0f, 2.0f, 1.0f));	//Position this object in the scene.
				break;
			}
		case 3:
			{
	
				SCENEOBJECTVERTEX CubeVertexList[VERTICESINCUBE] =
				{
					//Front Quad. 
					{ XMFLOAT3(0.5f, -0.5f, 0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(-0.5f, -0.5f, 0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(-0.5f, 0.5f, 0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },

					{ XMFLOAT3(-0.5f, 0.5f, 0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(0.5f, 0.5f, 0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(0.5f, -0.5f, 0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
										
					//Right Quad.
					{ XMFLOAT3(0.5f, -0.5f, -0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(1.0f, 0.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(0.5f, -0.5f, 0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(1.0f, 0.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(0.5f, 0.5f, 0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(1.0f, 0.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },

					{ XMFLOAT3(0.5f, 0.5f, 0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(1.0f, 0.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(0.5f, 0.5f, -0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(1.0f, 0.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(0.5f, -0.5f, -0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(1.0f, 0.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					
					//Bottom Quad. 
					{ XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, -1.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(-0.5f, -0.5f, 0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, -1.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(0.5f, -0.5f, 0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, -1.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					
					{ XMFLOAT3(0.5f, -0.5f, 0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, -1.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(0.5f, -0.5f, -0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, -1.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, -1.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					
					//Back Quad. 
					{ XMFLOAT3(-0.5f, 0.5f, -0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(0.5f, -0.5f, -0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					
					{ XMFLOAT3(0.5f, -0.5f, -0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(0.5f, 0.5f, -0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(-0.5f, 0.5f, -0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					
					//Left Quad.
					{ XMFLOAT3(-0.5f, 0.5f, 0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(-1.0f, 0.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(-0.5f, -0.5f, 0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(-1.0f, 0.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(-1.0f, 0.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					
					{ XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(-1.0f, 0.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(-0.5f, 0.5f, -0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(-1.0f, 0.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(-0.5f, 0.5f, 0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(-1.0f, 0.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					
					//Top Quad. 
					{ XMFLOAT3(0.5f, 0.5f, 0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(-0.5f, 0.5f, 0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(-0.5f, 0.5f, -0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },

					{ XMFLOAT3(-0.5f, 0.5f, -0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(0.5f, 0.5f, -0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					{ XMFLOAT3(0.5f, 0.5f, 0.5f), XMFLOAT2(0.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
					
				};
				unsigned int CubeIndexList[VERTICESINCUBE] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35 };

			
				NoCatastrophicFailuresOccured = YellowCube.DefineMesh(GraphicsDevice, GraphicsDeviceContext, VERTICESINCUBE, CubeVertexList, VERTICESINCUBE, CubeIndexList);
				//YellowCube.Transform(XMMatrixScaling(2.0f, 2.0f, 2.0f));	//Make it twice as large.
				YellowCube.Transform(XMMatrixTranslation(-4.0f, 2.5f, 6.0f));	//Reposition it. Play with this value. Start out by adding or subtracting 2 from each number.
				break;
			}
		default:
			{
				AllMeshesDefined = true;
				break;
			}
		}
	} while(NoCatastrophicFailuresOccured && !AllMeshesDefined);


	return NoCatastrophicFailuresOccured;
}
//=====================================================================================================================


//=====================================================================================================================
//  Game::UnloadContent()
//
//	Purpose: 
//		To allow any code you want to run as the program closes in order to cleanup.
//
//	Input:
//		None.
//
//	Output:
//		None.
//
//  Notes:
//		All the game objects you create need their Shutdown() methods called to release the associate vertex and index buffers.
//	Since Shaders are owned by this class, it is also responsible for calling the Shutdown() method of any shaders created.
//
//=====================================================================================================================
void Game::UnloadContent()
{
	YellowCube.Shutdown();
	Triangle.Shutdown();
	Ground.Shutdown();
	Shader.Shutdown();	//Do any cleanup the Shader requires.
}
//=====================================================================================================================


//=====================================================================================================================
//  Game::Update()
//
//	Purpose: 
//		To do everything that needs to be done in one frame except draw stuff to the screen.
//
//	Input:
//		float TimeDelta - Amount of time that has passed since the last frame occured in milliseconds.
//
//	Output:
//		None.
//
//  Notes:
//		This is where most of your game code will be. It gets called every frame to change anything that needs to be changed
//	or done during that frame. It runs in a loop that needs to be called at least 30 times per second but there's nothing
//	to control how often it gets called. Things would move at unpredictable rates if we did not use TimeDelta to take in to
//	account the amount of time that has passed since the last frame.
//
//		We start out by processing the keyboard and game controller input to change the camera's position and direction. You
//	can also toggle full screen on and off.
//
//		The camera movement this frame is stored as a 3D vector that we treat more like a 2D vector. The facing normal should 
//	point in the direction we want the camera to face. And as a normal should have a length of 1. Any movement during the 
//	frame is cumulative from the various controls. When you move it uses either the CameraFacingNormal or a normal rotated 90
//	degrees away from the camera facing. It's basic vector addition to add the movement to the camera position.
//
//		XMMatrixLookAtRH is used to create a view matrix to simulate the camera every frame. Generally, I would say it is a 
//	good idea to not continuously recreate the view matrix but it's easier then maintaining a view matrix between frames and
//	this is really early in this tutorial series.
//
//		Finally some very simple rigid animation is thrown in to show you not only how to do it, but that it can be done and how
//	easy it is to do. Experiment by turning the rotations off and on and changing their directions and speed. 
//
//		The scene is lit with a simple Blinn-Phong shader that has "directional" lighting as opposed to point lights or
//	spot lights. Directional lighting is nothing more than a direction that the light shines in. It is a normalized vector
//	describing a direction and it has a color. That's all it is. Look at the shader for more detail. By rotating that direction
//	the light source seems to orbit the scene similar to a day and night cycle except the light shines through solid objects.
//
//=====================================================================================================================
void Game::Update(float TimeDelta)
{
	XMVECTOR LookAtVector;										//Position for camera to look at.
	XMVECTOR CameraLocation;									//Where the camera is positioned.
	XMVECTOR CameraMovement = XMVectorZero();					//The change in position this frame as a 3D vector.
	DWORD Controller1StateResult = XInputGetState(0, &Controller1State);	//XBox 360 controller state.
	float ThumbLHorizontal;										//Controller Left Thumb Horizontal value;
	float ThumbLVertical;										//Controller Left Thumb Vertical value;
	float ThumbRHorizontal;										//Controller Right Thumb Horizontal value;
	float ThumbRVertical;										//Controller Right Thumb Vertical value;


	if (!Keyboard.Update()) PostQuitMessage(0);	//If DirectInput has crashed, go ahead and shutdown the app. Otherwise, get the current keyboard state.

	if (Controller1StateResult == ERROR_SUCCESS)	//If there is an XBox360 controller plugged in...
	{
		if(Controller1State.Gamepad.wButtons & XINPUT_GAMEPAD_BACK) PostQuitMessage(0);		//Close the program if the Back button on the controller is pressed.

		ThumbLHorizontal = (float) Controller1State.Gamepad.sThumbLX/32768.0f;	//Get Controller's current Left Thumb horizontal value.
		ThumbLVertical = (float) Controller1State.Gamepad.sThumbLY/32768.0f;	//Get Controller's current Left Thumb vertical value.
		ThumbRHorizontal = (float) Controller1State.Gamepad.sThumbRX/32768.0f;	//Get Controller's current Left Thumb horizontal value.
		ThumbRVertical = (float) Controller1State.Gamepad.sThumbRY/32768.0f;	//Get Controller's current Left Thumb vertical value.

		if (ThumbLVertical > 0.2f || ThumbLVertical < -0.2f) 
			CameraMovement = CameraFacingNormal * ThumbLVertical;		//Left thumb vert moves forward and back. CameraFacing is a vector and multiplying increases its length which is the speed here.
		if (ThumbLHorizontal > 0.2f || ThumbLHorizontal < -0.2f) 
			CameraMovement += XMVector4Transform(CameraFacingNormal, XMMatrixRotationZ(XM_PIDIV2)) * ThumbLHorizontal;	//Move camera left or right. Pi over 2 is a quarter circle. So, this says that in addition to any other movement this frame, move in a direction 90 degrees away from the direction being faced by an amount of whatever the Horizontal Left thumb value is.
		if (ThumbRHorizontal > 0.3f || ThumbRHorizontal < -0.3f) 
			 CameraFacingNormal = XMVector4Transform(CameraFacingNormal, XMMatrixRotationZ(ThumbRHorizontal * 0.0005f * TimeDelta));	//Rotate camera.
	}

	
	if (Keyboard.KeyPressed(DIK_LSHIFT))	//If these keys are pressed while the left shift key is pressed...
	{
		if (Keyboard.KeyPressed(DIK_D)) CameraMovement += XMVector4Transform(CameraFacingNormal,XMMatrixRotationZ(XM_PIDIV2));	//Move right. Pi over 2 is 90 degrees.
		if (Keyboard.KeyPressed(DIK_A)) CameraMovement += XMVector4Transform(CameraFacingNormal,XMMatrixRotationZ(-XM_PIDIV2));	//Move left.
	} 
	else
	{
		if (Keyboard.KeyPressed(DIK_ESCAPE)) PostQuitMessage(0);	//Stop program if escape is pressed.
		if (Keyboard.KeyPressed(DIK_W)) CameraMovement = CameraFacingNormal;		//Move forward.
		if (Keyboard.KeyPressed(DIK_S)) CameraMovement = -CameraFacingNormal;		//Move backward.
		if (Keyboard.KeyPressed(DIK_D)) CameraFacingNormal = XMVector4Transform(CameraFacingNormal,XMMatrixRotationZ(0.0005f * TimeDelta));	//Spin right.
		if (Keyboard.KeyPressed(DIK_A)) CameraFacingNormal = XMVector4Transform(CameraFacingNormal,XMMatrixRotationZ(-0.0005f * TimeDelta));//Spin left.
	}
	
	if (Keyboard.KeyPressed(DIK_RALT))		//If the right Alt key is pressed...
	{
		if(Keyboard.KeyPressed(DIK_RETURN) )	//If return is pressed...
		{
			//Toggle between full screen and windowed mode.
			if(InFullScreenMode)
			{
				SwapChain->SetFullscreenState(false, NULL);
				InFullScreenMode = false;
			}
			else
			{
				SwapChain->SetFullscreenState(true, NULL);
				InFullScreenMode = true;
			}
		}
	}

	CameraPosition += CameraMovement * TimeDelta * 0.002f;	//Add the camera movement this frame scaled up or down by the amount of time that has passed since the last frame and a scale number you can change to the current camera position to give a new position.

	CameraLocation = XMVectorSet(XMVectorGetX(CameraPosition), CameraHeight, XMVectorGetY(CameraPosition), 1.0f);	//Throw away the height value of the CameraPosition and use the CameraHeight for the Y value.
	LookAtVector = CameraLocation + XMVectorSet(XMVectorGetX(CameraFacingNormal), 0.0f, XMVectorGetY(CameraFacingNormal), 1.0f);	//Camera should look at a spot that is in the direction of CameraFacingNormal (ignoring any Y value) and the distance in front of the camera position that is the length of CameraFacingNormal.
	
	View = XMMatrixLookAtRH(CameraLocation, LookAtVector, XMVectorSet(0.0f, 1.0f, 0.0f, 1.0f));	//Create a right handed LookAt matrix for our view matrix putting the camera at CameraLocation looking towards the LookAt point and using the cheat for the Up direction.

	Triangle.TransformAtOrigin(XMMatrixRotationY(0.001f * TimeDelta));	//Make the triangle spin by a constant rate regardless of frame rate.
	YellowCube.TransformAtOrigin(XMMatrixRotationY(-0.001f * TimeDelta));	//Make the yellow cube spin.
	XMStoreFloat3(&DiffuseLightDirection, XMVector3Transform(XMLoadFloat3(&DiffuseLightDirection), XMMatrixRotationZ(0.0001f * TimeDelta)));	//Make the light source orbit the scene at a fixed rate independent of the frame rate.
	XMStoreFloat3(&DiffuseLightDirection, XMVector3Normalize(XMLoadFloat3(&DiffuseLightDirection)));	//Normalize the light source direction in case it is no longer normalized.
}
//=====================================================================================================================


//=====================================================================================================================
//  Game::Draw()
//
//	Purpose: 
//		To do draw a single frame on the computer screen.
//
//	Input:
//		float TimeDelta - Amount of time that has passed since the last frame occured in milliseconds.
//
//	Output:
//		None.
//
//  Notes:
//		Since all the drawing code is tucked away neatly elsewhere, this method ends up being very short and sweet. There's
//	basically nothing to it. The first two lines clear the backbuffer in corn flower blue which is a constant. And then
//	it clears the depth stencil. You can clear the screen in any color you like.
//
//		Then each game object's Draw() method needs to be called to tell it to draw it self to the back buffer. The parameters
//	for the shader have to be sent here.
//
//		Finaly, the swapchain is told to make the backbuffer the frontbuffer and draw it to the screen by presenting it and
//	the image appears on the computer monitor. 
//
//=====================================================================================================================
void Game::Draw(float TimeDelta)
{
	GraphicsDeviceContext->ClearRenderTargetView(BackBuffer, RGBACornFlowerBlue);
	GraphicsDeviceContext->ClearDepthStencilView(DepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);

	YellowCube.Draw(GraphicsDeviceContext, View, Projection, Shader, DiffuseLightDirection, AmbientLightColor, DiffuseLightColor);
	Triangle.Draw(GraphicsDeviceContext, View, Projection, Shader, DiffuseLightDirection, AmbientLightColor, DiffuseLightColor);
	Ground.Draw(GraphicsDeviceContext, View, Projection, Shader, DiffuseLightDirection, AmbientLightColor, DiffuseLightColor);

	SwapChain->Present(0,0);
}
//=====================================================================================================================




Game.h
#pragma once
#pragma comment(lib, "XInput.lib")
#include <Windows.h>
#include <XInput.h>				//Allows us to communicate with the XBox 360 controller.
#include "directx11game.h"		//This class inheriets from here.
#include "SceneObjectClass.h"	//New class to allow us to put objects in the scene.
#include "ShaderClass.h"


//=====================================================================================================================
//  Game : public DirectXGame
//
//	Purpose: 
//		This is where this frame work is modified to create a game.
//
//  Notes:
//		I am changing the comments on this class from the previous example. You modify this class in order to create your
//	game. So, you will quickly notice the code in this class has been modified to create a scene with objects in it that 
//	you can move around in using either the keyboard or an XBox 360 controller if you have one hooked up to your PC (which
//	I HIGHLY recommend although for programming it can be more convienient not to have to leave the keyboard). For actual
//	games I would prefer to see the XBox 360 controller be the primary, if not sole input device.
//
//		Notice that this class inherits from DirectX11Game. Because of that, the methods of this class are automatically
//	called at the appropriate time. You just have to fill these methods with instructions to create a game.
//
//=====================================================================================================================
class Game : public DirectX11Game
{
	public:
		Game(void);
		virtual ~Game(void);
 		bool Initialize(void);
		bool LoadContent(void);
		void UnloadContent(void);
		void Update(float);
		void Draw(float);

	private:
		SceneObjectClass Triangle;
		SceneObjectClass Ground;
		SceneObjectClass YellowCube;
		ShaderClass Shader;
		XMMATRIX View;
		XMMATRIX Projection;
		XMVECTOR CameraFacingNormal;
		XINPUT_STATE Controller1State;
		XINPUT_STATE PreviousController1State;
		float CameraHeight;
		XMVECTOR CameraPosition;
		bool InFullScreenMode;
		XMFLOAT3 DiffuseLightDirection;
		XMFLOAT4 AmbientLightColor;
		XMFLOAT4 DiffuseLightColor;

		#define VERTICESINCUBE 36		//Constant to make it more clear what this number is.
};
//=====================================================================================================================




ALL of that code was required to be written line by line in order to put a blank blue green window on the screen in preparation for drawing a 3D video game to the screen. This is basically the absolute bare bones code that you will need every time you make a 2D or 3D game in DirectX 11. It's quite a bit of code considering it does nothing but create a blank blue window and get you ready to start writing some game code.


Compare that to basically the exact same thing in C# - XNA/MonoGame and keep in mind that the MonoGame template generates 100% of this code for you - this is what it GIVES you when you start it up:

Program.cs
using System;

namespace Game1
{
#if WINDOWS || LINUX
    /// <summary>
    /// The main class.
    /// </summary>
    public static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            using (var game = new Game1())
                game.Run();
        }
    }
#endif
}



Game1.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace Game1
{
    public class Game1 : Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        {
        
            base.Initialize();
        }


        protected override void LoadContent()
        {
            
            spriteBatch = new SpriteBatch(GraphicsDevice);

        }

        
        protected override void UnloadContent()
        {

        }

        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                Exit();

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            base.Draw(gameTime);
        }
    }
}



Now granted, the MonoGame code is actually doing considerably more work behind the scenes with a lot of classes that are not even included in my DX code such as the Sprite class. But it's a fraction of the code even IF they didn't just give 100% of this code to you on startup.

Both examples appear to do the exact same thing. The do nearly the exact same thing because I wrote this DX code to specifically work almost identical to the way this MonoGame code works. (I did it largely to help XNA programmers switch to DX and because the XNA way of doing things is something I'm familiar with. So this code was very intentionally designed to be nearly identical in terms of functionality.) Neither one of them does anything other than put a blank blue window on the screen. Both of them set things up for you to immediately jump in and start coding a game. If you added a Sprite class to the DX example you could pretty much immediately start drawing sprites to the screen with either example and no additional code. But notice XNA/MonoGame in C# has a spite class ready for you to just start using, but you would have to make your own sprite class in C++/DX. We had to make our own class to handle keyboard input. C#/XNA has that built in already. Heck, we had to build our own class to tell Windows to give us a process to run under let alone give us a Window to draw in. That's all handled for you behind the scenes with C#.

When you get into C++, you quickly realize you have to tell it how to do everything including things you had previously taken for granted. DX and C++ for example doesn't know how to read common image files like .JPG or .GIF files. So, if you want to read those in DX, you have to teach it how to read a JPeg file which means you need to be able to teach college students how to read a JPeg file with pen and paper.

Granted, you can find some libraries that other people have written which may or may not cost money to do many of these tasks for you, but all that stuff is built into a language like C#.

That is the difference between a high level and low level language. C# is high level because it does 100 times as much stuff for you as C++. C++ is a low level language because the language itself basically does nothing for you. Until more recent versions of C++, even ATL and standard libraries were not actually part of the C++ language. Simple data structures that we take for granted in C# like Lists had to be built from scratch yourself in C++. With some standard libraries in C++, things have gotten better. But those are optional and you can use them or not use them in C++. And while you may have not written them line by line, someone else had to write those libraries line by line in C++ because they are not part of the language and don't come with the language.

I would consider Python even a little bit more high level than C#. There is a world of difference between coding in Python and coding in C++. It's not even really comparable once you get past the stuff you learn in the classroom and get into real world C++ coding with the Windows API or something like DirectX.

Python has its uses, but it's really a night and day different thing. I'm no Python expert. I only barely learned it enough to write my own scripts in Blender. But I am familiar enough with it to say that it's not even remotely comparable to C++.

Again, I consider C to basically be the same thing as C++ minus the OOP.

This post has been edited by BBeck: 02 November 2015 - 12:25 PM

Was This Post Helpful? 5
  • +
  • -

#13 Ryano121   User is offline

  • D.I.C Lover
  • member icon

Reputation: 1461
  • View blog
  • Posts: 3,289
  • Joined: 30-January 11

Re: the experts can't agree on anything :(

Posted 02 November 2015 - 12:13 PM

I think that was officially BBeck's longest post to date :)
Was This Post Helpful? 2
  • +
  • -

#14 BBeck   User is offline

  • Here to help.
  • member icon


Reputation: 792
  • View blog
  • Posts: 1,886
  • Joined: 24-April 12

Re: the experts can't agree on anything :(

Posted 02 November 2015 - 12:19 PM

Woo hoo! :bananaman: :sorcerer: :clap: :gunsmilie:
Was This Post Helpful? 0
  • +
  • -

#15 herc65   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 11
  • Joined: 01-November 15

Re: the experts can't agree on anything :(

Posted 02 November 2015 - 04:37 PM

Please tell me the usefulness of C in creating custom utilities for both console and GUI. Python has no inherent GUI capabilities although it is extensible, but I don't know about C.
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2