iphone - dibujo - como dibujar un cilindro paso a paso
¿Cómo se dibuja un cilindro con OpenGLES? (5)
¿Cómo se dibuja un cilindro con OpenGLES?
De hecho, puedes dibujar un cilindro en OpenGL ES calculando la geometría del objeto. El proyecto de código abierto GLUT | ES tiene rutinas de dibujo de geometría para sólidos (cilindros, esferas, etc.) dentro de su archivo fuente glutes_geometry.c. Desafortunadamente, estas funciones usan las llamadas glBegin () y glEnd (), que no están presentes en OpenGL ES.
El código para una implementación de cilindro parcialmente funcional para OpenGL ES se puede encontrar en el hilo del foro aquí .
El primer paso es escribir una subrutina que dibuje un triángulo. Te dejaré eso a ti. Entonces, simplemente dibuja una serie de triángulos para formar la forma de un cilindro. El truco es aproximar un círculo con un polígono con una gran cantidad de lados como 64. Aquí hay un pseudo-código fuera de mi cabeza.
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);
}
Es casi seguro que hay un error en el código. Lo más probable es que haya arruinado el orden de enrollamiento en el triángulo, por lo que podría terminar con la mitad de los triángulos aparentemente visibles o un caso muy extraño con solo la parte posterior visible.
El rendimiento pronto querrá que dibujes tiras triangulares y ventiladores para mayor eficiencia, pero esto debería ayudarte a comenzar.
Tendrás que hacerlo a través de la carga de objetos. No puede invocar primitivas de forma 3D con Open GL ES.
Mira a través del blog de Jeff Lamarche, hay muchos recursos realmente buenos sobre cómo objetar la carga allí. Texto del enlace
Puede dibujar un cilindro procesalmente calculando la geometría. Además de eso, debes hacerlo de forma que admita la eliminación de triángulos y también necesites calcular las coordenadas de mapeo y posiblemente también las normales. Por lo tanto, tomará un poco de pensamiento hacerlo desde cero.
He creado un módulo para Unity3D en C # que hace exactamente esto y le permite modificar los parámetros. Debería poder convertir fácilmente a C o C ++ ya que el cálculo de la geometría es el mismo en todas partes. Mire el video para ver de qué se trata y descargue el código de GitHub .
Espero que esto te pueda ayudar, esta es mi implementación de un cilindro en OpenGLES 2.0 para 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;
}