Всем привет! Начал изучать directx и столкнулся с проблемой.
Если в 9 версии для создания треугольника, достаточно создать вертексный буффер со структурой, н-р:
struct MYVERTEX
{
FLOAT x, y, z, w;
DWORD color;
};
где я могу помимо координат, установить цвет и сделать это все динамически в коде,
то в 11 версии, если я правильно понял, примитивы рисуются шейдерами, т.е. с туториала:
//-------------------------------------------------------------------------------------- // Create Direct3D device and swap chain //-------------------------------------------------------------------------------------- HRESULT InitDevice() { HRESULT hr = S_OK; RECT rc; GetClientRect( g_hWnd, &rc); UINT width = rc.right - rc.left; UINT height = rc.bottom - rc.top; UINT createDeviceFlags = 0; #ifdef _DEBUG createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_DRIVER_TYPE driverTypes[] = { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, D3D_DRIVER_TYPE_REFERENCE, }; UINT numDriverTypes = ARRAYSIZE( driverTypes); D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, }; UINT numFeatureLevels = ARRAYSIZE( featureLevels); DXGI_SWAP_CHAIN_DESC sd; ZeroMemory( &sd, sizeof( sd)); sd.BufferCount = 1; sd.BufferDesc.Width = width; sd.BufferDesc.Height = height; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.OutputWindow = g_hWnd; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; for ( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++) { g_driverType = driverTypes[driverTypeIndex]; hr = D3D11CreateDeviceAndSwapChain( NULL, g_driverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext); if ( SUCCEEDED( hr)) break; } if ( FAILED( hr)) return hr; // Create a render target view ID3D11Texture2D* pBackBuffer = NULL; hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D), ( LPVOID*)&pBackBuffer); if ( FAILED( hr)) return hr; hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView); pBackBuffer->Release( ); if ( FAILED( hr)) return hr; g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, NULL); // Compile the vertex shader ID3DBlob* pVSBlob = NULL; hr = CompileShaderFromFile( L"Tutorial02.fx", "VS", "vs_4_0", &pVSBlob); if ( FAILED( hr)) { MessageBox( NULL, L"The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", L"Error", MB_OK); return hr; } // Create the vertex shader hr = g_pd3dDevice->CreateVertexShader( pVSBlob->GetBufferPointer( ), pVSBlob->GetBufferSize( ), NULL, &g_pVertexShader); if ( FAILED( hr)) { pVSBlob->Release( ); return hr; } // Define the input layout D3D11_INPUT_ELEMENT_DESC layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; UINT numElements = ARRAYSIZE( layout); // Create the input layout hr = g_pd3dDevice->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer( ), pVSBlob->GetBufferSize( ), &g_pVertexLayout); pVSBlob->Release( ); if ( FAILED( hr)) return hr; // Set the input layout g_pImmediateContext->IASetInputLayout( g_pVertexLayout); // Compile the pixel shader ID3DBlob* pPSBlob = NULL; hr = CompileShaderFromFile( L"Tutorial02.fx", "PS", "ps_4_0", &pPSBlob); if ( FAILED( hr)) { MessageBox( NULL, L"The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", L"Error", MB_OK); return hr; } // Create the pixel shader hr = g_pd3dDevice->CreatePixelShader( pPSBlob->GetBufferPointer( ), pPSBlob->GetBufferSize( ), NULL, &g_pPixelShader); pPSBlob->Release( ); if ( FAILED( hr)) return hr; // Create vertex buffer SimpleVertex vertices[] = { XMFLOAT3( 0.0f, 0.5f, 0.5f), XMFLOAT3( 0.5f, -0.5f, 0.5f), XMFLOAT3( -0.5f, -0.5f, 0.5f), }; D3D11_BUFFER_DESC bd; ZeroMemory( &bd, sizeof( bd)); bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof( SimpleVertex) * 3; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; bd.CPUAccessFlags = 0; D3D11_SUBRESOURCE_DATA InitData; ZeroMemory( &InitData, sizeof( InitData)); InitData.pSysMem = vertices; hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer); if ( FAILED( hr)) return hr; // Set vertex buffer UINT stride = sizeof( SimpleVertex); UINT offset = 0; g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset); // Setup the viewport D3D11_VIEWPORT vp; vp.Width = ( FLOAT)width; vp.Height = ( FLOAT)height; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; vp.TopLeftX = 0; vp.TopLeftY = 0; g_pImmediateContext->RSSetViewports( 1, &vp); // Set primitive topology g_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); return S_OK; }
//-------------------------------------------------------------------------------------- // Render a frame //-------------------------------------------------------------------------------------- void Render() { // Clear the back buffer float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f }; // red,green,blue,alpha g_pImmediateContext->ClearRenderTargetView( g_pRenderTargetView, ClearColor); // Render a triangle g_pImmediateContext->VSSetShader( g_pVertexShader, NULL, 0); g_pImmediateContext->PSSetShader( g_pPixelShader, NULL, 0); g_pImmediateContext->Draw( 3, 0); // Present the information rendered to the back buffer to the front buffer (the screen) g_pSwapChain->Present( 0, 0); }
//-------------------------------------------------------------------------------------- // Vertex Shader //-------------------------------------------------------------------------------------- float4 VS(float4 Pos : POSITION ) : SV_POSITION { return Pos; } //-------------------------------------------------------------------------------------- // Pixel Shader //-------------------------------------------------------------------------------------- float4 PS( float4 Pos : SV_POSITION ) : SV_Target { return float4( 0.5f, 1.0f, 0.5f, 1.0f ); // Yellow, with Alpha = 1 }
Как динамически изменить цвет треугольника, н-р по нажатию мыши?
Читай про constant buffer.
Спасибо.
Можно изменить Layout, добавить в него ещё один параметр, например , COLOUR. И перед отрисовкой, когда нужно изменить цвет объекта или вертекса, менять COLOUR и обновлять буфер.
D3D11_INPUT_ELEMENT_DESC layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR" , 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 } };
а можно и отделить буферы: позицию вертексов от цвета и обновлять только буфер цвета.
D3D11_INPUT_ELEMENT_DESC layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR" , 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 0, D3D11_INPUT_PER_VERTEX_DATA, 1 } };
Спасибо bykabak, так возможно даже проще. Буду изучать оба ответа.
Скоро эти ваши гэйпи станут на столько сложными, что появится отдельная профессия "Умеющий в гэйпи"...
А ведь еще каких-то 10 лет назад для "нарисовать треугольник с динамически изменяемым цветом" достаточно было наговнять с десяток строк кода на убогом йэпи.
celsius
> если я правильно понял, примитивы рисуются шейдерами,
Ну и что? Передавай в шейдер все что угодно и будет тебе счастье. Что может быть проще щейдера?
san
>Что может быть проще щейдера?
ffp.
Знания хорошо усваиваются, когда API развивается параллельно с тобой в одно время и ты видишь как от immediate mode уходят к шейдерному конвейеру, а потом вообще к вулкану. А ретроспективно изучать всегда тяжело.
школьники, которые не осилили управление очередями через семафоры (или фенсы ) :)
innuendo
Там же все просто. Ну это занудно пипец. А так взял DX11 и не паришься вообще ни о чем
innuendo
Ну ты то шишек набил на этом говне, а каково молодым специалистам, изучать все это говно с нуля?
nes
> а каково молодым специалистам, изучать все это говно с нуля?
ничего не знаю - уже в школе нужно знать как работает современно апи :)
innuendo
школьники деньги переводят, им некада
g-cont
Пытаются умножить на 0.33
Тема в архиве.