OpenGL / C ++ 3D球体 [英] OpenGL/C++ 3D sphere
问题描述
下面是在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屋!