我正在尝试使用此处的最后一个算法绘制球体:http://paulbourke.net/miscellaneous/sphere_cylinder/。使用八面体。
这是我的算法:
struct Vertex {
GLdouble position[3];
GLfloat color[3];
GLdouble normal[3];
};
struct XYZ {
GLdouble x;
GLdouble y;
GLdouble z;
};
struct FACET3 {
XYZ p1;
XYZ p2;
XYZ p3;
};
Vertex sphere_vertices_new[512];
FACET3 facet[512];
以上只是一些声明。
下面我计算所有内容,然后绘制线条:
void Normalise(XYZ *p_input)
{
double magnitude = 0;
magnitude = sqrt((p_input->x * p_input->x )+ (p_input->y * p_input->y) + (p_input->z * p_input->z));
p_input->x = p_input->x / magnitude;
p_input->y = p_input->y / magnitude;
p_input->z = p_input->z / magnitude;
}
int CreateNSphere(FACET3 *f,int iterations)
{
int i,it;
double a;
XYZ p[6] = {0,0,1, 0,0,-1, -1,-1,0, 1,-1,0, 1,1,0, -1,1,0};
XYZ pa,pb,pc;
int nt = 0,ntold;
/* Create the level 0 object */
a = 1 / sqrt(2.0);
for (i=0;i<6;i++) {
p[i].x *= a;
p[i].y *= a;
}
f[0].p1 = p[0]; f[0].p2 = p[3]; f[0].p3 = p[4];
f[1].p1 = p[0]; f[1].p2 = p[4]; f[1].p3 = p[5];
f[2].p1 = p[0]; f[2].p2 = p[5]; f[2].p3 = p[2];
f[3].p1 = p[0]; f[3].p2 = p[2]; f[3].p3 = p[3];
f[4].p1 = p[1]; f[4].p2 = p[4]; f[4].p3 = p[3];
f[5].p1 = p[1]; f[5].p2 = p[5]; f[5].p3 = p[4];
f[6].p1 = p[1]; f[6].p2 = p[2]; f[6].p3 = p[5];
f[7].p1 = p[1]; f[7].p2 = p[3]; f[7].p3 = p[2];
nt = 8;
if (iterations < 1)
return(nt);
/* Bisect each edge and move to the surface of a unit sphere */
for (it=0;it<iterations;it++) {
ntold = nt;
for (i=0;i<ntold;i++) {
pa.x = (f[i].p1.x + f[i].p2.x) / 2;
pa.y = (f[i].p1.y + f[i].p2.y) / 2;
pa.z = (f[i].p1.z + f[i].p2.z) / 2;
pb.x = (f[i].p2.x + f[i].p3.x) / 2;
pb.y = (f[i].p2.y + f[i].p3.y) / 2;
pb.z = (f[i].p2.z + f[i].p3.z) / 2;
pc.x = (f[i].p3.x + f[i].p1.x) / 2;
pc.y = (f[i].p3.y + f[i].p1.y) / 2;
pc.z = (f[i].p3.z + f[i].p1.z) / 2;
Normalise(&pa);
Normalise(&pb);
Normalise(&pc);
f[nt].p1 = f[i].p1; f[nt].p2 = pa; f[nt].p3 = pc;
nt++;
f[nt].p1 = pa; f[nt].p2 = f[i].p2; f[nt].p3 = pb;
nt++;
f[nt].p1 = pb; f[nt].p2 = f[i].p3; f[nt].p3 = pc;
nt++;
f[i].p1 = pa;
f[i].p2 = pb;
f[i].p3 = pc;
}
}
return(nt);
}
void facet_to_vertex(FACET3 *f)
{
int i=0;
int a,b,c;
int k=0;
for (i=0;i<512;i++)
{
sphere_vertices_new[i].color[0] = 1.f;
sphere_vertices_new[i].color[1] = 1.f;
sphere_vertices_new[i].color[2] = 1.f;
}
for (i=0;i<512;i++)
{
//printf("The vertices (x,y,z) for facet %d are: V_1 = x:%f , y:%f, z:%f. \n", i, f[i].p1.x, f[i].p1.y, f[i].p1.z);
//printf("The vertices (x,y,z) for facet %d are: V_2 = x:%f , y:%f, z:%f. \n", i, f[i].p2.x, f[i].p2.y, f[i].p2.z);
//printf("The vertices (x,y,z) for facet %d are: V_3 = x:%f , y:%f, z:%f. \n", i, f[i].p3.x, f[i].p3.y, f[i].p3.z);
//For V_1
a=k;
sphere_vertices_new[a].position[0] = f[i].p2.x;
sphere_vertices_new[a].position[1] = f[i].p2.y;
sphere_vertices_new[a].position[2] = f[i].p2.z;
printf(">>>%d \n", a);
//For V_2
b=k+1;
sphere_vertices_new[b].position[0] = f[i].p1.y;
sphere_vertices_new[b].position[1] = f[i].p1.y;
sphere_vertices_new[b].position[2] = f[i].p1.y;
printf(">>>%d \n", b);
//For V_3
c=k+2;
sphere_vertices_new[c].position[0] = f[i].p3.z;
sphere_vertices_new[c].position[1] = f[i].p3.z;
sphere_vertices_new[c].position[2] = f[i].p3.z;
printf(">>>%d \n", c);
k++;
}
}
主要问题在于“facet_to_vertex”方法。我从构面中提取信息,然后在“sphere_vertices_new”数组中传递它。问题是如果我使用“GL_POINTS”它似乎是一个球体。但是当我使用GL_LINES,GL_LINE_STRIP或GL_TRIANGLES时,一切都搞砸了。
使用积分:
使用行:
编辑:绘图代码:
void SetupGemetry() {
/* Allocate and assign One Vertex Buffer Object to our handle */
glGenBuffers(1, &vbo);
/* Bind our VBO as being the active buffer and storing vertex attributes (coordinates + colors) */
glBindBuffer(GL_ARRAY_BUFFER, vbo);
//MY CODE glBufferData...!!!!!!!!!!!!!!!!!!!!!!
glBufferData ( GL_ARRAY_BUFFER, 512 * sizeof ( struct Vertex ), sphere_vertices_new, GL_STATIC_DRAW );
/* Enable attribute index 0 as being used */
glEnableVertexAttribArray( 0 );
//MY CODE glVertexAttribPointer...! for the Sphere Vertices
glVertexAttribPointer ( ( GLuint ) 0, 3, GL_DOUBLE, GL_FALSE, sizeof ( struct Vertex ), ( const GLvoid* ) offsetof
(struct Vertex ,position) );
/* Enable attribute index 1 as being used */
glEnableVertexAttribArray ( 1 );/* Bind our second VBO as being the active buffer and storing vertex attributes(colors) */
/* Specify that our color data is going into attribute index 1, and contains three floats per vertex */
/* Note stride = sizeof ( struct Vertex ) and pointer = ( const GLvoid* ) ( 3 * sizeof ( GLdouble ) ) i.e. the size
(in bytes) occupied by the first attribute (position) */
glVertexAttribPointer ( ( GLuint ) 1, 3, GL_FLOAT, GL_FALSE, sizeof ( struct Vertex ), ( const GLvoid* )
offsetof(struct Vertex,color) );
}
void SetupShaders(void){
/* Read our shaders into the appropriate buffers */
vertexsource = filetobuf("tutorial3.vert");
fragmentsource = filetobuf("tutorial3.frag");
/* Assign our handles a "name" to new shader objects */
vertexshader = glCreateShader(GL_VERTEX_SHADER);
fragmentshader = glCreateShader(GL_FRAGMENT_SHADER);
/* Associate the source code buffers with each handle */
glShaderSource(vertexshader, 1, (const GLchar**)&vertexsource, 0);
glShaderSource(fragmentshader, 1, (const GLchar**)&fragmentsource, 0);
/* Compile our shader objects */
glCompileShader(vertexshader);
glCompileShader(fragmentshader);
/* Assign our program handle a "name" */
shaderprogram = glCreateProgram();
glAttachShader(shaderprogram, vertexshader);/* Attach our shaders to our program */
glAttachShader(shaderprogram, fragmentshader);
/* Bind attribute 0 (coordinates) to in_Position and attribute 1 (colors) to in_Color*/
glBindAttribLocation(shaderprogram, 0, "in_Position");
glBindAttribLocation(shaderprogram, 1, "in_Color");
//pass the normal to vertex shader
glBindAttribLocation(shaderprogram, 2, "in_Normal");
/* Link our program, and set it as being actively used */
glLinkProgram(shaderprogram);
glUseProgram(shaderprogram);
}
void Render(int i) {
GLfloat angle;
//PROJECTION
glm::mat4 Projection = glm::perspective(45.0f, 1.0f, 0.1f, 100.0f);
angle = (GLfloat) (i/50 % 360); //to dia gia nan pio argo
//printf("Angle: >>>> %f, \n", angle);
//VIEW
glm::mat4 View = glm::mat4(1.);
View = glm::translate(View, glm::vec3(0.f, 0.f, -4.0f)); // x, y, z position ?
View = glm::rotate(View, angle * -1.0f, glm::vec3(1.f, 0.f, 0.f));
View = glm::rotate(View, angle * 0.5f, glm::vec3(0.f, 1.f, 0.f));
View = glm::rotate(View, angle * 0.5f, glm::vec3(0.f, 0.f, 1.f));
//MODEL
glm::mat4 Model = glm::mat4(1.0);
glm::mat4 MVP = Projection * View * Model;
glUniformMatrix4fv(glGetUniformLocation(shaderprogram, "MVP_matrix"), 1, GL_FALSE, glm::value_ptr(MVP));
//Transfer additional information to the vertex shader //mycode
glm::mat4 MV = Model * View;
glUniformMatrix4fv(glGetUniformLocation(shaderprogram, "MV_matrix"), 1, GL_FALSE, glm::value_ptr(MV));
/* Bind our modelmatrix variable to be a uniform called mvpmatrix in our shaderprogram */
glClearColor(0.0, 0.0, 0.0, 1.0);/* Make our background black */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_LINES, 0, 512);
}