3D球体OpenGL

时间:2011-04-27 05:07:08

标签: java android opengl-es 3d geometry

我想创建一个Sphere,实际上是一个地球仪。但我似乎无法找到有关如何处理球体的顶点和索引,如何设置它们的任何有用信息。你们中的任何人都可以引导我走上正确的轨道,或许可以给我一些示例代码或链接到教程吗?

3 个答案:

答案 0 :(得分:4)

最简单的方法是使用glu函数。我主要在C工作,但在Java中它可能是这样的:

import net.java.games.jogl.GL;
import net.java.games.jogl.GLU;
import net.java.games.jogl.GLUquadric;

...

GLUquadric quad = glu.gluNewQuadric();
glu.gluSphere(quad, 2, 10, 15);
glu.gluDeleteQuadric(quad);

这将创建一个半径为2的球体,具有10个经度细分和15个纬度细分。它还将处理创建纹理坐标和正常法线。

如果您真的想了解如何进行细分并自己创建球形近似,可以查看this code

答案 1 :(得分:3)

Subdivisionoctahredon效果非常好。

答案 2 :(得分:2)

import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.awt.GLJPanel;
import javax.swing.JFrame;


public class Sphere extends GLJPanel implements GLEventListener,KeyListener {

    /**
     * 
     */
    private static final long serialVersionUID = -7419599978736850207L;

    private float rotateX, rotateY, rotateZ;

    public static void main(String[] args) {
        JFrame window = new JFrame("Cube");
        GLCapabilities caps = new GLCapabilities(null);
        Sphere panel = new Sphere(caps);
        window.setContentPane(panel);
        window.pack();
        window.setLocation(50, 50);
        window.setResizable(false);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setVisible(true);
        panel.requestFocusInWindow();
    }


    public Sphere(GLCapabilities capabilities) {
        // TODO Auto-generated constructor stub
        super(capabilities);
        setPreferredSize(new Dimension(500, 500));
        addGLEventListener(this);
        addKeyListener(this);
        rotateX = 15;
        rotateY = 15;
        rotateZ = 0;
    }



    void drawSphere(double r, int lats, int longs,GL2 gl) {
                int i, j;
                for(i = 0; i <= lats; i++) {
                    double lat0 = Math.PI * (-0.5 + (double) (i - 1) / lats);
                   double z0  = Math.sin(lat0);
                   double zr0 =  Math.cos(lat0);

                   double lat1 = Math.PI * (-0.5 + (double) i / lats);
                   double z1 = Math.sin(lat1);
                   double zr1 = Math.cos(lat1);

                   gl.glBegin(gl.GL_QUAD_STRIP);
                   for(j = 0; j <= longs; j++) {
                       double lng = 2 * Math.PI * (double) (j - 1) / longs;
                       double x = Math.cos(lng);
                       double y = Math.sin(lng);

                       gl.glNormal3d(x * zr0, y * zr0, z0);
                       gl.glVertex3d(x * zr0, y * zr0, z0);
                       gl.glNormal3d(x * zr1, y * zr1, z1);
                       gl.glVertex3d(x * zr1, y * zr1, z1);
                   }
                   gl.glEnd();
               }
           }

           void computeLocation(GL2 gl) {
               double x = 2 * Math.cos(0);     // my x-, y-, and z-coordinates
               double y = 2 * Math.sin(0);
               double z = 20;
               double d = Math.sqrt(x * x + y * y + z * z); // distance to origin

               gl.glMatrixMode(gl.GL_PROJECTION);        // Set projection parameters.
               gl.glLoadIdentity();
               gl.glFrustum(-d * 0.5, d * 0.5, -d * 0.5, d * 0.5, d - 1.1, d + 1.1);
          }

           public void display(GLAutoDrawable drawable) {

                GL2 gl = drawable.getGL().getGL2();
                gl.glClearColor(0, 0, 0, 0);
                gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

                gl.glMatrixMode(GL2.GL_PROJECTION);
                gl.glLoadIdentity();
                gl.glMatrixMode(GL2.GL_MODELVIEW);

                gl.glLoadIdentity();

                gl.glRotatef(rotateZ, 0, 0, 1);
                gl.glRotatef(rotateY, 0, 1, 0);
                gl.glRotatef(rotateX, 1, 0, 0);
                gl.glColor3d(1.0, 0.0, 0.0);
                drawSphere(1, 10, 10, gl);

            }

            public void init(GLAutoDrawable drawable) {
                // called when the panel is created
                GL2 gl = drawable.getGL().getGL2();
                computeLocation(gl);
                gl.glEnable(GL.GL_DEPTH_TEST);
            }

            @Override
            public void dispose(GLAutoDrawable drawable) {

            }

            @Override
            public void reshape(GLAutoDrawable drawable, int x, int y, int width,
                    int height) {

            }


            @Override
            public void keyPressed(java.awt.event.KeyEvent e) {
                int key = e.getKeyCode();
                if (key == KeyEvent.VK_LEFT)
                    rotateY -= 15;
                else if (key == KeyEvent.VK_RIGHT)
                    rotateY += 15;
                else if (key == KeyEvent.VK_DOWN)
                    rotateX += 15;
                else if (key == KeyEvent.VK_UP)
                    rotateX -= 15;
                else if (key == KeyEvent.VK_PAGE_UP)
                    rotateZ += 15;
                else if (key == KeyEvent.VK_PAGE_DOWN)
                    rotateZ -= 15;
                else if (key == KeyEvent.VK_HOME)
                    rotateX = rotateY = rotateZ = 0;
                repaint();

            }

            @Override
            public void keyReleased(java.awt.event.KeyEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void keyTyped(java.awt.event.KeyEvent e) {
                // TODO Auto-generated method stub

            }



}