chapter 2 opengl vs. directx as api © 2008 cengage learning emea

50
CHAPTER 2 CHAPTER 2 OpenGL vs. DirectX as API OpenGL vs. DirectX as API © 2008 Cengage Learning EM

Upload: spencer-walton

Post on 28-Dec-2015

256 views

Category:

Documents


6 download

TRANSCRIPT

CHAPTER 2CHAPTER 2

OpenGL vs. DirectX as APIOpenGL vs. DirectX as API

© 2008 Cengage Learning EMEA

LEARNING OBJECTIVESLEARNING OBJECTIVES

In this chapter you will learn about:– Application programming interfacesApplication programming interfaces– OpenGL: a standard for cross-OpenGL: a standard for cross-

platform high performance graphicsplatform high performance graphics– The OpenGL Utility Toolkit (GLUT)The OpenGL Utility Toolkit (GLUT)– DirectX foundation classes and DirectX foundation classes and

Direct3D 10Direct3D 10

APPLICATION PROGRAMMING APPLICATION PROGRAMMING INTERFACESINTERFACES

An application programming interface, or API, is a programmatically implemented interface provided in the form of a library.

This interface provides a certain number of services for use by an application program.

An API is a unified interface featuring a number of classes/structures, constants and functions.

Examples of common APIs:– Microsoft’s Win32 API, Sun Microsystems’s Java Platform,

the OpenGL graphics API, Microsoft’s DirectX API (consisting of several APIs providing interfaces for sound, input control, graphics, etc.), the Simple DirectMedia Layer, and the Single UNIX Specification.

APPLICATION PROGRAMMING APPLICATION PROGRAMMING INTERFACESINTERFACES

Graphics interfaces, such as OpenGL and Direct3D, can be investigated using a blackbox approach.

A blackbox is a system described through its inputs and outputs without any consideration of its internal workings.

APPLICATION PROGRAMMING APPLICATION PROGRAMMING INTERFACESINTERFACES

Application programming interfaces can be described through the functions contained in their libraries. These functions can be divided into the following main categories:

1 Attribute functions.2 Primitive functions.3 Viewing functions.4 Transformation functions.5 Query functions.6 Control functions.7 Input functions.

APPLICATION PROGRAMMING APPLICATION PROGRAMMING INTERFACESINTERFACES

OPENGL: A STANDARD FOR CROSS-OPENGL: A STANDARD FOR CROSS-PLATFORM HIGH PERFORMANCE PLATFORM HIGH PERFORMANCE

GRAPHICSGRAPHICS The Open Graphics Library, or OpenGL, is a

procedural-based 3D graphics API explicitly designed by Silicon Graphics for the standardized development of 3D and 2D graphical applications.

Examples of games using OpenGL for graphics:– id Software’s Quake and Doom 3 series as well

as games produced by their engine licensees and Epic Games’s Unreal series and games based on their Unreal Engine technology.

OpenGL is very easy to learn and frees the developer from underlying hardware technicalities.

OpenGL is a cross-platform API, unlike Microsoft’s Direct3D API, (which is limited to the Windows and Xbox/Xbox360 platforms).

OpenGL is, at the lowest level, nothing more than a specification periodically updated and/or revised by the OpenGL Architecture Review Board (ARB).

OPENGL: A STANDARD FOR CROSS-OPENGL: A STANDARD FOR CROSS-PLATFORM HIGH PERFORMANCE PLATFORM HIGH PERFORMANCE

GRAPHICSGRAPHICS

From a design standpoint OpenGL has two main goals:– Seamless interaction with a vast array of

3D accelerators.– To offer the same capabilities on a

number of computing platforms. The API is based on a client-server

architecture and modeled as a state machine.

OPENGL: A STANDARD FOR CROSS-OPENGL: A STANDARD FOR CROSS-PLATFORM HIGH PERFORMANCE PLATFORM HIGH PERFORMANCE

GRAPHICSGRAPHICS

The OpenGL interface consists of over 120 commands, with the letters ‘gl’ preceding each, for example: glColor, glVertex, glBegin, glDisable, glBitmap

These commands, or functions, are used to define a scene’s geometry, lighting, atmospheric elements such as fog, and material properties – all the elements needed to create interactive

three-dimensional scenes.

OPENGL: A STANDARD FOR CROSS-OPENGL: A STANDARD FOR CROSS-PLATFORM HIGH PERFORMANCE PLATFORM HIGH PERFORMANCE

GRAPHICSGRAPHICS

A Very Basic OpenGL A Very Basic OpenGL ProgramProgram

#include <gl/gl.h>#include <gl/gl.h>

/* dummy window creation function *//* dummy window creation function */void SomeWindowCreationRoutine(){}void SomeWindowCreationRoutine(){}

/* dummy loop function *//* dummy loop function */void KeepTheWindowActive(){}void KeepTheWindowActive(){}

int main()int main(){{

/* call some routine to create the window *//* call some routine to create the window */SomeWindowCreationRoutine();SomeWindowCreationRoutine();

/* set the clear color - red, green, blue, alpha*//* set the clear color - red, green, blue, alpha*/glClearColor(1.0, 1.0, 1.0, 0.0);glClearColor(1.0, 1.0, 1.0, 0.0);

/* clear frame buffer *//* clear frame buffer */glClear(GL_COLOR_BUFFER_BIT);glClear(GL_COLOR_BUFFER_BIT);

/* set color to red *//* set color to red */glColor3f(1.0, 0.0, 0.0);glColor3f(1.0, 0.0, 0.0);

A Very Basic OpenGL A Very Basic OpenGL ProgramProgram

/* glBegin composes the group of vertices below as a/* glBegin composes the group of vertices below as a polygon */polygon */glBegin(GL_POLYGON);glBegin(GL_POLYGON);

glVertex3f(0.0, -10.0, -6.0); //x = 0, y = -10, z = -6glVertex3f(0.0, -10.0, -6.0); //x = 0, y = -10, z = -6glVertex3f(-10.0, 0.0, 6.0); //x = -10, y = 0, z = 6glVertex3f(-10.0, 0.0, 6.0); //x = -10, y = 0, z = 6glVertex3f(10.0, 0.0, 6.0); //x = 10, y = 0, z = 6glVertex3f(10.0, 0.0, 6.0); //x = 10, y = 0, z = 6

/* glEnd indicates the end of the rendering group *//* glEnd indicates the end of the rendering group */glEnd();glEnd();

/* make sure all previously issued commands are/* make sure all previously issued commands are completed */completed */glFlush();glFlush();

/* call a routine to keep the window active - allowing/* call a routine to keep the window active - allowing the triangle to be shown */the triangle to be shown */KeepTheWindowActive();KeepTheWindowActive();

/* exit the application*//* exit the application*/return 0;return 0;

}}

THE OPENGL UTILITY TOOLKIT THE OPENGL UTILITY TOOLKIT (GLUT)(GLUT)

The OpenGL Utility Toolkit, or GLUT, is a utility library for OpenGL applications.

GLUT, as a programming interface, provides functions for system-level control and initialization – in essence window creation and control.

An OpenGL game or graphics application using GLUT for window creation and input control can be run across a vast array of operating systems.

THE OPENGL UTILITY TOOLKIT THE OPENGL UTILITY TOOLKIT (GLUT)(GLUT)

GLUT functions are arranged into the following API categories based on their respective area of functionality:

1 Callback creation and registration functions.2 Event processing initialization.3 Font rendering functions.4 Initialization functions.5 Menu creation and control functions.6 Model rendering functions.7 State retrieval functions.8 Window color-map manipulation functions.9 Window creation and control functions.10 Window overlay specification and control functions.

A Very Simple GLUT A Very Simple GLUT ProgramProgram

#include <gl/glut.h> //glut library, it imports gl.h, glu.h#include <gl/glut.h> //glut library, it imports gl.h, glu.h#include <iostream> //standard IO#include <iostream> //standard IO

using namespace std;using namespace std;

void display(void)void display(void){{

//...some OpenGL initialization functions//...some OpenGL initialization functions

/* contents of back buffer are set to become that of/* contents of back buffer are set to become that of front buffer (double buffering)*/front buffer (double buffering)*/glutSwapBuffers ();glutSwapBuffers ();

}}

A Very Simple GLUT A Very Simple GLUT ProgramProgram

void controlMenu(int x)void controlMenu(int x){{

/* basic switch control structure, prints the text/* basic switch control structure, prints the text corresponding to the selected action in the commandcorresponding to the selected action in the command prompt window */prompt window */switch(x)switch(x){{

case 1: cout << "First item selected" << endl;case 1: cout << "First item selected" << endl;break;break;

case 2: cout << "Second item selected" << endl;case 2: cout << "Second item selected" << endl;break;break;

case 3: exit(0); //terminate the applicationcase 3: exit(0); //terminate the application}}/* set the current window for redisplay *//* set the current window for redisplay */glutPostRedisplay();glutPostRedisplay();

}}

A Very Simple GLUT A Very Simple GLUT ProgramProgram

void menu()void menu(){{

/* create a new pop-up menu *//* create a new pop-up menu */glutCreateMenu(controlMenu);glutCreateMenu(controlMenu);

/* add menu entries to the bottom of the current menu *//* add menu entries to the bottom of the current menu */glutAddMenuEntry("First Item",1);glutAddMenuEntry("First Item",1);glutAddMenuEntry("Second Item",2);glutAddMenuEntry("Second Item",2);glutAddMenuEntry("Quit",3);glutAddMenuEntry("Quit",3);

/* attach the right mouse button for menu selection *//* attach the right mouse button for menu selection */glutAttachMenu(GLUT_RIGHT_BUTTON);glutAttachMenu(GLUT_RIGHT_BUTTON);

}}

A Very Simple GLUT A Very Simple GLUT ProgramProgram

int main(int argc, char** argv)int main(int argc, char** argv){{

/* initialize the GLUT library. *//* initialize the GLUT library. */glutInit(&argc, argv);glutInit(&argc, argv);

/* set the initial display mode: double buffering and a/* set the initial display mode: double buffering and a depth buffer. */depth buffer. */glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

/* set default window size *//* set default window size */glutInitWindowSize(300, 200);glutInitWindowSize(300, 200);

/* create a top-level window with a caption *//* create a top-level window with a caption */glutCreateWindow("...event-driven mouse input...");glutCreateWindow("...event-driven mouse input...");

/* display our contents in the window *//* display our contents in the window */glutDisplayFunc(display);glutDisplayFunc(display);

/* call our menu function *//* call our menu function */menu();menu();

/* enter the GLUT event processing loop - will handle/* enter the GLUT event processing loop - will handle any callback */any callback */glutMainLoop();glutMainLoop();

return 0;return 0;}}

DIRECTX FOUNDATION DIRECTX FOUNDATION CLASSESCLASSES

Microsoft DirectX is an all encompassing description for a number of game-programming-centric APIs.

These APIs are also used outside the game development sphere for tasks such as video editing, video playback, input control, 3D rendering, and sound and music playback.

DIRECTX FOUNDATION DIRECTX FOUNDATION CLASSESCLASSES

DirectX is targeted at the Windows and Xbox/Xbox 360 platforms, with DirectX 10, the version covered by this book, completely exclusive to Microsoft Windows Vista.

Direct3D allows for the quick rendering of high-quality three-dimensional graphics and is, just like its main competitor, OpenGL.

DIRECTX FOUNDATION DIRECTX FOUNDATION CLASSESCLASSES

DirectX is released as both a runtime and software development kit (SDK), constantly updated and available from Microsoft’s DirectX website.

The DirectX SDK allows developers to utilize each of the DirectX APIs and it includes a number of tools and utilities such as the Microsoft cross-platform audio creation tool.

DIRECTX FOUNDATION DIRECTX FOUNDATION CLASSESCLASSES

The DirectX API consists of the following main technologies:– DirectX Graphics (actually containing three

versions of Direct3D for the sake of backwards compatibility): Direct3D 9

– The latest release of the Direct3D 3D graphics rendering API for Windows XP and Windows 2000 based computers (not taking advantage of the Windows Vista Display Driver Model).

Direct3D 9Ex (also called DirectX 9 for Windows Vista)– An extended version of the Direct3D 9 API, providing

additional access to Windows Vista specific extensions for the rendering of 3D graphics. The Windows Aero graphical user interface utilizes this API, for example.

DIRECTX FOUNDATION DIRECTX FOUNDATION CLASSESCLASSES

Direct3D 10– The newest API for the rendering of two– and

three-dimensional graphics targeted at Windows Vista’s Display Driver Model. Also the only API supporting Shader Model 4 (see Chapter 6).

DirectDraw (deprecated)– An API for the rendering of 2D graphics (can use

software or hardware acceleration depending on availability). DirectDraw never supported the rendering of 3D graphics and have been deprecated since the release of DirectX 8. A number of crucial 2D DirectDraw rendering calls remain and are available via the Direct3D API.

DIRECTX FOUNDATION DIRECTX FOUNDATION CLASSESCLASSES

– DirectX Audio: Cross-Platform Audio Creation (XACT)

– A high-level audio library and engine for the playback and recording of digital audio using the Xbox 360’s compressed audio format (XAudio) and DirectSound on Windows.

– Also features the XACT Audio Creation Tool that arranges audio files into so called wave banks (a single audio file made up of multiple audio files).

– XACT also supports 5.1 surround sound configurations.

DIRECTX FOUNDATION DIRECTX FOUNDATION CLASSESCLASSES

DirectSound– An API for the playback and recording of digital

audio – allowing a single audio playback/recording implementation regardless of the audio hardware being used.

– Following the architectural changes in Windows Vista, DirectSound no longer has direct communication with the underlying hardware, rather using an emulation layer – there is thus no longer any DirectSound hardware acceleration.

– At the time of writing, this API is expected to be replaced by XAudio2, a cross-platform, lowlevel API that will be used in unison with Windows XP, Vista and the Xbox 360 console.

DIRECTX FOUNDATION DIRECTX FOUNDATION CLASSESCLASSES

DirectSound3D– An extension of the DirectSound API to facilitate

the playback of 3D audio (a sequence of sound effects expanding the listener’s awareness from pure stereo to a spatial environment).

– Integrated into the DirectSound API for the DirectX 10 SDK release.

DIRECTX FOUNDATION DIRECTX FOUNDATION CLASSESCLASSES

DirectMusic– Not strictly speaking an API; DirectMusic can rather be

considered a high-level set of objects utilizing the DirectSound API.

– It provides high-level functions for the playback of sounds and music.

– Provides support for the playback of MIDI, Wav, playback using the Microsoft Software Synthesizer when hardware synthesis is not available, the control of playback tempo and pitch, the simultaneous playback from several sounds sources and numerous other capabilities.

– DirectMusic, although remaining unchanged, has now mostly been integrated into the DirectSound subsystem since the DirectX 10 SDK release.

DIRECTX FOUNDATION DIRECTX FOUNDATION CLASSESCLASSES

– DirectX Input: XInput

– An API allowing input control using an Xbox 360 Controller connected to a Microsoft Windows-based computer.

DirectInput– An API for input control via input devices such as

the mouse, keyboard or game controllers.– This API was last updated with the release of

DirectX 8.

DIRECTX FOUNDATION DIRECTX FOUNDATION CLASSESCLASSES

– DirectX Networking: DirectPlay (deprecated)

– This API facilitates easy network programming for connecting games and other kinds of applications over a dial-up connection, within a LAN environment as well as via the Internet.

– In short DirectPlay only sends and receives packets – the network architecture remains the responsibility of the programmer.

– DirectPlay was deprecated in 2004, the last release being part of the DirectX 8 SDK.

DIRECTX FOUNDATION DIRECTX FOUNDATION CLASSESCLASSES

– DirectX Media (completely phased out): DirectAnimation, DirectShow and some

DirectX plug-ins– An API dealing with multimedia functions such as

2D animation for websites (DirectAnimation), audio processing, video acceleration and the streaming of media (DirectShow).

– DirectShow was integrated into Microsoft’s Platform SDK with most of the other components completely deprecated and replaced by newer Microsoft technologies.

A Very Simple Direct3D 10 A Very Simple Direct3D 10 ProgramProgram

#include <windows.h>#include <windows.h>#include <d3d10.h>#include <d3d10.h>#include <d3dx10.h>#include <d3dx10.h>#include "resource.h"#include "resource.h"

/* create a structure to store the triangle’s vertex coordinates *//* create a structure to store the triangle’s vertex coordinates */struct TriangleVertexstruct TriangleVertex{{ D3DXVECTOR3 Coordinate; D3DXVECTOR3 Coordinate; };};

/* initialize the instance handle, g_hInstance,/* initialize the instance handle, g_hInstance, the handle to the window, g_hWindow, etc. */the handle to the window, g_hWindow, etc. */HWND g_hWindow = NULL;HWND g_hWindow = NULL;HINSTANCE g_hInstance = NULL; HINSTANCE g_hInstance = NULL; D3D10_DRIVER_TYPE g_dx10DriverType = D3D10_DRIVER_TYPE_NULL;D3D10_DRIVER_TYPE g_dx10DriverType = D3D10_DRIVER_TYPE_NULL;ID3D10Device* g_pd3d10Device = NULL;ID3D10Device* g_pd3d10Device = NULL;IDXGISwapChain* g_pdx10SwapChain = NULL;IDXGISwapChain* g_pdx10SwapChain = NULL;ID3D10EffectTechnique* g_pd3d10EffectTechnique = NULL;ID3D10EffectTechnique* g_pd3d10EffectTechnique = NULL;ID3D10Buffer* g_pd3d10VertexBuffer = NULL;ID3D10Buffer* g_pd3d10VertexBuffer = NULL;ID3D10InputLayout* g_pd3d10InputVertexLayout = NULL;ID3D10InputLayout* g_pd3d10InputVertexLayout = NULL;ID3D10Effect* g_pd3d10Effect = NULL;ID3D10Effect* g_pd3d10Effect = NULL;ID3D10RenderTargetView* g_pd3d10RenderTargetView = NULL;ID3D10RenderTargetView* g_pd3d10RenderTargetView = NULL;

A Very Simple Direct3D 10 A Very Simple Direct3D 10 ProgramProgram

/* function prototypes *//* function prototypes */HRESULT InitDevice();HRESULT InitDevice();void Clean();void Clean();LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow );HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow );void DrawTriangle();void DrawTriangle();

/* initialize the message processing loop elements and the idle time required/* initialize the message processing loop elements and the idle time required for the rendering of our triangle via winMain, the application entry point */for the rendering of our triangle via winMain, the application entry point */int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

LPWSTR LPWSTR lpCmdLine, int nCmdShow) lpCmdLine, int nCmdShow){{

if((FAILED(InitWindow(hInstance, nCmdShow)))||(FAILED(InitDevice())))if((FAILED(InitWindow(hInstance, nCmdShow)))||(FAILED(InitDevice()))){{

Clean(); //do device cleanup – freeing resourcesClean(); //do device cleanup – freeing resourcesreturn 0;return 0;

}}

MSG msg = {0};MSG msg = {0};while(WM_QUIT != msg.message)while(WM_QUIT != msg.message){{

A Very Simple Direct3D 10 A Very Simple Direct3D 10 ProgramProgram

if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){{

TranslateMessage(&msg);TranslateMessage(&msg);DispatchMessage(&msg);DispatchMessage(&msg);

}}elseelse{{

DrawTriangle(); //render our triangleDrawTriangle(); //render our triangle}}

}}Clean();Clean();return (int)msg.wParam;return (int)msg.wParam;

}}

/* register the class and create the output window *//* register the class and create the output window */HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow)HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow){{

/* register the window class *//* register the window class *///////////////////////////////////////////////////////

A Very Simple Direct3D 10 A Very Simple Direct3D 10 ProgramProgram

WNDCLASSEX wndcex;WNDCLASSEX wndcex;wndcex.cbSize wndcex.cbSize = sizeof(WNDCLASSEX);= sizeof(WNDCLASSEX);wndcex.style wndcex.style = CS_HREDRAW | CS_VREDRAW;= CS_HREDRAW | CS_VREDRAW;wndcex.lpfnWndProc wndcex.lpfnWndProc = WndProc;= WndProc;wndcex.cbClsExtra wndcex.cbClsExtra = 0;= 0;wndcex.cbWndExtra wndcex.cbWndExtra = 0;= 0;wndcex.hInstance wndcex.hInstance = hInstance;= hInstance;wndcex.hIcon wndcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_PROG1);= LoadIcon(hInstance, (LPCTSTR)IDI_PROG1);wndcex.hCursor wndcex.hCursor = LoadCursor(NULL, IDC_ARROW);= LoadCursor(NULL, IDC_ARROW);wndcex.hbrBackground wndcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);= (HBRUSH)(COLOR_WINDOW+1);wndcex.lpszMenuName wndcex.lpszMenuName = NULL;= NULL;wndcex.lpszClassName wndcex.lpszClassName = "StaticTriangle";= "StaticTriangle";wndcex.hIconSm wndcex.hIconSm = LoadIcon(wndcex.hInstance, (LPCTSTR)IDI_PROG1);= LoadIcon(wndcex.hInstance, (LPCTSTR)IDI_PROG1);

if(!RegisterClassEx(&wndcex))if(!RegisterClassEx(&wndcex))return E_FAIL;return E_FAIL;

/* create the window *//* create the window *///////////////////////////////////////////////g_hInstance = hInstance;g_hInstance = hInstance;

RECT rectangle = {0, 0, 800, 600};RECT rectangle = {0, 0, 800, 600};AdjustWindowRect(&rectangle, WS_OVERLAPPEDWINDOW, FALSE);AdjustWindowRect(&rectangle, WS_OVERLAPPEDWINDOW, FALSE);

A Very Simple Direct3D 10 A Very Simple Direct3D 10 ProgramProgram

g_hWindow = CreateWindow(g_hWindow = CreateWindow("StaticTriangle","StaticTriangle","Rendering a triangle without any "Rendering a triangle without any

transformations",transformations",WS_OVERLAPPEDWINDOW,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,rectangle.right - rectangle.left,rectangle.right - rectangle.left,rectangle.bottom - rectangle.top,rectangle.bottom - rectangle.top,NULL, NULL, hInstance, NULL);NULL, NULL, hInstance, NULL);

if(!g_hWindow)if(!g_hWindow)return E_FAIL;return E_FAIL;

ShowWindow(g_hWindow, nCmdShow);ShowWindow(g_hWindow, nCmdShow);

return S_OK;return S_OK;}}

A Very Simple Direct3D 10 A Very Simple Direct3D 10 ProgramProgram

/* create the Direct3D device and swap chain *//* create the Direct3D device and swap chain */HRESULT InitDevice()HRESULT InitDevice(){{ HRESULT hresult_ = S_OK;HRESULT hresult_ = S_OK;

/* setup client rectangle width and height *//* setup client rectangle width and height *///////////////////////////////////////////////////////////////////////////////////////////RECT rectangle;RECT rectangle;GetClientRect(g_hWindow, &rectangle);GetClientRect(g_hWindow, &rectangle);

int rectangle_width = rectangle.right - rectangle.left;int rectangle_width = rectangle.right - rectangle.left;int rectangle_height = rectangle.bottom - rectangle.top;int rectangle_height = rectangle.bottom - rectangle.top;int deviceFlags = 0;int deviceFlags = 0;

/* specify D3D10 drivers to use *//* specify D3D10 drivers to use *///////////////////////////////////////////////////////////////////D3D10_DRIVER_TYPE d3d10drivers[] =D3D10_DRIVER_TYPE d3d10drivers[] ={{

D3D10_DRIVER_TYPE_HARDWARE,D3D10_DRIVER_TYPE_HARDWARE,D3D10_DRIVER_TYPE_REFERENCE,D3D10_DRIVER_TYPE_REFERENCE,

};};

A Very Simple Direct3D 10 A Very Simple Direct3D 10 ProgramProgram

int numberDrivers = sizeof(d3d10drivers)/sizeof(d3d10drivers[0]);int numberDrivers = sizeof(d3d10drivers)/sizeof(d3d10drivers[0]);

/* create the swap chain *//* create the swap chain *///////////////////////////////////////////////////////DXGI_SWAP_CHAIN_DESC swapchain;DXGI_SWAP_CHAIN_DESC swapchain;SecureZeroMemory(&swapchain, sizeof(swapchain));SecureZeroMemory(&swapchain, sizeof(swapchain));

swapchain.BufferCount = 1;swapchain.BufferCount = 1;swapchain.BufferDesc.Width = rectangle_width;swapchain.BufferDesc.Width = rectangle_width;swapchain.BufferDesc.Height = rectangle_height;swapchain.BufferDesc.Height = rectangle_height;swapchain.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;swapchain.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;swapchain.BufferDesc.RefreshRate.Numerator = 30;swapchain.BufferDesc.RefreshRate.Numerator = 30;swapchain.BufferDesc.RefreshRate.Denominator = 1;swapchain.BufferDesc.RefreshRate.Denominator = 1;swapchain.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;swapchain.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;swapchain.OutputWindow = g_hWindow;swapchain.OutputWindow = g_hWindow;swapchain.SampleDesc.Count = 1;swapchain.SampleDesc.Count = 1;swapchain.SampleDesc.Quality = 0;swapchain.SampleDesc.Quality = 0;swapchain.Windowed = TRUE;swapchain.Windowed = TRUE;

A Very Simple Direct3D 10 A Very Simple Direct3D 10 ProgramProgram

for(int d3d10DriverCount = 0; d3d10DriverCount < numberDrivers; for(int d3d10DriverCount = 0; d3d10DriverCount < numberDrivers; d3d10DriverCount++)d3d10DriverCount++)

{{g_dx10DriverType = d3d10drivers[d3d10DriverCount];g_dx10DriverType = d3d10drivers[d3d10DriverCount];hresult_ = D3D10CreateDeviceAndSwapChain(hresult_ = D3D10CreateDeviceAndSwapChain(

NULL, g_dx10DriverType, NULL,NULL, g_dx10DriverType, NULL,deviceFlags, D3D10_SDK_VERSION,deviceFlags, D3D10_SDK_VERSION,&swapchain, &g_pdx10SwapChain,&swapchain, &g_pdx10SwapChain,&g_pd3d10Device);&g_pd3d10Device);

if(SUCCEEDED(hresult_))if(SUCCEEDED(hresult_))break;break;

}}

if(FAILED(hresult_))if(FAILED(hresult_))return hresult_;return hresult_;

/* specify the render target view *//* specify the render target view */////////////////////////////////////////////////////////////////////////ID3D10Texture2D *pBuffer;ID3D10Texture2D *pBuffer;hresult_ = g_pdx10SwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D),(LPVOID*) hresult_ = g_pdx10SwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D),(LPVOID*)

&pBuffer); &pBuffer);

if(FAILED(hresult_))if(FAILED(hresult_))return hresult_;return hresult_;

A Very Simple Direct3D 10 A Very Simple Direct3D 10 ProgramProgram

hresult_ = g_pd3d10Device->CreateRenderTargetView(pBuffer, NULL, hresult_ = g_pd3d10Device->CreateRenderTargetView(pBuffer, NULL, &g_pd3d10RenderTargetView); &g_pd3d10RenderTargetView);

pBuffer->Release();pBuffer->Release();

if(FAILED(hresult_))if(FAILED(hresult_))return hresult_;return hresult_;

g_pd3d10Device->OMSetRenderTargets(1,&g_pd3d10RenderTargetView, g_pd3d10Device->OMSetRenderTargets(1,&g_pd3d10RenderTargetView, NULL);NULL);

/* create the viewport *//* create the viewport *///////////////////////////////////////////////////D3D10_VIEWPORT viewport;D3D10_VIEWPORT viewport;viewport.TopLeftX viewport.TopLeftX = 0;= 0;viewport.TopLeftY viewport.TopLeftY = 0;= 0;viewport.Width viewport.Width = rectangle_width;= rectangle_width;viewport.Height viewport.Height = rectangle_height;= rectangle_height;viewport.MinDepth viewport.MinDepth = 0.0f;= 0.0f;viewport.MaxDepth viewport.MaxDepth = 1.0f;= 1.0f;

g_pd3d10Device->RSSetViewports(1, &viewport);g_pd3d10Device->RSSetViewports(1, &viewport);

A Very Simple Direct3D 10 A Very Simple Direct3D 10 ProgramProgram

/* load the effect file specifying our triangle’s color*//* load the effect file specifying our triangle’s color*/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////hresult_ = D3DX10CreateEffectFromFile(hresult_ = D3DX10CreateEffectFromFile(

"effect.fx", NULL, NULL, "fx_4_0", "effect.fx", NULL, NULL, "fx_4_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, D3D10_SHADER_ENABLE_STRICTNESS, 0,

g_pd3d10Device, NULL, NULL, &g_pd3d10Effect, NULL, NULL);g_pd3d10Device, NULL, NULL, &g_pd3d10Effect, NULL, NULL);

/* if the effect file is missing *//* if the effect file is missing *///////////////////////////////////////////////////////////////////////if(FAILED(hresult_))if(FAILED(hresult_)){{

return hresult_;return hresult_;}}

/* set the effect technique and input layout *//* set the effect technique and input layout *///////////////////////////////////////////////////////////////////////////////////////////////g_pd3d10EffectTechnique = g_pd3d10Effect->GetTechniqueByName("Triangle");g_pd3d10EffectTechnique = g_pd3d10Effect->GetTechniqueByName("Triangle");

D3D10_INPUT_ELEMENT_DESC inputlayout[] =D3D10_INPUT_ELEMENT_DESC inputlayout[] ={{

{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,D3D10_INPUT_PER_VERTEX_DATA, 0},D3D10_INPUT_PER_VERTEX_DATA, 0},

};};

A Very Simple Direct3D 10 A Very Simple Direct3D 10 ProgramProgram

int numberOfElements = sizeof(inputlayout) / sizeof(inputlayout[0]);int numberOfElements = sizeof(inputlayout) / sizeof(inputlayout[0]);

D3D10_PASS_DESC PassDescription;D3D10_PASS_DESC PassDescription;g_pd3d10EffectTechnique->GetPassByIndex(0)-g_pd3d10EffectTechnique->GetPassByIndex(0)->GetDesc(&PassDescription);>GetDesc(&PassDescription);

hresult_ = g_pd3d10Device->CreateInputLayout(hresult_ = g_pd3d10Device->CreateInputLayout(inputlayout, inputlayout,

numberOfElements,numberOfElements,

PassDescription.pIAInputSignature,PassDescription.pIAInputSignature,

PassDescription.IAInputSignatureSize,PassDescription.IAInputSignatureSize,

&g_pd3d10InputVertexLayout);&g_pd3d10InputVertexLayout);

if(FAILED(hresult_))if(FAILED(hresult_))return hresult_;return hresult_;

g_pd3d10Device->IASetInputLayout(g_pd3d10InputVertexLayout);g_pd3d10Device->IASetInputLayout(g_pd3d10InputVertexLayout);

A Very Simple Direct3D 10 A Very Simple Direct3D 10 ProgramProgram

/* specify our triangle’s vertices *//* specify our triangle’s vertices *///////////////////////////////////////////////////////////////TriangleVertex vertices[] =TriangleVertex vertices[] ={{

D3DXVECTOR3(0.0f, 1.0f, 1.0f),D3DXVECTOR3(0.0f, 1.0f, 1.0f),D3DXVECTOR3(1.0f, -1.0f, 1.0f),D3DXVECTOR3(1.0f, -1.0f, 1.0f),D3DXVECTOR3(-1.0f, -1.0f, 1.0f),D3DXVECTOR3(-1.0f, -1.0f, 1.0f),

};};

/* setup the buffer resource *//* setup the buffer resource *///////////////////////////////////////////////////////D3D10_BUFFER_DESC bufferdesc;D3D10_BUFFER_DESC bufferdesc;bufferdesc.Usage bufferdesc.Usage = D3D10_USAGE_DEFAULT;= D3D10_USAGE_DEFAULT;bufferdesc.BindFlags bufferdesc.BindFlags = D3D10_BIND_VERTEX_BUFFER;= D3D10_BIND_VERTEX_BUFFER;bufferdesc.CPUAccessFlags bufferdesc.CPUAccessFlags = 0;= 0;bufferdesc.MiscFlags bufferdesc.MiscFlags = 0;= 0;bufferdesc.ByteWidth bufferdesc.ByteWidth = sizeof(TriangleVertex)*3;= sizeof(TriangleVertex)*3;

/* initialize resource *//* initialize resource */////////////////////////////////////////////////////////////D3D10_SUBRESOURCE_DATA ResourceData;D3D10_SUBRESOURCE_DATA ResourceData;ResourceData.pSysMem = vertices;ResourceData.pSysMem = vertices;

A Very Simple Direct3D 10 A Very Simple Direct3D 10 ProgramProgram

hresult_ = g_pd3d10Device->CreateBuffer(&bufferdesc,hresult_ = g_pd3d10Device->CreateBuffer(&bufferdesc, &ResourceData, &g_pd3d10VertexBuffer);&ResourceData, &g_pd3d10VertexBuffer);

if(FAILED(hresult_))if(FAILED(hresult_))return hresult_;return hresult_;

/* setup the vertex buffer *//* setup the vertex buffer *///////////////////////////////////////////////////UINT elementstride = sizeof(TriangleVertex);UINT elementstride = sizeof(TriangleVertex);

UINT bufferoffset = 0;UINT bufferoffset = 0;g_pd3d10Device->IASetVertexBuffers(0, 1, &g_pd3d10VertexBuffer,g_pd3d10Device->IASetVertexBuffers(0, 1, &g_pd3d10VertexBuffer,

&elementstride, &bufferoffset);&elementstride, &bufferoffset);

/* bind the primitive type and data order information to a/* bind the primitive type and data order information to a triangle list */triangle list */g_pd3d10Device->IASetPrimitiveTopology(g_pd3d10Device->IASetPrimitiveTopology(

D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);return S_OK;return S_OK;

}}

A Very Simple Direct3D 10 A Very Simple Direct3D 10 ProgramProgram

/* setup our WndProc callback *//* setup our WndProc callback */LRESULT CALLBACK WndProc(HWND hWindow, UINT msg, WPARAM wParam, LRESULT CALLBACK WndProc(HWND hWindow, UINT msg, WPARAM wParam,

LPARAM lParam)LPARAM lParam){{

HDC devicecontext;HDC devicecontext;PAINTSTRUCT paintstructure;PAINTSTRUCT paintstructure;

switch(msg)switch(msg){{

case WM_DESTROY:case WM_DESTROY:PostQuitMessage(0);PostQuitMessage(0);break;break;

case WM_PAINT:case WM_PAINT:devicecontext = BeginPaint (hWindow, &paintstructure);devicecontext = BeginPaint (hWindow, &paintstructure);EndPaint(hWindow, &paintstructure);EndPaint(hWindow, &paintstructure);

break;break;

default:default:return DefWindowProc(hWindow, msg, wParam, lParam);return DefWindowProc(hWindow, msg, wParam, lParam);

}}return 0;return 0;

}}

A Very Simple Direct3D 10 A Very Simple Direct3D 10 ProgramProgram

/* checks whether an object has been created, and if it has, deallocates it *//* checks whether an object has been created, and if it has, deallocates it */void Clean()void Clean(){{

if(g_pd3d10Device)if(g_pd3d10Device)g_pd3d10Device->ClearState();g_pd3d10Device->ClearState();

if(g_pd3d10InputVertexLayout)if(g_pd3d10InputVertexLayout)g_pd3d10InputVertexLayout->Release();g_pd3d10InputVertexLayout->Release();

if(g_pd3d10VertexBuffer)if(g_pd3d10VertexBuffer)g_pd3d10VertexBuffer->Release();g_pd3d10VertexBuffer->Release();

if(g_pd3d10RenderTargetView)if(g_pd3d10RenderTargetView)g_pd3d10RenderTargetView->Release();g_pd3d10RenderTargetView->Release();

if(g_pd3d10Effect)if(g_pd3d10Effect)g_pd3d10Effect->Release();g_pd3d10Effect->Release();

if(g_pd3d10Device)if(g_pd3d10Device)g_pd3d10Device->Release();g_pd3d10Device->Release();

if(g_pdx10SwapChain)if(g_pdx10SwapChain)g_pdx10SwapChain->Release();g_pdx10SwapChain->Release();

}}

A Very Simple Direct3D 10 A Very Simple Direct3D 10 ProgramProgram

/* draw the triangle *//* draw the triangle */void DrawTriangle()void DrawTriangle(){{

/* start by clearing the back-buffer with the color white *//* start by clearing the back-buffer with the color white */float ClearBufferColour[4] = {1.0f, 1.0f, 1.0f, 1.0f};float ClearBufferColour[4] = {1.0f, 1.0f, 1.0f, 1.0f};g_pd3d10Device->ClearRenderTargetView(g_pd3d10RenderTargetView, g_pd3d10Device->ClearRenderTargetView(g_pd3d10RenderTargetView, ClearBufferColour);ClearBufferColour);

/* obtain the D3D10_TECHNIQUE_DESC effect-variable description *//* obtain the D3D10_TECHNIQUE_DESC effect-variable description */D3D10_TECHNIQUE_DESC technique;D3D10_TECHNIQUE_DESC technique;g_pd3d10EffectTechnique->GetDesc(&technique);g_pd3d10EffectTechnique->GetDesc(&technique);

/* render by looping over the number of technique passes *//* render by looping over the number of technique passes */for(int i = 0; i < technique.Passes; ++i)for(int i = 0; i < technique.Passes; ++i){{g_pd3d10EffectTechnique->GetPassByIndex(i)->Apply(0);g_pd3d10EffectTechnique->GetPassByIndex(i)->Apply(0);g_pd3d10Device->Draw(3, 0);g_pd3d10Device->Draw(3, 0);}}

/* switch the back- and front-buffer and display the/* switch the back- and front-buffer and display thetriangle */triangle */g_pdx10SwapChain->Present(0,0);g_pdx10SwapChain->Present(0,0);

}}

A Very Simple Direct3D 10 A Very Simple Direct3D 10 ProgramProgram

float4 VSVertexShader(float4 Pos : POSITION) : SV_POSITIONfloat4 VSVertexShader(float4 Pos : POSITION) : SV_POSITION{{ return Pos;return Pos;}}

float4 PSPixelShader(float4 Pos : SV_POSITION) : SV_Targetfloat4 PSPixelShader(float4 Pos : SV_POSITION) : SV_Target{{ return float4(1.0f, 0.0f, 0.0f, 1.0f);return float4(1.0f, 0.0f, 0.0f, 1.0f);}}

technique10 Triangletechnique10 Triangle{{ pass P0pass P0 {{ SetGeometryShader(NULL);SetGeometryShader(NULL); SetVertexShader(CompileShader(vs_4_0, VSVertexShader()));SetVertexShader(CompileShader(vs_4_0, VSVertexShader())); SetPixelShader(CompileShader(ps_4_0, PSPixelShader()));SetPixelShader(CompileShader(ps_4_0, PSPixelShader())); }}}}