java 3D 球体 OpenGL

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5799609/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 12:48:43  来源:igfitidea点击:

3D Sphere OpenGL

javaandroidopengl-es3dgeometry

提问by Henrik

I would like to create a Sphere, actually a globe. But i can't seem to find any helpful information about how to handle the vertices and indices to a sphere, how to set them up. Could any of you lead me on to the right track, maybe give me some example code or link to a tutorial?

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

采纳答案by genpfault

Subdivisionof an octahredonworks pretty well.

细分的的octahredon工作得很好。

回答by JCooper

The easiest thing to do is to use the glu functions. I work mostly in C, but in Java it's probably something like:

最简单的方法是使用 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);

This will create a sphere of radius 2, with 10 longitude subdivisions and 15 latitude subdivisions. It will handle creating texture coordinates and proper normals as well.

这将创建一个半径为 2 的球体,其中包含 10 个经度细分和 15 个纬度细分。它还将处理创建纹理坐标和适当的法线。

If you really want to understand how to do the subdivisions and create the spherical approximation yourself, you might look at this code.

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

回答by Mostafizar

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

            }



}