今天用opengl建模了一個球體,接下來簡單的介紹一下自己的實現方法。
先用一張比較容易理解的圖來說明。
如圖所示,假設要建模一個單位球體,球上任意一點的坐標都可由圖中所示公式表示。
接下來的代碼將生成15層,每層33個頂點。
for (float phi = phi_start+ step_size; phi < phi_end-1e-5; phi += step_size) { float cos_phi = cosf(phi); float sin_phi = sinf(phi); for (float theta = 0.f; theta < theta_end+1e-5f; theta += step_size) { float cos_theta = cosf(theta); float sin_theta = sinf(theta); vec_ver.push_back(Vertex(Vector3f<float>(cos_theta*cos_phi, sin_phi, sin_theta*cos_phi),Vector2f<float>(theta*pi2_inverse, phi*pi_inverse + 0.5f))); } }
以上代碼生成了所有頂點,暫且忽略紋理坐標
注意浮點數的比較需要特殊處理
接下來需要生成索引坐標
i表示該點的位置,i+1為在該點右邊的位置,i+33為在該點上面的位置,i+33+1,為在右上邊的位置
for (int hlevel = 0; hlevel < 14; hlevel++) { int index = (hlevel << 5)+hlevel; //hlevel * 33; for (int rlevel = 0; rlevel < 32; rlevel++) { int now_index = index + rlevel; int now_index_right = now_index + 1; int now_index_up = index + rlevel + 33; int now_index_right_up = now_index_right + 33; vec_index.push_back(now_index); vec_index.push_back(now_index_up); vec_index.push_back(now_index_right_up); vec_index.push_back(now_index); vec_index.push_back(now_index_right_up); vec_index.push_back(now_index_right); } }
以上代碼就可以生成所有的索引上,注意我們采用的是左手坐標系。
接下來思考一個問題,紋理坐標要如何表示,實際上這並沒有一個固定的表示方法,根據需求變化。
我采用的方法是
——