graphics

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit 5650fcae7c4a9e4c815efff572b423d237d0fd10
parent fa2fd2f7efa608df989f83e25840ed986c2a8d1f
Author: Brian Swetland <swetland@frotz.net>
Date:   Thu, 31 Jan 2013 15:49:32 -0800

wip d3d goop

Diffstat:
Acommon/app.h | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acommon/dxapp.cc | 221+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahello/hello.cc | 283+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahello/hello.fx | 28++++++++++++++++++++++++++++
4 files changed, 598 insertions(+), 0 deletions(-)

diff --git a/common/app.h b/common/app.h @@ -0,0 +1,65 @@ +/* Copyright 2013 Brian Swetland <swetland@frotz.net> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _DX_APP_H_ +#define _DX_APP_H_ + +#include <windows.h> + +/* TODO: figure out wtf is up with dxgitype.h macro redefinitions... */ +#pragma warning ( disable : 4005 ) + +#include <d3d10.h> +#include <d3dx10.h> + +#ifdef _DEBUG +#define DEVICE_DEBUG_FLAGS D3D10_CREATE_DEVICE_DEBUG +#define SHADER_DEBUG_FLAGS D3D10_SHADER_DEBUG +#else +#define DEVICE_DEBUG_FLAGS 0 +#define SHADER_DEBUG_FLAGS 0 +#endif + +class App { +public: + App(); + virtual ~App(); + virtual int init(void) = 0; + virtual void render(void) = 0; + + int start(HINSTANCE hInstance, int nCmdShow); + +protected: + int width; + int height; + ID3D10Device *device; + IDXGISwapChain *swap; + ID3D10RenderTargetView *target; + ID3D10Texture2D *depthStencil; + ID3D10DepthStencilView *depthStencilView; + ID3D10RasterizerState *rasterizerState; + +private: + int initD3D(void); + HWND hwnd; + HINSTANCE hinstance; +}; + +App *createApp(void); + +void printx(const char *fmt, ...); +void printmtx(D3DXMATRIX *m, const char *name); + +#endif +\ No newline at end of file diff --git a/common/dxapp.cc b/common/dxapp.cc @@ -0,0 +1,221 @@ +/* Copyright 2013 Brian Swetland <swetland@frotz.net> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <stdarg.h> + +#include "app.h" + +LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); + +App::App() : width(800), height(600), device(NULL), target(NULL), swap(NULL) { +} + +App::~App() { + if (device) device->ClearState(); + if (rasterizerState) rasterizerState->Release(); + if (depthStencilView) depthStencilView->Release(); + if (depthStencil) depthStencil->Release(); + if (target) target->Release(); + if (swap) swap->Release(); + if (device) device->Release(); +} + +static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { + PAINTSTRUCT ps; + HDC hdc; + switch( message ) { + case WM_PAINT: + hdc = BeginPaint( hWnd, &ps ); + EndPaint( hWnd, &ps ); + break; + case WM_DESTROY: + PostQuitMessage( 0 ); + break; + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + return 0; +} + +int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) { + App *app = createApp(); + + if (app->start(hInstance, nCmdShow)) + return 0; + + MSG msg = {0}; + while (msg.message != WM_QUIT) { + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } else { + app->render(); + } + } + + delete app; + return (int) msg.wParam; +} + +int App::start(HINSTANCE hInstance, int nCmdShow) { + hinstance = hInstance; + + WNDCLASSEX wc; + memset(&wc, 0, sizeof(wc)); + wc.cbSize = sizeof(WNDCLASSEX); + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = WndProc; + wc.hInstance = hInstance; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); + wc.lpszClassName = "MyWindowClass"; + + if (!RegisterClassEx(&wc)) + return -1; + + RECT rc = { 0, 0, width, height }; + + AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, false); + hwnd = CreateWindow("MyWindowCLass", "Hello", WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, width, height, + NULL, NULL, hInstance, NULL); + if (!hwnd) + return -1; + + ShowWindow(hwnd, nCmdShow); + + if (FAILED(initD3D())) + return -1; + if (init()) + return -1; + return 0; +} + +int App::initD3D(void) { + HRESULT hr; + RECT rc; + GetClientRect(hwnd, &rc); + + unsigned width = rc.right - rc.left; + unsigned height = rc.bottom - rc.top; + + DXGI_SWAP_CHAIN_DESC sc; + ZeroMemory(&sc, sizeof(sc)); + sc.BufferCount = 1; + sc.BufferDesc.Width = width; + sc.BufferDesc.Height = height; + sc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + sc.BufferDesc.RefreshRate.Numerator = 60; + sc.BufferDesc.RefreshRate.Denominator = 1; + sc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + sc.OutputWindow = hwnd; + sc.SampleDesc.Count = 1; + sc.SampleDesc.Quality = 0; + sc.Windowed = TRUE; + + hr = D3D10CreateDeviceAndSwapChain(NULL, + D3D10_DRIVER_TYPE_HARDWARE, NULL, DEVICE_DEBUG_FLAGS, + D3D10_SDK_VERSION, &sc, &swap, &device); + if (FAILED(hr)) + return -1; + + ID3D10Texture2D *buffer; + hr = swap->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*) &buffer); + if (FAILED(hr)) + return hr; + hr = device->CreateRenderTargetView(buffer, NULL, &target); + buffer->Release(); + if (FAILED(hr)) + return hr; + + D3D10_TEXTURE2D_DESC td; + td.Width = width; + td.Height = height; + td.MipLevels = 1; + td.ArraySize = 1; + td.Format = DXGI_FORMAT_D32_FLOAT; + td.SampleDesc.Count = 1; + td.SampleDesc.Quality = 0; + td.Usage = D3D10_USAGE_DEFAULT; + td.BindFlags = D3D10_BIND_DEPTH_STENCIL; + td.CPUAccessFlags = 0; + td.MiscFlags = 0; + hr = device->CreateTexture2D(&td, NULL, &depthStencil); + if (FAILED(hr)) + return -1; + + D3D10_DEPTH_STENCIL_VIEW_DESC dsvd; + dsvd.Format = td.Format; + dsvd.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2D; + dsvd.Texture2D.MipSlice = 0; + hr = device->CreateDepthStencilView(depthStencil, &dsvd, &depthStencilView); + if (FAILED(hr)) + return -1; + + D3D10_VIEWPORT vp; + vp.Width = width; + vp.Height = height; + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + vp.TopLeftX = 0; + vp.TopLeftY = 0; + device->RSSetViewports(1, &vp); + + D3D10_RASTERIZER_DESC rd; + rd.FillMode = D3D10_FILL_SOLID; + rd.CullMode = D3D10_CULL_BACK; + rd.FrontCounterClockwise = true; + rd.DepthBias = 0; + rd.DepthBiasClamp = 0.0f; + rd.SlopeScaledDepthBias =0.0f; + rd.DepthClipEnable = true; + rd.ScissorEnable = false; + rd.MultisampleEnable = false; + rd.AntialiasedLineEnable = false; + hr = device->CreateRasterizerState(&rd, &rasterizerState); + if (FAILED(hr)) + return -1; + device->RSSetState(rasterizerState); + + device->OMSetRenderTargets(1, &target, depthStencilView); + + return S_OK; +} + +void printx(const char *fmt, ...) { +#if DEBUG || _DEBUG + char buf[128]; + va_list ap; + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + buf[127] = 0; + va_end(ap); + OutputDebugString(buf); +#endif +} + +void printmtx(D3DXMATRIX *m, const char *name) { +#if DEBUG || _DEBUG + printx("| %8.4f %8.4f %8.4f %8.4f | \"%s\"\n", + m->_11, m->_12, m->_13, m->_14, name); + printx("| %8.4f %8.4f %8.4f %8.4f |\n", + m->_21, m->_22, m->_23, m->_24); + printx("| %8.4f %8.4f %8.4f %8.4f |\n", + m->_31, m->_32, m->_33, m->_34); + printx("| %8.4f %8.4f %8.4f %8.4f |\n", + m->_41, m->_42, m->_43, m->_44); +#endif +} diff --git a/hello/hello.cc b/hello/hello.cc @@ -0,0 +1,282 @@ +/* Copyright 2013 Brian Swetland <swetland@frotz.net> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "app.h" +#include "matrix.h" + +struct CubeVertex { + D3DXVECTOR3 Pos; + D3DXVECTOR4 Color; +}; + +static D3D10_INPUT_ELEMENT_DESC cube_layout[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0 }, +}; + +#if 0 // original +static CubeVertex cube_vertices[] = { + { D3DXVECTOR3( -1.0f, 1.0f, -1.0f ), D3DXVECTOR4( 0.0f, 0.0f, 1.0f, 1.0f ) }, + { D3DXVECTOR3( 1.0f, 1.0f, -1.0f ), D3DXVECTOR4( 0.0f, 1.0f, 0.0f, 1.0f ) }, + { D3DXVECTOR3( 1.0f, 1.0f, 1.0f ), D3DXVECTOR4( 0.0f, 1.0f, 1.0f, 1.0f ) }, + { D3DXVECTOR3( -1.0f, 1.0f, 1.0f ), D3DXVECTOR4( 1.0f, 0.0f, 0.0f, 1.0f ) }, + { D3DXVECTOR3( -1.0f, -1.0f, -1.0f ), D3DXVECTOR4( 1.0f, 0.0f, 1.0f, 1.0f ) }, + { D3DXVECTOR3( 1.0f, -1.0f, -1.0f ), D3DXVECTOR4( 1.0f, 1.0f, 0.0f, 1.0f ) }, + { D3DXVECTOR3( 1.0f, -1.0f, 1.0f ), D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f ) }, + { D3DXVECTOR3( -1.0f, -1.0f, 1.0f ), D3DXVECTOR4( 0.0f, 0.0f, 0.0f, 1.0f ) }, +}; +#else // flip z +static CubeVertex cube_vertices[] = { + { D3DXVECTOR3( -1.0f, 1.0f, 1.0f ), D3DXVECTOR4( 0.0f, 0.0f, 1.0f, 1.0f ) }, + { D3DXVECTOR3( 1.0f, 1.0f, 1.0f ), D3DXVECTOR4( 0.0f, 1.0f, 0.0f, 1.0f ) }, + { D3DXVECTOR3( 1.0f, 1.0f, -1.0f ), D3DXVECTOR4( 0.0f, 1.0f, 1.0f, 1.0f ) }, + { D3DXVECTOR3( -1.0f, 1.0f, -1.0f ), D3DXVECTOR4( 1.0f, 0.0f, 0.0f, 1.0f ) }, + { D3DXVECTOR3( -1.0f, -1.0f, 1.0f ), D3DXVECTOR4( 1.0f, 0.0f, 1.0f, 1.0f ) }, + { D3DXVECTOR3( 1.0f, -1.0f, 1.0f ), D3DXVECTOR4( 1.0f, 1.0f, 0.0f, 1.0f ) }, + { D3DXVECTOR3( 1.0f, -1.0f, -1.0f ), D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f ) }, + { D3DXVECTOR3( -1.0f, -1.0f, -1.0f ), D3DXVECTOR4( 0.0f, 0.0f, 0.0f, 1.0f ) }, +}; +#endif + +#if 0 +static DWORD cube_indices[] = { // CW, but CCW on Z faces if RH + 3,1,0, 2,1,3, + 0,5,4, 1,5,0, + 3,4,7, 0,4,3, + 1,6,5, 2,6,1, + 2,7,6, 3,7,2, + 6,4,5, 7,4,6, +}; +#else +static DWORD cube_indices[] = { // CCW + 0,1,3, 3,1,2, + 4,5,0, 0,5,1, + 7,4,3, 3,4,0, + 5,6,1, 1,6,2, + 6,7,2, 2,7,3, + 5,4,6, 6,4,7, +}; +#endif + +class TestApp : public App { +public: + TestApp(); + ~TestApp(); + int init(void); + void render(void); + +private: + float t; + DWORD timeStart; + + ID3D10Effect *effect; + ID3D10EffectTechnique *technique; + ID3D10InputLayout *layout; + ID3D10Buffer *vtxbuf; + ID3D10Buffer *idxbuf; + + ID3D10EffectMatrixVariable *uMVP; +// ID3D10EffectMatrixVariable *uView; +// ID3D10EffectMatrixVariable *uProjection; + + D3DXMATRIX world; + D3DXMATRIX view; + D3DXMATRIX projection; + + mat4 proj; + mat4 mvp; +}; + +TestApp::TestApp() : App(), t(0.0f), timeStart(0), vtxbuf(NULL), idxbuf(NULL), layout(NULL), effect(NULL) { +} + +TestApp::~TestApp() { + if (vtxbuf) vtxbuf->Release(); + if (idxbuf) idxbuf->Release(); + if (layout) layout->Release(); + if (effect) effect->Release(); +} + +int TestApp::init(void) { + HRESULT hr; + + hr = D3DX10CreateEffectFromFile("hello.fx", NULL, NULL, "fx_4_0", + D3D10_SHADER_ENABLE_STRICTNESS | SHADER_DEBUG_FLAGS, + 0, device, NULL, NULL, &effect, NULL, NULL ); + + if (FAILED(hr)) { + MessageBox(NULL, "Cannot open hello.fx", "Error", MB_OK); + return -1; + } + + technique = effect->GetTechniqueByName("Render"); +// uWorld = effect->GetVariableByName("World")->AsMatrix(); +// uView = effect->GetVariableByName("View")->AsMatrix(); + uMVP = effect->GetVariableByName("MVP")->AsMatrix(); + + D3D10_PASS_DESC pass; + technique->GetPassByIndex(0)->GetDesc(&pass); + hr = device->CreateInputLayout(cube_layout, sizeof(cube_layout)/sizeof(cube_layout[0]), + pass.pIAInputSignature, pass.IAInputSignatureSize, &layout); + if (FAILED(hr)) + return -1; + + D3D10_BUFFER_DESC bd; + bd.Usage = D3D10_USAGE_DEFAULT; + bd.ByteWidth = sizeof(CubeVertex) * sizeof(cube_vertices)/sizeof(cube_vertices[0]); //XXX + bd.BindFlags = D3D10_BIND_VERTEX_BUFFER; + bd.CPUAccessFlags = 0; + bd.MiscFlags = 0; + + D3D10_SUBRESOURCE_DATA InitData; + InitData.pSysMem = cube_vertices; + hr = device->CreateBuffer(&bd, &InitData, &vtxbuf); + if (FAILED(hr)) + return -1; + + bd.Usage = D3D10_USAGE_DEFAULT; + bd.ByteWidth = sizeof(DWORD) * sizeof(cube_indices) / sizeof(cube_indices[0]); + bd.BindFlags = D3D10_BIND_INDEX_BUFFER; + bd.CPUAccessFlags = 0; + bd.MiscFlags = 0; + InitData.pSysMem = cube_indices; + hr = device->CreateBuffer(&bd, &InitData, &idxbuf); + if (FAILED(hr)) + return -1; + + D3DXMatrixIdentity(&world); + + D3DXVECTOR3 eye(0.0f, 0.0f, 5.0f); + D3DXVECTOR3 at(0.0f, 0.0f, 0.0f); + D3DXVECTOR3 up(0.0f, 1.0f, 0.0f); + D3DXMatrixLookAtLH(&view, &eye, &at, &up); + + D3DXMatrixIdentity(&view); + D3DXMatrixTranslation(&view, 0, 0, 10); + + D3DXMatrixPerspectiveFovRH(&projection, (float) D3DX_PI * 0.5f, width / (float) height, 0.1f, 100.0f); +// printmtx(&projection, "proj1"); + mat4 tmp; + tmp.setPerspective(D3DX_PI * 0.5, width / (float) height, 0.1f, 100.0f); + memcpy(&projection,&tmp,sizeof(float[16])); +// printmtx(&projection, "proj2"); + return 0; +} + +void TestApp::render(void) { + static float t = 0.0f; + static DWORD timeStart = 0; + DWORD timeCur = GetTickCount(); + if (timeStart == 0) + timeStart = timeStart; + t = (timeCur - timeStart) / 1000.0f; + + float rgba[4] = { 0.0f, 0.125f, 0.3f, 1.0f }; + device->ClearRenderTargetView(target, rgba); + device->ClearDepthStencilView(depthStencilView, D3D10_CLEAR_DEPTH, 1.0f, 0 ); +#if 0 + printmtx(&world,"world"); + printmtx(&view,"view"); + printmtx(&projection,"projection"); +#endif + + +// D3DXMATRIX xlat, MVP, rotn, tmp; + + UINT stride = sizeof(CubeVertex); + UINT offset = 0; + device->IASetInputLayout(layout); + device->IASetVertexBuffers(0, 1, &vtxbuf, &stride, &offset); + device->IASetIndexBuffer(idxbuf, DXGI_FORMAT_R32_UINT, 0); + device->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + D3D10_TECHNIQUE_DESC td; + technique->GetDesc(&td); + + mat4 world, view, proj, tmp, mvp; + + proj.setPerspective(M_PI * 0.5, 1024.0/768.0, 1.0, 100.0); + view.identity().rotateX(D2R(25)).translate(0, 0, -10); + world.identity().rotateY(t); + mvp = world * view * proj; + uMVP->SetMatrix((float*) mvp.data()); + for (unsigned p = 0; p < td.Passes; ++p) { + technique->GetPassByIndex(p)->Apply(0); + device->DrawIndexed(36, 0, 0 ); + } + + world.identity().rotateY(t).translate(-5,0,0).rotateY(t); + mvp = world * view * proj; + uMVP->SetMatrix((float*) mvp.data()); + for (unsigned p = 0; p < td.Passes; ++p) { + technique->GetPassByIndex(p)->Apply(0); + device->DrawIndexed(36, 0, 0 ); + } + +#if 0 + D3DXMatrixIdentity(&view); +// D3DXMatrixRotationX(&tmp,D2R(-25)); +// D3DXMatrixMultiply(&view,&view,&tmp); + D3DXMatrixTranslation(&tmp, 0, 0, -10); + D3DXMatrixMultiply(&view,&view,&tmp); + + D3D10_TECHNIQUE_DESC td; + technique->GetDesc(&td); + D3DXMatrixRotationY(&world, t); + MVP = world * view * projection; + uMVP->SetMatrix((float*) &MVP); + //uMVP->SetMatrixTranspose((float*) &MVP); + for (unsigned p = 0; p < td.Passes; ++p) { + technique->GetPassByIndex(p)->Apply(0); + device->DrawIndexed(36, 0, 0 ); + } + + D3DXMatrixRotationY(&world, t); + D3DXMatrixTranslation(&xlat, -5.0, 0.0, 0.0); + D3DXMatrixRotationY(&rotn, t); + D3DXMatrixMultiply(&world, &world, &xlat); + //printmtx(&world, "v1"); + D3DXMatrixMultiply(&world, &world, &rotn); + MVP = world * view * projection; + //printmtx(&MVP, "mvp1"); + uMVP->SetMatrix((float*) &MVP); + //uMVP->SetMatrixTranspose((float*) &MVP); +#if 0 + mat4 XMVP, xworld, xxlat, xrotn, xview, xproj; + memcpy(&xview, &view, sizeof(float[16])); + memcpy(&xproj, &projection, sizeof(float[16])); + memcpy(&xworld, &rotn, sizeof(float[16])); + memcpy(&xxlat, &xlat, sizeof(float[16])); + memcpy(&xrotn, &rotn, sizeof(float[16])); + xworld.mul(xworld, xxlat); + memcpy(&world, &xworld, sizeof(float[16])); + //printmtx(&world, "v2"); + xworld.mul(xworld, xrotn); + XMVP = xworld * xview * xproj; + memcpy(&MVP, &XMVP, sizeof(float[16])); + //printmtx(&MVP, "mvp2"); + //uMVP->SetMatrixTranspose((float*) &MVP); + uMVP->SetMatrix((float*)XMVP.data()); +#endif + for (unsigned p = 0; p < td.Passes; ++p) { + technique->GetPassByIndex(p)->Apply(0); + device->DrawIndexed(36, 0, 0 ); + } +#endif + swap->Present(0, 0); +} + +App *createApp(void) { + return new TestApp(); +} +\ No newline at end of file diff --git a/hello/hello.fx b/hello/hello.fx @@ -0,0 +1,27 @@ + +matrix MVP; + +struct VS_OUTPUT { + float4 Pos : SV_POSITION; + float4 Color : COLOR0; +}; + +VS_OUTPUT VS( float4 Pos : POSITION, float4 Color : COLOR ) { + VS_OUTPUT output = (VS_OUTPUT) 0; + output.Pos = mul(Pos,MVP); // DX +// output.Pos = mul(MVP, Pos); // GL + output.Color = Color; + return output; +} + +float4 PS( VS_OUTPUT input ) : SV_Target { + return input.Color; +} + +technique10 Render { + pass P0 { + SetVertexShader(CompileShader(vs_4_0, VS())); + SetGeometryShader(NULL); + SetPixelShader(CompileShader(ps_4_0, PS())); + } +} +\ No newline at end of file