簡體   English   中英

DirectX9 C ++實時為頂點數據重新着色

[英]DirectX9 C++ Recoloring Vertex data in real time

我是DirectX的新手,並且開始了解API的功能。

我設法使用以下函數正確顯示和渲染了三角形:

初始化頂點:

void Menu::InitializeMenu(float x, float y, float width, float height, D3DCOLOR color,    IDirect3DDevice9* d3dDevice)
{
CUSTOMVERTEX vertices[] =
{
    { x, y, 0.5f, 1.0f, color },
    { x + width, y, 0.5f, 1.0f, color },
    { x + width, y + height, 0.5f, 1.0f, color },

    { x, y, 0.5f, 1.0f, color },
    { x , y + height, 0.5f, 1.0f, color },
    { x + width, y + height, 0.5f, 1.0f, color },
};

if (FAILED(d3dDevice->CreateVertexBuffer(6 * sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &m_vertexBuffer, NULL)))
    return;

void *locked_buffer;
if (FAILED(m_vertexBuffer->Lock(0, sizeof(vertices), (void **)&locked_buffer, 0)))
    return;



memcpy(locked_buffer, vertices, sizeof(vertices));
m_vertexBuffer->Unlock();
}

這里的所有內容都在Menu類中定義。

畫畫:

void Menu::RenderMenu(IDirect3DDevice9 *d3dDevice)
{
d3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
d3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
d3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
d3dDevice->SetRenderState(D3DRS_SRCBLENDALPHA, D3DRS_DESTBLENDALPHA);
d3dDevice->SetStreamSource(0, m_vertexBuffer, 0, sizeof(CUSTOMVERTEX));
d3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
d3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
}

一切正常,我渲染了兩個三角形,這又生成了一個半透明的四邊形。

現在的問題是:我希望能夠在程序開始渲染后更改三角形中頂點的顏色(所有內容都已初始化,並且至少渲染過一次)。

我考慮過的事情:-我考慮過使用不同的參數調用InitializeMenu函數以用不同的顏色重新初始化頂點,原因是我沒有這樣做是因為它看起來效率很低而且不切實際。

-材料:我還沒有實現材料,這是因為我還不知道如何做,並且因為我希望找到一個更簡單的選擇。 我需要的只是頂點顏色。 如果材料是完成此任務的唯一方法,我將執行。

-着色器:我知道您可以使用着色器為頂點着色,但是我幾乎沒有着色器經驗,並且正如我之前所言,我寧願找到一個更簡單的替代方法。 是的,我知道着色器很簡單,我已經可以實時更改着色器中頂點的顏色。 它使用的是GLSL,但我敢肯定它的差別不會太大。 當我要添加多個四邊形(每個四邊形的2個三角形的集合)時,問題就來了。 我只知道如何更改進入頂點着色器的所有頂點的顏色。 和以前一樣,如果着色器是唯一的實現方法,我將實現。 請給我指出正確的方向。 我對着色器在低層的工作方式了解得很少(我了解着色器的概念和流程,只是不知道如何利用着色器才能有效地使用它)。

研究:我到處都看過了,也許我沒問正確的問題,但是我找不到任何答案。

這實際上是我第一次發布問題,通常有人已經問過我問題。 我試圖盡我最大的努力來解釋我的問題,但是如果仍然不清楚,請隨時請求更多代碼或信息。

PS:我正在使用Windows 8桌面,不確定是否真的很重要。

要更新頂點,您將需要執行與InitializeMenu類似的操作,但無需再次調用CreateVertexBuffer。 您還需要對創建頂點緩沖區的方式進行一些修改。

頂點緩沖區有兩種類型:靜態和動態。 靜態頂點緩沖區不允許CPU進行更改,而動態頂點緩沖區則允許。

要創建動態頂點緩沖區,請將D3DU​​SAGE_DYNAMIC添加到CreateVertexBuffer:

d3dDevice->CreateVertexBuffer(6 * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &m_vertexBuffer, NULL)

然后,您可以創建一個新的函數來更改顏色:

void Menu::ChangeColor(D3DColor color) {
    CUSTOMVERTEX *locked_buffer;
    if (FAILED(m_vertexBuffer->Lock(0, 0, (void **)&locked_buffer, 0))) {
        return;
    }

    for (int i=0; i<6; i++) {
        // use whatever you called color in your CUSTOMVERTEX struct
        locked_buffer[i].color = color;
    }
    m_vertexBuffer->Unlock();
}

該代碼本質上是從GPU獲取頂點數據,並允許您在CPU上對其進行更新。 您不需要重新創建頂點緩沖區,只需更新所需的值即可。

您可以定義一個隨機函數,然后將綠色,藍色,黃色,紅色,紫色等顏色元素添加到數組中。 然后,您可以調用random函數來隨機選擇數組中的顏色。

像這樣:

int arr [15] = {10,210,140,180,250,189,183,107,183,107,60,2,55,85,48};

D3DCOLOR color1; D3DCOLOR color2; D3DCOLOR color3; D3DCOLOR color4;

srand(time(NULL));
CUSTOMVERTEX vertices[] =
{{ x, y, 0.5f, 1.0f, color = D3DCOLOR_XRGB(arr[rand() % 14 + 0], arr[rand() % 14 + 0], arr[rand() % 14 + 0])},
{ x + width, y, 0.5f, 1.0f, color = D3DCOLOR_XRGB(arr[rand() % 14 + 0], arr[rand() % 14 + 0], arr[rand() % 14 + 0])},
{ x + width, y + height, 0.5f, 1.0f, color = D3DCOLOR_XRGB(arr[rand() % 14 + 0], arr[rand() % 14 + 0], arr[rand() % 14 + 0])},

{ x, y, 0.5f, 1.0f, color = D3DCOLOR_XRGB(arr[rand() % 14 + 0], arr[rand() % 14 + 0], arr[rand() % 14 + 0])},
{ x , y + height, 0.5f, 1.0f, color = D3DCOLOR_XRGB(arr[rand() % 14 + 0], arr[rand() % 14 + 0], arr[rand() % 14 + 0])},
{ x + width, y + height, 0.5f, 1.0f, color = D3DCOLOR_XRGB(arr[rand() % 14 + 0], arr[rand() % 14 + 0], arr[rand() % 14 + 0])},
};

一件事,您可能必須使用不同的D3DCOLOR顏色變量,即; color1,color2,color3等,以避免取消引用和覆蓋值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM