2009-06-29 5 views

Répondre

1

Vous devrez le faire via le chargement de l'objet. Vous ne pouvez pas appeler des primitives de forme 3D à l'aide d'Open GL ES. Regardez le blog de Jeff Lamarche, il y a beaucoup de très bonnes ressources sur la façon d'y charger des objets. link text

+0

Merci pour la réponse. Cependant, on m'a dit que vous pourriez dessiner un cylindre dans OpenGLES en utilisant simplement des 'quads'. Et je voudrais éviter d'utiliser un logiciel de modélisation 3D à ce stade. Quelqu'un pourrait-il donner une réponse plus précise? – RexOnRoids

+0

Les sous-systèmes OpenGL ES ne sont pas disponibles en quad, car ils ont été retirés pour alléger le paquet. La méthode programmatique la plus simple pour dessiner des cylindres est d'utiliser GLUT mais cela n'est pas disponible pour OpenGL ES. –

+0

J'ai fini par télécharger blender et installer le script d'exportation Objective-C de quelqu'un pour créer/exporter un modèle 3D dans un projet OpenGL iPhone SDK. Ça a pris un peu de temps mais une fois que tout était en place ça a bien fonctionné. Je suis content que je n'ai pas essayé d'écrire manuellement une routine dans Xcode pour manipuler les cylindres pour le modèle 3D puisque le modèle 3D finit par avoir environ 500 sommets et environ 700 faces LOL. Merci – RexOnRoids

1

Vous pouvez en effet dessiner un cylindre dans OpenGL ES en calculant la géométrie de l'objet. Le projet open source GLUT|ES comporte des routines de dessin de géométrie pour les solides (cylindres, sphères, etc.) dans son fichier source glutes_geometry.c. Malheureusement, ces fonctions utilisent les appels glBegin() et glEnd(), qui ne sont pas présents dans OpenGL ES.

Le code d'une implémentation de vérin partiel pour OpenGL ES se trouve dans le fil de discussion here.

3

La première étape consiste à écrire un sous-programme qui dessine un triangle. Je vais laisser ça à vous. Ensuite, dessinez simplement une série de triangles qui forment la forme d'un cylindre. L'astuce consiste à approximer un cercle avec un polygone avec un grand nombre de côtés comme 64. Voici un pseudo-code au sommet de ma tête.

for (i = 0; i < 64; i++) 
{ 
    angle = 360 * i/63; // Or perhaps 2 * PI * i/63 
    cx[i] = sin(angle); 
    cy[i] = cos(angle); 
} 

for (i = 0; i < 63; i++) 
{ 
    v0 = Vertex(cx[i], cy[i], 0); 
    v1 = Vertex(cx[i + 1], cy[i + 1], 0); 
    v2 = Vertex(cx[i], cy[i], 1); 
    v3 = Vertex(cx[i + 1], cy[i + 1], 1); 

    DrawTriangle(v0, v1, v2); 
    DrawTriangle(v1, v3, v2); 
    // If you have it: DrawQuad(v0, v1, v3, v2); 
} 

Il y a presque certainement une erreur dans le code. Le plus probable est que j'ai foiré l'ordre sinueux dans le triangle dessine de sorte que vous pourriez vous retrouver avec seulement la moitié des triangles apparemment visibles ou un cas très étrange avec seulement le dos visible. La performance voudra bientôt que vous dessinez des bandes triangulaires et des ventilateurs pour l'efficacité, mais ceci devrait vous aider à démarrer.

0

Vous pouvez dessiner un cylindre de manière procédurale en calculant la géométrie. En plus de cela, vous devez faire en sorte qu'il supporte triangle stripping et vous devez également calculer les coordonnées de cartographie et éventuellement les normales. Donc, il faudra un peu de réflexion à faire à partir de zéro.

J'ai créé un module pour Unity3D en C# qui fait exactement cela et vous permet de modifier les paramètres. Vous devriez être capable de convertir facilement en C ou C++ car le calcul de la géométrie est le même partout. Regardez le video pour voir de quoi il s'agit et téléchargez le code de GitHub.

1

J'espère que cela peut vous aider, voici ma mise en œuvre d'un cylindre dans OpenGLES 2.0 pour Android

import java.nio.ByteBuffer; 
import java.nio.ByteOrder; 
import java.nio.FloatBuffer; 

import javax.microedition.khronos.opengles.GL10; 

public class Cylinder { 

    public Cylinder(int n) { 

     this.numOfVertex = n; 

     float[] vertex = new float[3 * (n + 1) * 2]; 
     byte[] baseIndex = new byte[n]; 
     byte[] topIndex = new byte[n]; 
     byte[] edgeIndex = new byte[n*2 + 2]; 

     double perAngle = 2 * Math.PI/n; 

     for (int i = 0; i < n; i++) { 
      double angle = i * perAngle; 
      int offset = 6 * i; 

      vertex[offset + 0] = (float)(Math.cos(angle) * radious) + cx; 
      vertex[offset + 1] = -height; 
      vertex[offset + 2] = (float)(Math.sin(angle) * radious) + cy; 

      vertex[offset + 3] = (float)(Math.cos(angle) * radious) + cx; 
      vertex[offset + 4] = height; 
      vertex[offset + 5] = (float)(Math.sin(angle) * radious) + cy; 

      topIndex[i] = (byte)(2*i); 

      baseIndex[i] = (byte)(2*i +1); 

      edgeIndex[2*i + 1] = baseIndex[i]; 
      edgeIndex[2*i] = topIndex[i]; 

     } 


     edgeIndex[2*n] = topIndex[0]; 
     edgeIndex[2*n+1] = baseIndex[0]; 

     ByteBuffer vbb = ByteBuffer 
       .allocateDirect(vertex.length * 4) 
       .order(ByteOrder.nativeOrder()); 

     mFVertexBuffer = vbb.asFloatBuffer(); 
     mFVertexBuffer.put(vertex); 
     mFVertexBuffer.position(0); 

     normalBuffer = mFVertexBuffer; 

     mCircleBottom = ByteBuffer.allocateDirect(baseIndex.length); 
     mCircleBottom.put(baseIndex); 
     mCircleBottom.position(0); 

     mCircleTop = ByteBuffer.allocateDirect(topIndex.length); 
     mCircleTop.put(topIndex); 
     mCircleTop.position(0); 

     mEdge = ByteBuffer.allocateDirect(edgeIndex.length); 
     mEdge.put(edgeIndex); 
     mEdge.position(0); 
    } 

    public void draw(GL10 gl) 
    { 
     gl.glCullFace(GL10.GL_BACK); 
     gl.glEnable(GL10.GL_CULL_FACE); 
     gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mFVertexBuffer); 
     gl.glNormalPointer(GL10.GL_FLOAT, 0, normalBuffer); 
     gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 

     gl.glPushMatrix(); 

     gl.glColor4f(1f, 0, 0, 0); 
     gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, numOfVertex * 2 + 2, GL10.GL_UNSIGNED_BYTE, mEdge); 
     gl.glPopMatrix(); 
     gl.glPushMatrix(); 

     gl.glColor4f(0.9f, 0, 0, 0); 
     gl.glDrawElements(GL10.GL_TRIANGLE_FAN, numOfVertex, GL10.GL_UNSIGNED_BYTE, mCircleTop); 
     gl.glPopMatrix(); 

     gl.glPushMatrix(); 

     gl.glTranslatef(0, 2*height, 0); 
     gl.glRotatef(-180, 1, 0, 0); 

     gl.glColor4f(0.9f,0, 0, 0); 
     gl.glDrawElements(GL10.GL_TRIANGLE_FAN, numOfVertex , GL10.GL_UNSIGNED_BYTE, mCircleBottom); 
     gl.glPopMatrix(); 

    } 

    private FloatBuffer mFVertexBuffer; 
    private FloatBuffer normalBuffer; 
    private ByteBuffer mCircleBottom; 
    private ByteBuffer mCircleTop; 
    private ByteBuffer mEdge; 
    private int numOfVertex; 
    private int cx = 0; 
    private int cy = 0; 
    private int height = 1; 
    private float radious = 1; 
}