Android+NDK+OpenGL繪製球形

首先申明一點,我利用的是ndk進行開發(做畢業設計),目前利用ndk調用opengl es進行基本物體的繪製

因此,所繪製的代碼採用c語言進行編寫,已經把正方體,曲線,圓的繪製函數編寫出來了,球的比較麻煩,最近參考了很多資料,才弄出來,

發個帖子,希望共同學習,不會的可以借鑑

 

好了,步入正文

繪製球的基本思路,我參考了外國網站上一篇文章,希望大家能閱讀一下思想很好。(http://local.wasp.uwa.edu.au/~pbourke/miscellaneous/sphere_cylinder/

我用的就是第一個思路,經緯分割吧。把球按經緯分割成小正方形,每個正方形按四個頂點進行繪製

c語言實現的代碼如下:

 

/*

   Create a unit sphere centered at the origin

   This code illustrates the concept rather than implements it efficiently

   It is called with two arguments, the theta and phi angle increments in degrees

   Note that at the poles only 3 vertex facet result

        while the rest of the sphere has 4 point facets

*/

typedef struct {

   double x,y,z;

} XYZ;

void CreateUnitSphere(int dtheta,int dphi)

{

   int n;

   int theta,phi;

   XYZ p[4];

 

   for (theta=-90;theta<=90-dtheta;theta+=dtheta) {

      for (phi=0;phi<=360-dphi;phi+=dphi) {

         n = 0;

         p[n].x = cos(theta*DTOR) * cos(phi*DTOR);

         p[n].y = cos(theta*DTOR) * sin(phi*DTOR);

         p[n].z = sin(theta*DTOR);

         n++;

         p[n].x = cos((theta+dtheta)*DTOR) * cos(phi*DTOR);

         p[n].y = cos((theta+dtheta)*DTOR) * sin(phi*DTOR);

         p[n].z = sin((theta+dtheta)*DTOR);

         n++;

         p[n].x = cos((theta+dtheta)*DTOR) * cos((phi+dphi)*DTOR);

         p[n].y = cos((theta+dtheta)*DTOR) * sin((phi+dphi)*DTOR);

         p[n].z = sin((theta+dtheta)*DTOR);

         n++;

         if (theta > -90 && theta < 90) {

            p[n].x = cos(theta*DTOR) * cos((phi+dphi)*DTOR);

            p[n].y = cos(theta*DTOR) * sin((phi+dphi)*DTOR);

            p[n].z = sin(theta*DTOR);

            n++;

         }

 

         /* Do something with the n vertex facet p */

 

      }

   }

}

這是非常關鍵的函數實現代碼。珍藏!
然後就是繪製。我直接把jni.c端的代碼全部發上了,如下:
#include <jni.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <GLES/gl.h>
typedef unsigned char byte;
typedef struct {
   GLfloat x,y,z;
} XYZ;
float rotateQuad;
#define PI 3.14159265
#define DTOR PI/180
static byte indices[8]={0,1,1,2,2,3,3,0};  //索引數組
void CreateUnitSphere(int dtheta,int dphi)
{
   int n;
   int theta,phi;
   XYZ p[4];
   for (theta=-90;theta<=90-dtheta;theta+=dtheta) {
      for (phi=0;phi<=360-dphi;phi+=dphi) {
         n = 0;
         p[n].x = cos(theta*DTOR) * cos(phi*DTOR);
         p[n].y = cos(theta*DTOR) * sin(phi*DTOR);
         p[n].z = sin(theta*DTOR);
         n++;
         p[n].x = cos((theta+dtheta)*DTOR) * cos(phi*DTOR);
         p[n].y = cos((theta+dtheta)*DTOR) * sin(phi*DTOR);
         p[n].z = sin((theta+dtheta)*DTOR);
         n++;
         p[n].x = cos((theta+dtheta)*DTOR) * cos((phi+dphi)*DTOR);
         p[n].y = cos((theta+dtheta)*DTOR) * sin((phi+dphi)*DTOR);
         p[n].z = sin((theta+dtheta)*DTOR);
         n++;
         if (theta >=-90 && theta <= 90) {
            p[n].x = cos(theta*DTOR) * cos((phi+dphi)*DTOR);
            p[n].y = cos(theta*DTOR) * sin((phi+dphi)*DTOR);
            p[n].z = sin(theta*DTOR);
            n++;
         }
         /* Do something with the n vertex facet p */
glVertexPointer(3, GL_FLOAT, 0, p);
glDrawElements(GL_LINES, 8, GL_UNSIGNED_BYTE, indices);
      }
   }
}
void Java_com_ldj_hellondk_NdkGLRenderer_onNdkSurfaceCreated (JNIEnv* env, jobject obj)
{
// 啓用陰影平滑
glShadeModel(GL_SMOOTH);
// 黑色背景
glClearColor(0, 0, 0, 0);
// 設置深度緩存
glClearDepthf(1.0f);
// 啓用深度測試
glEnable(GL_DEPTH_TEST);
// 所作深度測試的類型
glDepthFunc(GL_LEQUAL);
// 告訴系統對透視進行修正
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
}
void Java_com_ldj_hellondk_NdkGLRenderer_onNdkSurfaceChanged (JNIEnv* env, jobject obj, jint width, jint height)
{
//圖形最終顯示到屏幕的區域的位置、長和寬
    glViewport (0,0,width,height);
//指定矩陣
glMatrixMode   (GL_PROJECTION);
//將當前的矩陣設置爲glMatrixMode指定的矩陣
    glLoadIdentity ();
    glOrthof       (-2, 2, -2, 2, -2, 2);
}
 
void Java_com_ldj_hellondk_NdkGLRenderer_onNdkDrawFrame (JNIEnv* env, jobject obj)
{
//啓用頂點設置功能,之後必須要關閉功能
    glEnableClientState (GL_VERTEX_ARRAY);
//清屏
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode (GL_MODELVIEW);
    glLoadIdentity (); 
glFrontFace(GL_CW);
glRotatef(rotateQuad, 1.0f, 0.5f, 0.0f);//旋轉效果
    CreateUnitSphere(10,10);
//關閉頂點設置功能
glDisableClientState(GL_VERTEX_ARRAY);
rotateQuad -= 0.5f;
}
ok,這就繪製成功了,效果圖如下,繪製實體的話,改一下drawelement的參數就行了

 

效果圖

 

可以去下載源代碼,給個鏈接吧

http://download.csdn.net/source/3219224

 

 

我是菜鳥,最近做畢設做的鬱悶,查資料難啊,所以共享自己的東西,希望研究這方面的人和我交流學習!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章