簡體   English   中英

C ++ OpenGL網格渲染

[英]C++ OpenGL mesh rendering

我知道互聯網上有很多這方面的資源,但它們似乎並沒有幫助我。

我想要實現的目標:
我正在從數據中烘焙網格,該數據將頂點存儲在vector<Vector3>
Vector3sctruct方含float x, y, z
它將三角形存儲在map<int, vector<int>>
(地圖的關鍵是子網格, vector<int>是三角形)
vector<Vector2>的紫外線
Vector2是一個包含float x, ystruct
vector<Color>的顏色值
(顏色值適用於像uv那樣的頂點)

現在我想編寫一個代碼,可以讀取該數據並以最大的性能將其繪制到屏幕上

我得到了什么:

static void renderMesh(Mesh mesh, float x, float y, float z) {
    if (mesh.triangles.empty()) return;
    if (mesh.vertices.empty()) return;
    if (mesh.uvs.empty()) return;
    glColor3f(1, 1, 1);
    typedef std::map<int, std::vector<int>>::iterator it_type;
    for (it_type iterator = mesh.triangles.begin(); iterator != mesh.triangles.end(); iterator++) {
        int submesh = iterator->first;
        if (submesh < mesh.textures.size()) glBindTexture(GL_TEXTURE_2D, mesh.textures[submesh].id);
        else glBindTexture(GL_TEXTURE_2D, 0);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        for (int i = 0; i < iterator->second.size(); i += 3) {
            int t0 = iterator->second[i + 0];
            int t1 = iterator->second[i + 1];
            int t2 = iterator->second[i + 2];
            Vector3 v0 = mesh.vertices[t0];
            Vector3 v1 = mesh.vertices[t1];
            Vector3 v2 = mesh.vertices[t2];
            Color c0 = mesh.vertexColors[t0];
            Color c1 = mesh.vertexColors[t1];
            Color c2 = mesh.vertexColors[t2];
            Vector2 u0 = mesh.uvs[t0];
            Vector2 u1 = mesh.uvs[t1];
            Vector2 u2 = mesh.uvs[t2];
            glBegin(GL_TRIANGLES);
            glColor4f(c0.r / 255.0f, c0.g / 255.0f, c0.b / 255.0f, c0.a / 255.0f); glTexCoord2d(u0.x, u0.y); glVertex3f(v0.x + x, v0.y + y, v0.z + z);
            glColor4f(c1.r / 255.0f, c1.g / 255.0f, c1.b / 255.0f, c1.a / 255.0f); glTexCoord2d(u1.x, u1.y); glVertex3f(v1.x + x, v1.y + y, v1.z + z);
            glColor4f(c2.r / 255.0f, c2.g / 255.0f, c2.b / 255.0f, c2.a / 255.0f); glTexCoord2d(u2.x, u2.y); glVertex3f(v2.x + x, v2.y + y, v2.z + z);
            glEnd();
            glColor3f(1, 1, 1);
        }
    }
}

問題:
我發現我渲染的方式不是最好的方法,你可以使用glDrawArrays獲得更高的性能(我認為它被稱為)。
你能幫我改寫我的代碼以適應glDrawArrays,因為我到目前為止在互聯網上找到的東西並沒有太多幫助我。

謝謝,如果還有更多信息需要請問。

不推薦使用glBeginglEnd等函數。 glDrawArrays這樣的函數具有更好的性能,但使用起來稍微復雜一些。

glBegin渲染技術的問題是,每次想要繪制某些東西時,你必須逐個傳遞每個頂點。 今天,圖形卡能夠非常快速地渲染數千個頂點,但是如果你逐一渲染它,無論你的顯卡性能如何,渲染都會變得遲鈍。

glDrawArrays的主要優點是你必須初始化一次數組,然后用一次調用繪制它。 首先,您需要在程序的開頭填充每個屬性的數組。 在你的情況下:位置,顏色和紋理坐標。 它必須是float數組,如下所示:

std::vector<float> vertices;
std::vector<float> colors;
std::vector<float> textureCoords;

for (int i = 0; i < iterator->second.size(); i += 3) {
    int t0 = iterator->second[i + 0];
    int t1 = iterator->second[i + 1];
    int t2 = iterator->second[i + 2];
    vertices.push_back(mesh.vertices[t0].x);
    vertices.push_back(mesh.vertices[t0].y);
    vertices.push_back(mesh.vertices[t0].z);
    vertices.push_back(mesh.vertices[t1].x);
    vertices.push_back(mesh.vertices[t1].y);
    vertices.push_back(mesh.vertices[t1].z);
    vertices.push_back(mesh.vertices[t2].x);
    vertices.push_back(mesh.vertices[t2].y);
    vertices.push_back(mesh.vertices[t2].z);

    // [...] Same for colors and texture coords.
}

然后,在另一個僅用於顯示的函數集中,您可以使用這些數組來繪制它:

// Enable everything you need
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

// Set your used arrays
glVertexPointer(3, GL_FLOAT, 0, vertices.data());
glColorPointer(4, GL_FLOAT, 0, colors.data());
glTexCoordPointer(2, GL_FLOAT, 0, textureCoords.data());

// Draw your mesh
glDrawArrays(GL_TRIANGLES, 0, size); // 'size' is the number of your vertices.

// Reset initial state
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);

當然,您必須啟用要使用的其他屬性,例如紋理或混合。


注意:

如果您想了解性能,還有其他函數使用索引來減少使用的數據大小,如glDrawElements

還有其他更先進的OpenGL技術,通過將數據直接保存在圖形卡內存(如Vertex Buffer Objects)上,可以提高性能。

暫無
暫無

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

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