2011-04-27 130 views
6

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

回答

3

Subdivisionoctahredon工作得很好。

+0

伟大的文章,有没有人有这个功能的Java端口? – 2011-04-27 05:35:16

+0

链接已损坏,应删除此答案。 – Yusha 2016-10-23 20:09:40

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

+0

我想它适用于普通的Java使用,但GLUquadric似乎不适用于Android?我可能是错的寿,任何人都知道这对于Android? – Henrik 2011-04-29 17:53:45

+1

@Henrik Hm。它看起来像在OpenGL-ES中不存在二次函数。这意味着你需要用适当的值实现你自己的vertex_array和normal_array。 – JCooper 2011-04-29 21:43:15

+1

是的,帮助,我用Blender创建一个简单的球体并导出为.Obj文件,在我的代码中读取它并将值复制到您讨论的thoose数组中。有一个很好的球体,感谢您的帮助 – Henrik 2011-04-29 21:51:20

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 

      } 



}