Elements
-
Naja, meine Lösung würde wohl so aussehen:
{ const int num_vertices = xres * yres; const float du = 1.0f / xres; const float dv = 1.0f / yres; float v = 0.0f; for (int j = 0; j < xres; ++j, v += dv) { float u = 0.0f; for (int i = 0; i < yres; ++i, u += du;) { vertices[j * xres + i].x = u * xscale + xoffset; vertices[j * xres + i].y = v * yscale + yoffset; } } const int num_quads = (xres - 1) * (yres - 1); const int num_indices = num_quads * 6; int index = 0; for (int j = 0; j < yres - 1; ++j) for (int i = 0; i < xres - 1; ++i) { indices[index++] = j * xres + i; indices[index++] = (j + 1) * xres + i; indices[index++] = j * xres + i + 1; indices[index++] = (j + 1) * xres + i; indices[index++] = (j + 1) * xres + i + 1; indices[index++] = j * xres + i + 1; } }
Find ich jetzt nicht nur um einiges lesbarer, sondern ist wohl auch flexibler.
-
Du ich date das Netz in Echtzeit auf einer solar rechenanlage ab,
keine Zeit die vertice menge zweimal durchlaufen zu müssen.
-
Um ok. Ka was für eine CPU du da hast und wie gut der Compiler ist, aber bist du dir sicher, dass diese ganzen Branches in der inner Loop tatsächlich besser sind als getrennte Schleifen!? Die Indexberechnung lässt sich außerdem problemlos mit den Vertices in die selbe Schleife packen, es braucht dazu nur ein einziges if:
{ const int num_vertices = xres * yres; const int num_quads = (xres - 1) * (yres - 1); const int num_indices = num_quads * 6; const float du = 1.0f / xres; const float dv = 1.0f / yres; int index = 0; float v = 0.0f; for (int j = 0; j < xres; ++j, v += dv) { float u = 0.0f; for (int i = 0; i < yres; ++i, u += du;) { vertices[j * xres + i].x = u * xscale + xoffset; vertices[j * xres + i].y = v * yscale + yoffset; if (j < (yres - 1) && i < (xres - 1)) { indices[index++] = j * xres + i; indices[index++] = (j + 1) * xres + i; indices[index++] = j * xres + i + 1; indices[index++] = (j + 1) * xres + i; indices[index++] = (j + 1) * xres + i + 1; indices[index++] = j * xres + i + 1; } } } }
Man könnte da oben außerdem praktisch alle Multiplikationen durch inkrementelle Additionen ersetzen.
-
naja im moment zieht diese loop , ich bin dabei diese zu optimieren,
wird noch dauern.. aber danke für deine Hinweise, das untere liefert
gerade zügige Ergebnise,und richtig die muls kommen weg
DWORD CTerrain::MakeTriangle(void) { register DWORD nIdx(0),nId(0); for(register WORD nY(m_stp),x,y; nY < m_height-m_stp; nY += m_stp ) for(register WORD nX(0); nX < m_width-m_stp; nX += m_stp ) for(register WORD n(0),p1(0),p2(0); n < 6; n++ )//1 quad = 2 triangles = 6 edges and edge 3&5 exists twice { switch(n) { case 0:x=nX,y=nY,m_pIdx[nId] = nIdx;break; case 1:{ y=nY,x=nX+m_stp,m_pIdx[nId] = nIdx; register DWORD id(((((DWORD)m_width*(y-1))+x)*6)/(m_stp*m_stp)); m_pIdx[nId]=m_pIdx[id]?m_pIdx[id]:nIdx; } break; case 2:x=nX+m_stp,y=nY+m_stp,m_pIdx[nId]=nIdx; break; case 3:x=nX,y=nY,m_pIdx[nId]=nIdx-3;break; case 4:{ x=nX,y=nY+m_stp,m_pIdx[nId] = nIdx; register DWORD id(((((DWORD)m_width*(y-1))+x)*6)/(m_stp*m_stp)); m_pIdx[nId]=m_pIdx[id]?m_pIdx[id]:nIdx; }break; case 5:x=nX+m_stp,y=nY+m_stp,m_pIdx[nId] = nIdx-2;//this x,y is the same as nIdx break; }; if(m_pIdx[nId] == nIdx) { m_pVert[nIdx].x = x - (m_width>>1); m_pVert[nIdx].y = y - (m_height>>1); m_pVert[nIdx].z = GetHVal(x,y);//get z from highmap m_pTVert[nIdx].u = (float)x / m_width; m_pTVert[nIdx].v = (float)y / m_height; nIdx++;//next vertice } nId++; } DWORD vertice_ersparnis(m_idsz-nIdx); return nIdx; }
-
Außerdem ist der Vertice count gewinn bei deiner loop NULL
-
Man könnte die verschachtelte Schleife überhaupt loswerden und die Indexberechnung mit % und / anstellen. Wenn die Auflösung des Gitters eine Zweierpotenz ist, sollte der Compiler % und / über triviale Bitoperationen implementieren.
Karsten Schulz schrieb:
Außerdem ist der Vertice count gewinn bei deiner loop NULL
Was genau meinst du damit? Weniger als xres * yres Vertices geht doch gar nicht mehr!?
-
aber natürlich, viele der eckwerte im netz sind indetisch , und
können durch die indextabelle mehrmals indiziert werden, somit
spare ich im VBO massig daten. Ich hatte vorher ein TRIANGLE_STRIP
netz, leider bereitet die geometire dann mehr probs als nutzen.Daher nun der Umbau auf vertice -Elements klar der index buffer
enthält für jeden vertice einen index, aber die anzahl der vertices
im VBO ist wesentlich geringer als bei width*height
-
Karsten Schulz schrieb:
aber natürlich, viele der eckwerte im netz sind indetisch, und können durch die indextabelle mehrmals indiziert werden, [...]
Exakt. Und dann braucht man genau xres * yres Vertices, statt (xres - 1) * (yres - 1) * 6 ...
-
Sehr gut, ich verwende deine loop.
thx
-
Okay.. also nun hab ich das optimal , danke für deine Mithilfe
DWORD CTerrain::MakeTriangle(void) { register GLuint *pIdx(m_pIdx),Off; for(register WORD y = 0; y < m_height; y+=m_stp) for(register WORD x = 0; x < m_width; x+=m_stp) { Off = y * m_width + x; m_pTVert[Off].u = (float)x/m_width; m_pTVert[Off].v = (float)y/m_height; m_pVert[Off].y = y; m_pVert[Off].x = x; m_pVert[Off].z = GetHVal(x,y); if(y<m_height-1 && x<m_width-1) { *pIdx++ = Off; *pIdx++ = (y + 1) * m_width + x; *pIdx++ = Off + 1; *pIdx++ = (y + 1) * m_width + x; *pIdx++ = (y + 1) * m_width + x + 1; *pIdx++ = Off + 1; } } return m_width*m_height;//^^ }