GAM531 DPS931 – Week 9 OpenGL 4.3 and Direct X 11
BlendState <RS> Singleton Texture <RS> Interface Base Class RM = Resource Manager BM = Base Manager IM = Iterative Manager Sh = Shader SO = SceneObject BlendState <RS> Singleton Texture <RS> DX/GL Uniform Buffer m Contains (m = many) RM m Either or (only one) DX/GL API Wrapper BlendStateManager <RS> Mesh <RS> TextureManager <RS> RM DX11 Device GL 4.3 Device IM ActorManager <RS> SO m m Actor <RS> RM ResourceController <RS> SceneController <RS> IM TextureSampler <RS> MeshManager <RS> Engine <RS> CameraManager <RS> m RM m SO SamplerManager <RS> LightManager <RS> IM Camera <RS> VertexFormat <RS> NodeManager <RS> BM MaterialManager <RS> RM VertexFormatManager<RS> RM m ShaderManager <RS> m m SO m m m Sh Sh Light <RS> Node <RS> m Material <RS> VertexShader <RS> FragmentShader <RS>
Cracking Open the Device template <RenderSystem RS> class Device {}; template <> class Device<RS_DX11> { ID3D11Device* dev; … }; template <> class Device<RS_GL43> { HGLRC context; … }; DX11 Device GL 4.3 Device DirectX Device Object Ptr Engine <RS> OpenGL Context Handle
Same Name, Completely Different Classes template <> class Device<RS_DX11> { IDXGISwapChain* swap; ID3D11Device* dev; ID3D11DeviceContext* con; ID3D11RenderTargetView* backbuffer; ID3D11DepthStencilView* depthBuffer; bool active; public: Device() : swap(0), dev(0), con(0), active(false) {} virtual ~Device(); void init(Window*); void release(); void renderStart(); void renderEnd(); void setFullScreen(bool); bool isActive() {return active;} void bindPrimitive(const PrimitiveTopology&); void draw(uint32, uint32); void drawIndexed(uint32, uint32, uint32); IDXGISwapChain* _exposeSwap() {return swap;} ID3D11Device* _exposeDevice() {return dev;} ID3D11DeviceContext* _exposeContext(); }; template<> class Device<RS_GL43> { HGLRC context; HDC hdc; HWND wh; GLuint prim; Window* window; bool active; public: Device() : context(0), hdc(0), active(false), window(0) {} virtual ~Device(); void init(Window*); void release(); void renderStart(); void renderEnd(); void setFullScreen(bool); bool isActive() {return active;} void bindPrimitive(const PrimitiveTopology&); void draw(uint32, uint32); void drawIndexed(uint32, uint32, uint32); };
Importing DX11 and OpenGL 4.3 #include <d3d11.h> #include <d3dx11.h> #include <d3dx10.h> #pragma comment (lib, "d3d11.lib") #pragma comment (lib, "d3dx11.lib") #pragma comment (lib, "d3dx10.lib") #pragma comment (lib, "DXGI.lib") (You must download the GLEW library) #include "GL/glew.h" #include "GL/wglew.h“
Biggest Difference Between GL and DX Object Oriented Free Floating Functions con->OMSetRenderTargets(1, &backbuffer, depthBuffer); dev->CreateDepthStencilView(pDepthStencil, &descDSV,&depthBuffer) dev->CreateTexture2D(&descDepth, NULL, &pDepthStencil ) swap->Release(); context = wglCreateContextAttribsARB(hdc, 0, attribs); glEnable(GL_DEPTH_TEST); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, format, type, data); wglDeleteContext(context);
Where Do We Start? Device Swap Chain Context Context Free Floating Functions Object Creation Frame Buffer Object Creation Frame Buffer Contains the state of the render system Contains the state of the render system
Initializing a Render System DXGI_SWAP_CHAIN_DESC d; ZeroMemory(&d, sizeof(DXGI_SWAP_CHAIN_DESC)); d.BufferCount = 1; d.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; d.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; d.OutputWindow = w->getWindowID(); d.SampleDesc.Count = 1; d.SampleDesc.Quality = 0; d.Windowed = TRUE d.BufferDesc.Width = w->getSize().x(); d.BufferDesc.Height = w->getSize().y(); d.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; d.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; D3D_FEATURE_LEVEL lev = D3D_FEATURE_LEVEL_11_0; D3D11CreateDeviceAndSwapChain(0, D3D_DRIVER_TYPE_HARDWARE, 0, 0, &lev, 1, D3D11_SDK_VERSION, &d, &swap, &dev, 0, &con)); hdc = GetDC(win->getWindowID()); PIXELFORMATDESCRIPTOR pfd; memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = pfd.cDepthBits = 32; pfd.iLayerType = PFD_MAIN_PLANE; int pixFmt = ChoosePixelFormat(hdc, &pfd); ... auto tc = wglCreateContext(hdc); ... glewInit(); int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 4, WGL_CONTEXT_MINOR_VERSION_ARB, 3, WGL_CONTEXT_FLAGS_ARB, 0, 0}; context = wglCreateContextAttribsARB(hdc, 0, attribs); wglMakeCurrent(0,0); wglDeleteContext(tc); wglMakeCurrent(hdc, context);
Now We Need to Draw to Something Currently On Screen Currently Being Written To Color buffer[1920][1080]; struct Color {float r, g, b;}; Screen may refresh before we are done rendering!
Setting Up The Back Buffer ID3D11Texture2D* bb; swap->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&bb)); dev->CreateRenderTargetView(bb, 0, &backbuffer)); bb->Release(); con->OMSetRenderTargets(1, &backbuffer, 0); //Was setup sufficiently during context construction glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
Is the pixel closer to the Camera? Rendering With Depth If Object A is rendered, then B, then C… C will be drawn on top of B, which is drawn on top of A… Is the pixel closer to the Camera? struct Color {float r, g, b;}; Color buffer[1920][1080]; float depthBuffer[1920][1080];
Setting Up The Depth Buffer ID3D11Texture2D* pDepthStencil = NULL; D3D11_TEXTURE2D_DESC descDepth; descDepth.Width = d.BufferDesc.Width; descDepth.Height = d.BufferDesc.Height; descDepth.MipLevels = descDepth.ArraySize = 1; descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT descDepth.SampleDesc.Count = 1; descDepth.SampleDesc.Quality = 0; descDepth.Usage = D3D11_USAGE_DEFAULT; descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; descDepth.CPUAccessFlags = 0; descDepth.MiscFlags = 0; dev->CreateTexture2D(&descDepth, 0, &pDepthStencil)); D3D11_DEPTH_STENCIL_DESC dsDesc; ZeroMemory(&dsDesc, sizeof(D3D11_DEPTH_STENCIL_DESC)); dsDesc.DepthEnable = true; dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; dsDesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL; dsDesc.StencilEnable = true; dsDesc.StencilReadMask = dsDesc.StencilWriteMask = 0xFF; … con->OMSetRenderTargets(1, &backbuffer, depthBuffer); glEnable(GL_DEPTH_TEST); glDepthRange(0, 1); glDepthMask (GL_TRUE); glDepthFunc(GL_LEQUAL); glClearDepth(1.0);
Where to Render To View Port Stats: X = 300 Y = 0 Height = 800 Width = 1200
Setting Up The View Port D3D11_VIEWPORT vp; ZeroMemory(&vp, sizeof(D3D11_VIEWPORT)); vp.TopLeftX = 0; vp.TopLeftY = 0; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; vp.Width = (float)w->getSize().x(); vp.Height = (float)w->getSize().y(); con->RSSetViewports(1, &vp); glViewport(0,0,win->getSize().x(), win->getSize().y());
Rendering The World One Object At A Time
Render Processes //Before each new frame con->ClearRenderTargetView(backbuffer, D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f)); con->ClearDepthStencilView(depthBuffer, D3D11_CLEAR_DEPTH, 1.0f, 0); //Bind Primitives (more about this later) con->IASetPrimitiveTopology(_dxTranPrim(p.pte)); //Draw an object (more about this later) con->Draw(size, offset); //Flip the back buffer (finish the frame) swap->Present(0, 0); //Before each new frame glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Draw an object (more about this later) glDrawArrays(prim, offset, size); //Flip the back buffer (finish the frame) SwapBuffers(hdc);
Setting Up Full Screen Mode if (b) { SetWindowLongPtr(wh, GWL_STYLE, WS_SYSMENU | WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE); SetWindowPos(wh, HWND_TOP, 0, 0, window->getSize().x(), window->getSize().y(), SWP_FRAMECHANGED); DEVMODE dmScreenSettings; memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); dmScreenSettings.dmSize=sizeof(dmScreenSettings); dmScreenSettings.dmPelsWidth = window->getSize().x(); dmScreenSettings.dmPelsHeight= window->getSize().y(); dmScreenSettings.dmBitsPerPel = 32; dmScreenSettings.dmFields=DM_BITSPERPEL |DM_PELSWIDTH|DM_PELSHEIGHT; window->showWindow(true); ShowCursor(FALSE); } else { SetWindowLongPtr(wh, GWL_STYLE, WS_OVERLAPPEDWINDOW | SetWindowPos(wh,HWND_TOP,0, 0,window->getSize().x(), ShowCursor(TRUE); } swap->SetFullscreenState(b, 0);
Releasing The Render Systems swap->SetFullscreenState(false, 0); swap->Release(); backbuffer->Release(); depthBuffer->Release(); dev->Release(); con->Release(); wglMakeCurrent(0,0); wglDeleteContext(context); ReleaseDC(wh,hdc);
Checking For Errors auto er = dev->CreateRenderTargetView(bb, 0, &backbuffer)); if(FAILED(er)) { //Error resolution } auto er = glGetError(); if(er != GL_NO_ERROR) { //Error resolution }
To Do Continue work on engine enhancement Read this week’s lab Read this week’s notes Re-implement OpenGL Device functions