Как вы рисуете цилиндр с OpenGLES? - PullRequest
3 голосов
/ 29 июня 2009

Как вы рисуете цилиндр с OpenGLES?

Ответы [ 5 ]

3 голосов
/ 30 июня 2009

Первый шаг - написать подпрограмму, которая рисует треугольник. Я оставлю это на ваше усмотрение. Затем просто нарисуйте серию треугольников, которые составляют форму цилиндра. Хитрость заключается в том, чтобы приблизить круг с многоугольником с большим количеством сторон, например 64. Вот немного псевдокода на макушке моей головы.

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);
}

В коде почти наверняка есть ошибка. Скорее всего, я испортил порядок намотки треугольников, чтобы вы могли получить только половину видимых треугольников или очень странный случай с видимой спиной.

Производительность скоро потребует от вас рисования треугольных полос и вентиляторов для повышения эффективности, но это должно помочь вам начать.

1 голос
/ 17 сентября 2014

Я надеюсь, что это может помочь вам, это моя реализация цилиндра в OpenGLES 2.0 для 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;
}
1 голос
/ 30 июня 2009

Вы действительно можете нарисовать цилиндр в OpenGL ES, рассчитав геометрию объекта. Проект с открытым исходным кодом GLUT | ES содержит процедуры рисования геометрии для твердых тел (цилиндры, сферы и т. Д.) В исходном файле glutes_geometry.c. К сожалению, эти функции используют вызовы glBegin () и glEnd (), которых нет в OpenGL ES.

Код для частично работающего цилиндра для реализации OpenGL ES можно найти в ветке форума здесь .

1 голос
/ 29 июня 2009

Вам нужно будет сделать это с помощью загрузки объекта. Вы не можете вызывать 3D примитивы формы, используя Open GL ES.

Посмотрите блог Джеффа Ламарша, там есть много действительно хороших ресурсов о том, как загружать объекты там. текст ссылки

0 голосов
/ 11 декабря 2012

Вы можете нарисовать цилиндр процедурно , рассчитав геометрию. Кроме того, вы должны сделать так, чтобы он поддерживал обрезание треугольников , и вам также необходимо вычислить координаты отображения и, возможно, также и нормали. Так что потребуется немного подумать, чтобы сделать с нуля.

Я создал модуль для Unity3D на C #, который делает именно это и позволяет настраивать параметры. Вы должны быть в состоянии легко конвертировать в C или C ++, поскольку расчет геометрии везде одинаков. Посмотрите видео , чтобы узнать, о чем идет речь, и загрузите код с GitHub .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...