OpenGL绘制球体

//球心坐标为(x,y,z),球的半径为radius,M,N分别表示球体的横纵向被分成多少份
void drawSphere(GLfloat xx, GLfloat yy, GLfloat zz, GLfloat radius, GLfloat M, GLfloat N)
{
 float step_z = PI/M;
 float step_xy = 2*PI/N;
 float x[4],y[4],z[4];

 float angle_z = 0.0;
 float angle_xy = 0.0;
 int i=0, j=0;
 glBegin(GL_QUADS);
  for(i=0; i<M; i++)
  {
   angle_z = i * step_z;
   
   for(j=0; j<N; j++)
   {
    angle_xy = j * step_xy;

    x[0] = radius * sin(angle_z) * cos(angle_xy);
    y[0] = radius * sin(angle_z) * sin(angle_xy);
    z[0] = radius * cos(angle_z);

    x[1] = radius * sin(angle_z + step_z) * cos(angle_xy);
    y[1] = radius * sin(angle_z + step_z) * sin(angle_xy);
    z[1] = radius * cos(angle_z + step_z);

    x[2] = radius*sin(angle_z + step_z)*cos(angle_xy + step_xy);
    y[2] = radius*sin(angle_z + step_z)*sin(angle_xy + step_xy);
    z[2] = radius*cos(angle_z + step_z);

    x[3] = radius * sin(angle_z) * cos(angle_xy + step_xy);
    y[3] = radius * sin(angle_z) * sin(angle_xy + step_xy);
    z[3] = radius * cos(angle_z);

    for(int k=0; k<4; k++)
    {
     glVertex3f(xx+x[k], yy+y[k],zz+z[k]);
    }
   }
  }
 glEnd();
}


 

### 使用OpenGL绘制球体 #### 创建窗口并初始化OpenGL上下文 为了使用OpenGL绘制球体,首先需要创建一个窗口,并在此基础上初始化OpenGL上下文。这一步骤通常借助于第三方库完成,比如GLFW或SDL。 ```cpp // C++代码示例 #include <GL/glew.h> #include <GLFW/glfw3.h> void createWindow(int width, int height) { glfwInit(); GLFWwindow* window = glfwCreateWindow(width, height, "LearnOpenGL", NULL, NULL); if (!window) { std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate(); exit(-1); } glfwMakeContextCurrent(window); glewExperimental = GL_TRUE; // 需要设置为true才能正常使用GLEW if (glewInit() != GLEW_OK) { // 初始化GLEW std::cout << "Failed to initialize GLEW" << std::endl; exit(-1); } glViewport(0, 0, width, height); // 设置视口大小 } ``` #### 定义顶点数据和索引缓冲对象(IBO) 对于球体而言,其表面由多个三角形组成。这些三角形通过一系列顶点坐标表示。下面展示了一个简单的球面网格生成算法: ```cpp std::vector<float> generateSphereVertices(float radius, unsigned int slices, unsigned int stacks) { float PI = 3.14159f; std::vector<float> vertices; for(unsigned int i=0 ;i<=stacks;++i){ double lat0=(PI*(double)(i-1)/(double)stacks)-(PI/2.); double z0 = sin(lat0)*radius; double zr0 = cos(lat0)*radius; double lat1=(PI*(double)i/(double)stacks)-(PI/2.); double z1 = sin(lat1)*radius; double zr1 = cos(lat1)*radius; for(unsigned int j=0;j<=slices;++j){ double lng = 2.*PI*(double)(j)/(double)slices; double x = cos(lng)*zr0; double y = sin(lng)*zr0; vertices.push_back(x); vertices.push_back(y); vertices.push_back(z0); x = cos(lng)*zr1; y = sin(lng)*zr1; vertices.push_back(x); vertices.push_back(y); vertices.push_back(z1); } } return vertices; } unsigned int VBO, IBO; glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices.data(), GL_STATIC_DRAW); glGenBuffers(1, &IBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(unsigned short), indices.data(), GL_STATIC_DRAW); ``` #### 编写着色器程序 接着编写两个着色器——顶点着色器和片段着色器来处理几何变换以及颜色计算等工作。 **顶点着色器** ```c #version 330 core layout(location = 0) in vec3 aPos; uniform mat4 model; uniform mat4 view; uniform mat4 projection; void main() { gl_Position = projection * view * model * vec4(aPos, 1.0); } ``` **片段着色器** ```c #version 330 core out vec4 FragColor; void main() { FragColor = vec4(1.0, 0.5, 0.2, 1.0); // 橙色 } ``` #### 渲染循环 最后,在主渲染循环内调用`drawElements()`方法即可将之前准备好的顶点数组按照指定的方式呈现到屏幕上。 ```cpp while(!glfwWindowShouldClose(window)){ processInput(window); glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); ourShader.use(); glBindVertexArray(VAO); glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0); glfwSwapBuffers(window); glfwPollEvents(); } ```
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值