实现OpenGL球形示例代码 [英] Implementing opengl sphere example code

查看:216
本文介绍了实现OpenGL球形示例代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试实现领域示例代码我

Trying to implement a sphere example code I found here on stackoverflow I have been running into problems. Note that I am not using the draw code, I am using the void SolidSphere function from this example to create my vertex data.

这是我的代码,对我引用的示例进行了一些小的更改:

This is my code with some minor changes to the example that I refered to:

std::vector<GLfloat> vertices;
std::vector<GLfloat> normals;
std::vector<GLfloat> texcoords;
std::vector<GLushort> indices;

    Sphere(shared_ptr<GL::Shader> _shader, shared_ptr<Material> _material, float radius, unsigned int rings, unsigned int sectors)
{
    this->attachShader(_shader);
    this->attachMaterial(_material);

    /** Implementation from:
    https://stackoverflow.com/questions/5988686/how-do-i-create-a-3d-sphere-in-opengl-using-visual-c?lq=1
    **/

    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 = sphere_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; r++) {
        for(s = 0; s < sectors; s++) {
            *i++ = r * sectors + s;
            *i++ = r * sectors + (s+1);
            *i++ = (r+1) * sectors + (s+1);
            *i++ = (r+1) * sectors + s;
        }
    }


           /************* THIS IS THE ADDED PART ********/
    for (unsigned int i = 0; i < vertices.size(); i += 3) {
        vertexCoords.push_back(glm::vec4(vertices[i], vertices[i+1], vertices[i+2], 1));
    }

    for (unsigned int i = 0; i < texcoords.size(); i += 2) {
        textureCoords.push_back(glm::vec2(texcoords[i], texcoords[i+1]));
    }
    indexElements = indices;

    cout << "Vertex vector size: " << vertexCoords.size() << endl;
    cout << "Texture vector size: " << textureCoords.size() << endl;
    cout << "Element index vector size: " << indexElements.size() << endl;
}

这里唯一的大变化是使用M_PI / 2而不是M_PI_2,并且有两个循环将值推入我的代码使用的格式:

The only big change here is using M_PI / 2 instead of M_PI_2 and two loops that pushes the value into the format my code uses which is:

vector <glm::vec4> vertexCoords;
vector <glm::vec2> textureCoords;
vector <GLushort> indexElements;

这是我正在渲染的图片:

Here is a picture of what I am rendering:

所以我在球体顶部看到了最后一行.

so I am seeing this last line on the top of the sphere..

我在这段代码中做错了什么可能会导致这种情况吗?

Is it anything obvious I am doing wrong in this code that could cause this?

推荐答案

在此循环中:

for(r = 0; r < rings; r++) {
    for(s = 0; s < sectors; s++) {
        *i++ = r * sectors + s;
        *i++ = r * sectors + (s+1);
        *i++ = (r+1) * sectors + (s+1);
        *i++ = (r+1) * sectors + s;
    }
}

您正在访问r+1s+1,当r = rings - 1s = sectors - 1(即循环的最后一次迭代)时,它们将比可用数据高一个.

you are accessing r+1 and s+1 which when r = rings - 1 and s = sectors - 1 (i.e. the last iteration of your loops) will be one higher than the data you have available.

这将指向未初始化的内存区域.它可以包含任何内容,但在这种情况下,它似乎包含零,这将说明该行偏离原点.

This will be pointing to an uninitialised area of memory. This could contain anything, but in this case it appears to contain zeros which would explain the line going off to the origin.

在绘制下一个"四边形时,您只需要提前一个循环就停止这些循环:

As you are drawing the "next" quad you simply need to stop these loops one iteration earlier:

for(r = 0; r < rings-1; r++) {
    for(s = 0; s < sectors-1; s++) {

这篇关于实现OpenGL球形示例代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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