在OPENGL ES中绘制球体时出现问题

发布于 2024-11-08 20:11:09 字数 4197 浏览 0 评论 0 原文

我一直在尝试使用 OpenGL ES 创建自己的球体,并且遵循此处描述的数学 http://www.math.montana.edu/frankw/ccp/multiworld/multipleIVP/spherical/learn.htm

但是当我绘制球体(仅绘制顶点),只绘制了球体的一半。您能否指出我在下面给出的代码中的确切问题是什么:

public class Sphere {

    static private FloatBuffer sphereVertex;
    static private FloatBuffer sphereNormal;
    static float sphere_parms[]=new float[3];

    double mRaduis;
    double mStep;
    float mVertices[];
    private static double DEG = Math.PI/180;
    int mPoints;

    /**
     * The value of step will define the size of each facet as well as the number of facets
     *  
     * @param radius
     * @param step
     */

    public Sphere( float radius, double step) {
        this.mRaduis = radius;
        this.mStep = step;
        sphereVertex = FloatBuffer.allocate(40000);
        mPoints = build();
        Log.d("ALIS CHECK!!!!!!", " COUNT:" + mPoints);
    }

    public void draw(GL10 gl) {
        gl.glFrontFace(GL10.GL_CW);
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, sphereVertex);

        gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
        gl.glDrawArrays(GL10.GL_POINTS, 0, mPoints);
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    }

    private int build() {

        /**
         * x = p * sin(phi) * cos(theta)
         * y = p * sin(phi) * sin(theta)
         * z = p * cos(phi)
         */
        double dTheta = mStep * DEG;
        double dPhi = dTheta;
        int points = 0;

        for(double phi = -(Math.PI/2); phi <= Math.PI/2; phi+=dPhi) {
            //for each stage calculating the slices
            for(double theta = 0.0; theta <= (Math.PI * 2); theta+=dTheta) {
                sphereVertex.put((float) (mRaduis * Math.sin(phi) * Math.cos(theta)) );
                sphereVertex.put((float) (mRaduis * Math.sin(phi) * Math.sin(theta)) );
                sphereVertex.put((float) (mRaduis * Math.cos(phi)) );
                points++;

            }
        }
        sphereVertex.position(0);
        return points;
    }
}

这也是我的渲染器类:

/**
 * These values are used to rotate the image by a certain value
 */
private float xRot;
private float yRot;

public void setxRot(float xRot) {
    this.xRot += xRot;
}

public void setyRot(float yRot) {
    this.yRot += yRot;
}

public GLViewRenderer(Context ctx) {
    //initialize our 3D triangle here
    mSphere = new Sphere(1, 25);
    //Initializing the rate counter object
    //This will help us in calculating the frames per second
    fpsCalculator = new RateCounter(TAG);
    fpsCalculator.start();
}

public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    //initialize all the things required for openGL configurations
    gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);    

    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); 
}

public void onDrawFrame(GL10 gl) {
    if(fpsCalculator != null) 
        fpsCalculator.countOnce();

    //write the drawing code needed
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT);   
    gl.glLoadIdentity();

    /**
     * Change this value in z if you want to see the image zoomed in
     */
    gl.glTranslatef(0.0f, 0.0f, -5.0f); 

    gl.glRotatef(xRot, 0.0f, 1.0f, 0.0f);
    gl.glRotatef(yRot, 1.0f, 0.0f, 0.0f);
    mSphere.draw(gl);
}

public void onSurfaceChanged(GL10 gl, int width, int height) {
    if(height == 0) {                       
        height = 1;                         
    }

    gl.glViewport(0, 0, width, height); 
    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glLoadIdentity();                

    //Calculate The Aspect Ratio Of The Window
    GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 0.1f, 100.0f);

    gl.glMatrixMode(GL10.GL_MODELVIEW);     //Select The Modelview Matrix
    gl.glLoadIdentity();                    //Reset The Modelview Matrix
}

/**
 * Used to stop the FPS counter
 */
public void pause() {
    if(fpsCalculator != null)
        fpsCalculator.stop();
}

}

我非常感谢对此的一些帮助。

PS:我尝试将 CW 更改为 CCW 仍然没有成功 谢谢

I've been trying to create my own sphere using OpenGL ES and I followed the math described here http://www.math.montana.edu/frankw/ccp/multiworld/multipleIVP/spherical/learn.htm

However when I draw the sphere (just the vertices), just half of the sphere is been drawn. Can you please point to me what is the exact problem in the code that I am giving below:

public class Sphere {

    static private FloatBuffer sphereVertex;
    static private FloatBuffer sphereNormal;
    static float sphere_parms[]=new float[3];

    double mRaduis;
    double mStep;
    float mVertices[];
    private static double DEG = Math.PI/180;
    int mPoints;

    /**
     * The value of step will define the size of each facet as well as the number of facets
     *  
     * @param radius
     * @param step
     */

    public Sphere( float radius, double step) {
        this.mRaduis = radius;
        this.mStep = step;
        sphereVertex = FloatBuffer.allocate(40000);
        mPoints = build();
        Log.d("ALIS CHECK!!!!!!", " COUNT:" + mPoints);
    }

    public void draw(GL10 gl) {
        gl.glFrontFace(GL10.GL_CW);
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, sphereVertex);

        gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
        gl.glDrawArrays(GL10.GL_POINTS, 0, mPoints);
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    }

    private int build() {

        /**
         * x = p * sin(phi) * cos(theta)
         * y = p * sin(phi) * sin(theta)
         * z = p * cos(phi)
         */
        double dTheta = mStep * DEG;
        double dPhi = dTheta;
        int points = 0;

        for(double phi = -(Math.PI/2); phi <= Math.PI/2; phi+=dPhi) {
            //for each stage calculating the slices
            for(double theta = 0.0; theta <= (Math.PI * 2); theta+=dTheta) {
                sphereVertex.put((float) (mRaduis * Math.sin(phi) * Math.cos(theta)) );
                sphereVertex.put((float) (mRaduis * Math.sin(phi) * Math.sin(theta)) );
                sphereVertex.put((float) (mRaduis * Math.cos(phi)) );
                points++;

            }
        }
        sphereVertex.position(0);
        return points;
    }
}

Also here is my renderer class:

/**
 * These values are used to rotate the image by a certain value
 */
private float xRot;
private float yRot;

public void setxRot(float xRot) {
    this.xRot += xRot;
}

public void setyRot(float yRot) {
    this.yRot += yRot;
}

public GLViewRenderer(Context ctx) {
    //initialize our 3D triangle here
    mSphere = new Sphere(1, 25);
    //Initializing the rate counter object
    //This will help us in calculating the frames per second
    fpsCalculator = new RateCounter(TAG);
    fpsCalculator.start();
}

public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    //initialize all the things required for openGL configurations
    gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);    

    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); 
}

public void onDrawFrame(GL10 gl) {
    if(fpsCalculator != null) 
        fpsCalculator.countOnce();

    //write the drawing code needed
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT);   
    gl.glLoadIdentity();

    /**
     * Change this value in z if you want to see the image zoomed in
     */
    gl.glTranslatef(0.0f, 0.0f, -5.0f); 

    gl.glRotatef(xRot, 0.0f, 1.0f, 0.0f);
    gl.glRotatef(yRot, 1.0f, 0.0f, 0.0f);
    mSphere.draw(gl);
}

public void onSurfaceChanged(GL10 gl, int width, int height) {
    if(height == 0) {                       
        height = 1;                         
    }

    gl.glViewport(0, 0, width, height); 
    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glLoadIdentity();                

    //Calculate The Aspect Ratio Of The Window
    GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 0.1f, 100.0f);

    gl.glMatrixMode(GL10.GL_MODELVIEW);     //Select The Modelview Matrix
    gl.glLoadIdentity();                    //Reset The Modelview Matrix
}

/**
 * Used to stop the FPS counter
 */
public void pause() {
    if(fpsCalculator != null)
        fpsCalculator.stop();
}

}

I'd really appreciate some help on this.

P.S: I tried changing CW to CCW still no luck
Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

层林尽染 2024-11-15 20:11:09

把这个改成

for(double phi = -(Math.PI/2); phi <= Math.PI/2; phi+=dPhi)

这个

for(double phi = -(Math.PI); phi <= Math.PI; phi+=dPhi)

Change this

for(double phi = -(Math.PI/2); phi <= Math.PI/2; phi+=dPhi)

to this

for(double phi = -(Math.PI); phi <= Math.PI; phi+=dPhi)
奈何桥上唱咆哮 2024-11-15 20:11:09

其实改成

for(double phi = -(Math.PI/2); phi <= Math.PI/2; phi+=dPhi)

就够

for(double phi = -(Math.PI); phi <= 0; phi+=dPhi)

了。当 phi 从 -(Math.PI) 到 +(Math.PI) 时,您将进行 360 度旋转并对每个点计数两次。您还可以这样做:

for(double phi = -(Math.PI); phi <= Math.PI; phi+=dPhi) {
     for(double theta = 0.0; theta <= (Math.PI); theta+=dTheta) {
     ... 
     }
}

避免计数两次。

Actually, changing

for(double phi = -(Math.PI/2); phi <= Math.PI/2; phi+=dPhi)

to

for(double phi = -(Math.PI); phi <= 0; phi+=dPhi)

is enough. With phi from -(Math.PI) to +(Math.PI) you are making 360 degrees turn and counting each point twice. You can also do:

for(double phi = -(Math.PI); phi <= Math.PI; phi+=dPhi) {
     for(double theta = 0.0; theta <= (Math.PI); theta+=dTheta) {
     ... 
     }
}

to avoid counting twice.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文