ПрограммированиеФорумГрафика

Как динамически изменить цвет треугольника в directx11 из туториала?

Страницы: 1 2 3 Следующая »
#0
13:32, 10 мая 2019

Всем привет! Начал изучать 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
}

Как динамически изменить цвет треугольника, н-р по нажатию мыши?

#1
14:11, 10 мая 2019

Читай про constant buffer.

#2
14:18, 10 мая 2019

Спасибо.

#3
19:11, 10 мая 2019

Можно изменить 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 }
  };
#4
19:19, 10 мая 2019

Спасибо bykabak, так возможно даже проще. Буду изучать оба ответа.

#5
8:15, 11 мая 2019

Скоро эти ваши гэйпи станут на столько сложными, что появится отдельная профессия "Умеющий в гэйпи"...
А ведь еще каких-то 10 лет назад для "нарисовать треугольник с динамически изменяемым цветом" достаточно было наговнять с десяток строк кода на убогом йэпи.

#6
8:27, 11 мая 2019

celsius
> если я правильно понял, примитивы рисуются шейдерами,
Ну и что? Передавай в шейдер все что угодно и будет тебе счастье. Что может быть проще щейдера?

#7
8:35, 11 мая 2019

san
>Что может быть проще щейдера?
ffp.

#8
10:48, 11 мая 2019

Знания хорошо усваиваются, когда API развивается параллельно с тобой в одно время и ты видишь как от immediate mode уходят к шейдерному конвейеру, а потом вообще к вулкану. А ретроспективно изучать всегда тяжело.

#9
11:22, 11 мая 2019

школьники, которые не осилили управление очередями через семафоры (или фенсы ) :)

#10
11:47, 11 мая 2019

innuendo
Там же все просто. Ну это занудно пипец. А так взял DX11 и не паришься вообще ни о чем

#11
12:19, 11 мая 2019

innuendo
Ну ты то шишек набил на этом говне, а каково молодым специалистам, изучать все это говно с нуля?

#12
13:38, 11 мая 2019

nes
> а каково молодым специалистам, изучать все это говно с нуля?

ничего не знаю - уже в школе нужно знать как работает современно апи :)

#13
13:40, 11 мая 2019

innuendo
школьники деньги переводят, им некада

#14
14:22, 11 мая 2019

g-cont
Пытаются умножить на 0.33

Страницы: 1 2 3 Следующая »
ПрограммированиеФорумГрафика

Тема в архиве.