OpenGL: Wie zeichne ich einen Tunnel richtig?
-
littletux schrieb:
Wie würde dies mit glDrawElements aussehen?
Google: glDrawElements example erster Eintrag...
-
Ich habe probiert mit glDrawElements zu arbeiten, aber irgendwie sehe ich nichts am Bildschirm. Habe ich was übersehen? Hier ist mein neuer Code:
void srOpenGL::DrawTube(unsigned border, float radius, float width) { //////////////////////////////////////////////////////////////////////////////// /// Ein Rohr zeichnen //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// unsigned int array = border*12, size = border*18; GLfloat end, length, start; GLfloat angle[2], posX[2], posY[2], posZ[2], textures[array], vertices[size]; GLubyte indices[size]; glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); for(unsigned int c = 0; c<size; c++) { indices[c] = static_cast<GLubyte>(c); } length = 1.0f/static_cast<GLfloat>(border); width/=2; posY[0] = width; posY[1] = -width; for(unsigned int c = 1, i = 0, j = 0; c<=border; c++, i+=18, j+=12) { angle[0] = (c-1)*2*M_PI/border; angle[1] = c*2*M_PI/border; start = c*length; end = (c+1)*length; posX[0] = radius*std::cos(angle[0]); posX[1] = radius*std::cos(angle[1]); posZ[0] = radius*std::sin(angle[0]); posZ[1] = radius*std::sin(angle[1]); textures[j] = start; textures[(j+1)] = 0.0f; textures[(j+2)] = start; textures[(j+3)] = 1.0f; textures[(j+4)] = end; textures[(j+5)] = 0.0f; textures[(j+6)] = start; textures[(j+7)] = 1.0f; textures[(j+8)] = end; textures[(j+9)] = 1.0f; textures[(j+10)] = end; textures[(j+11)] = 0.0f; vertices[i] = posX[0]; vertices[(i+1)] = posY[0]; vertices[(i+2)] = posZ[0]; vertices[(i+3)] = posX[0]; vertices[(i+4)] = posY[1]; vertices[(i+5)] = posZ[0]; vertices[(i+6)] = posX[1]; vertices[(i+7)] = posY[0]; vertices[(i+8)] = posZ[1]; vertices[(i+9)] = posX[0]; vertices[(i+10)] = posY[1]; vertices[(i+11)] = posZ[0]; vertices[(i+12)] = posX[1]; vertices[(i+13)] = posY[1]; vertices[(i+14)] = posZ[1]; vertices[(i+15)] = posX[1]; vertices[(i+16)] = posY[0]; vertices[(i+17)] = posZ[1]; } glTexCoordPointer(3, GL_FLOAT, sizeof(textures)/sizeof(GLfloat), textures); glVertexPointer(3, GL_FLOAT, sizeof(vertices)/sizeof(GLfloat), vertices); glPushMatrix(); glDrawElements(GL_TRIANGLES, sizeof(indices)/sizeof(GLubyte), GL_UNSIGNED_BYTE, indices); glPopMatrix(); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); //////////////////////////////////////// }
-
Deine Berechnungen mit
sizeof
sollten immer 1 liefern. (sizeof(textures)/sizeof(GLfloat))
-
Ich habe vergessen, meine Funktion aufzurufen. Jetzt kann ich was sehen. Meine Funktion zeichnet zwar ein Rohr aber irgendwie schaut von der seite eine große weiße Fläche raus und die Texturen werden auch nicht richtig angezeigt wie es vorher mit glTexCoord2f war. Woran liegt es?
-
Ich habe folgendes geändert:
glTexCoordPointer(2, GL_FLOAT, 0, &textures[0]); glVertexPointer(3, GL_FLOAT, 0, &vertices[0]);
Die Texturen werden zwar richtig dargestellt, aber irgendwie schauen aus der Seite des Rohrs lauter kleine senkrecht aufgestapelte Dreiecke raus. Ich weiß nicht warum, da dies eigentlich die selben Koordinaten sind wie in meine vorherigen Variante ohne glDrawElements.
-
Jetzt wird das Objekt richtig dargestellt! Der Fehler lag bei der Arraygröße. Es darf nicht maximal sein und muss wegen glVertex3f durch 3 geteit werden. Aber nun gibt es Probleme mit meine Textur, die nicht richtig auf die Oberfläche liegt. Kann mir bitte jemand weiter helfen?
const GLuint srOpenGL::CreateTube(unsigned int border, float radius, float width) { //////////////////////////////////////////////////////////////////////////////// /// Ein Rohr erstellen //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// float end, length, start; float angle[2], posX[2], posY[2], posZ[2]; GLfloat textures[(border*12)], vertices[(border*18)]; length = 1.0f/static_cast<float>(border); width/=2; posY[0] = width; posY[1] = -width; GLuint tube = glGenLists(1); for(unsigned int c=1, i=0, j=0; c<=border; c++, i+=12, j+=18) { angle[0] = (c-1)*2*M_PI/border; angle[1] = c*2*M_PI/border; start = c*length; end = (c+1)*length; posX[0] = radius*std::cos(angle[0]); posX[1] = radius*std::cos(angle[1]); posZ[0] = radius*std::sin(angle[0]); posZ[1] = radius*std::sin(angle[1]); textures[i] = start; textures[(i+1)] = 0.0f; textures[(i+2)] = start; textures[(i+3)] = 1.0f; textures[(i+4)] = end; textures[(i+5)] = 0.0f; textures[(i+6)] = start; textures[(i+7)] = 1.0f; textures[(i+8)] = end; textures[(i+9)] = 1.0f; textures[(+10)] = end; textures[(i+11)] = 0.0f; vertices[j] = posX[0]; vertices[(j+1)] = posY[0]; vertices[(j+2)] = posZ[0]; vertices[(j+3)] = posX[0]; vertices[(j+4)] = posY[1]; vertices[(j+5)] = posZ[0]; vertices[(j+6)] = posX[1]; vertices[(j+7)] = posY[0]; vertices[(j+8)] = posZ[1]; vertices[(j+9)] = posX[0]; vertices[(j+10)] = posY[1]; vertices[(j+11)] = posZ[0]; vertices[(j+12)] = posX[1]; vertices[(j+13)] = posY[1]; vertices[(j+14)] = posZ[1]; vertices[(j+15)] = posX[1]; vertices[(j+16)] = posY[0]; vertices[(j+17)] = posZ[1]; } glNewList(tube, GL_COMPILE); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); glTexCoordPointer(2, GL_FLOAT, 0, textures); glVertexPointer(3, GL_FLOAT, 0, vertices); glPushMatrix(); glDrawArrays(GL_TRIANGLES, 0, (6*border)); glPopMatrix(); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glEndList(); return tube; //////////////////////////////////////// }
-
vielleicht bekommst du mehr antworten wenn die leute rausfinden wovon du immer sprichst, "nicht richtig" ist so waaaage ;).
mach ein screenshot und poste den link dazu (gibt ja genug free image hoster).
-
Wenn man sich nur ein Viereck (bestehend aus zwei Dreiecken) vom Mantel eines Zylinders vorstellt, so sieht es wie folgt aus:
1---3 _ 6
|.../ __ /|
|../ __ /.|
|./ __ /..|
2 _ 4---5Wenn man die Variable start mit 0.0f und end mit 1.0f setzt, so wird die Textur im Dreieck (1-2-3) richtig Dargestellt, aber im Dreieck (4-5-6) wird die Textur schreck dargestellt.
Also er zeichnet die Punktspalte von 6 in X-Richtung und die Punktzeile von Punkt 6 zu Punkt 4. Mit anderen Worten ist die Textur des zweiten Dreiecks um 45° geneigt.
-
Mir ist gerade aufgefallen, wenn ich ein Rohr zeichne (also den Mantel vom Zylinder), wird nur auf ein Viereck die Textur richtig dargestellt. Ich vermute mal, dass es der erste ist. Bei den anderen Vierecken sieht es wie oben beschrieben aus. Hat es etwas mit glTexCoordPointer(2, GL_FLOAT, 0, textures) zu tun? Ich Frage nur, weil der erste Parameter eine 2 ist und bei den anderen Funktionen glVertexPointer(3, GL_FLOAT, 0, vertices) eine 3 ist.
-
Der erste Parameter von gl*Pointer gibt an wieviel Komponenten das Vertexattribut hat.
-
Ich habe den Fehler schon gefunden:
textures[(+10)] = end;
Es hat die Variable i gefählt. Jetzt klappt alles wunderbar!