OpenGL / C ++ 3D球体 [英] OpenGL/C++ 3D sphere

查看:427
本文介绍了OpenGL / C ++ 3D球体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是在OpenGL中手动创建球体的广泛代码。我修改了一点,所以它看起来更完整,现在,但仍然不能得到它的工作。它只产生一个白色的窗口。任何想法我错过了什么?

Below you find the widely spread code for manually creating a sphere in OpenGL. I modified it a little, so that it looks more complete now, but still can't get it to work. It only produces a white window. Any ideas what am I missing?

#include <vector>
#include <math.h>
#include <GL/glut.h>

#define M_PI 3.14159265358979323846
#define M_PI_2 1.57079632679489661923

int const win_width = 512;
int const win_height = 512;

using namespace std;

class SolidSphere
{
protected:
    std::vector<GLfloat> vertices;
    std::vector<GLfloat> normals;
    std::vector<GLfloat> texcoords;
    std::vector<GLushort> indices;

public:
    SolidSphere(float radius, unsigned int rings, unsigned int sectors)
    {
        float const R = 1./(float)(rings-1);
        float const S = 1./(float)(sectors-1);
        int r, s;

        vertices.resize(rings * sectors * 3);
        normals.resize(rings * sectors * 3);
        texcoords.resize(rings * sectors * 2);
        std::vector<GLfloat>::iterator v = vertices.begin();
        std::vector<GLfloat>::iterator n = normals.begin();
        std::vector<GLfloat>::iterator t = texcoords.begin();
        for(r = 0; r < rings; r++) {
            for(s = 0; s < sectors; s++) {
                float const y = sin(-M_PI_2 + M_PI * r * R);
                float const x = cos(2*M_PI * s * S) * sin(M_PI * r * R);
                float const z = sin(2*M_PI * s * S) * sin(M_PI * r * R);

                *t++ = s*S;
                *t++ = r*R;

                *v++ = x * radius;
                *v++ = y * radius;
                *v++ = z * radius;

                *n++ = x;
                *n++ = y;
                *n++ = z;
            }
        }

        indices.resize(rings * sectors * 4);
        std::vector<GLushort>::iterator i = indices.begin();
        for (r = 0; r < rings-1; r++) {
            for(s = 0; s < sectors-1; s++) {
                *i++ = r * sectors + s;
                *i++ = r * sectors + (s+1);
                *i++ = (r+1) * sectors + (s+1);
                *i++ = (r+1) * sectors + s;
            }
        }
    }

    void draw(GLfloat x, GLfloat y, GLfloat z)
    {
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
        glTranslatef(x,y,z);

        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_NORMAL_ARRAY);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);

        glVertexPointer(3, GL_FLOAT, 0, &vertices[0]);
        glNormalPointer(GL_FLOAT, 0, &normals[0]);
        glTexCoordPointer(2, GL_FLOAT, 0, &texcoords[0]);
        glDrawElements(GL_QUADS, indices.size(), GL_UNSIGNED_SHORT, &indices[0]);
        glPopMatrix();
    }
};

SolidSphere sphere(1, 12, 24);

void display()
{
    float const win_aspect = (float)win_width/(float)win_height;

    glViewport(0, 0, win_width, win_height);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45, win_aspect, 1, 10);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

#ifdef DRAW_WIREFRAME
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
#endif
    sphere.draw(0, 0, -5);

    glutSwapBuffers();
}

int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowSize(win_width, win_height);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("3D Sphere");
    glutDisplayFunc(display);
    glutMainLoop();
    return 0;
}

推荐答案

对glDrawElements的调用必须如下所示:

The call to glDrawElements must look like this

    glDrawElements(GL_QUADS, indices.size(), GL_UNSIGNED_SHORT, &indices[0]);

由于 draw ,否则必须在其前面加上前缀(只有在方法定义在类外部时才有效。

Also since the draw method is written inline, no SolidSphere:: must prefix it (that would be valid only if the method is defined outside the class.

您发布的代码源于我在一年前提供的StackOverflow答案: http://stackoverflow.com/a/5989676/524368

The code you posted originates in this StackOverflow answer I gave over a year ago: http://stackoverflow.com/a/5989676/524368

如果你看看这个答案, draw 的定义和其中的glDrawElements调用是正确的并且对答案中的代码的任何编辑是对其他部分,但不是这样的。因此,无论你从哪里获取代码,它都会改变错误。

And if you look at this answer the definition of draw and the glDrawElements call therein are correct and any edits to the code in the answer were to other parts, but not this. So wherever you took the code from, it got altered with mistakes.

这篇关于OpenGL / C ++ 3D球体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆