一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Android - android使用OPENGL ES繪制圓柱體

android使用OPENGL ES繪制圓柱體

2022-03-07 14:52劉國棟 Android

這篇文章主要為大家詳細介紹了android使用OPENGL ES繪制圓柱體 ,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了android使用OPENGL ES繪制圓柱體的具體代碼,供大家參考,具體內容如下

效果圖:

android使用OPENGL ES繪制圓柱體

編寫jiem.java

    *指定屏幕所要顯示的假面,并對見、界面進行相關設置
    *為Activity設置恢復處理,當Acitvity恢復設置時顯示界面同樣應該恢復
    *當Activity暫停設置時,顯示界面同樣應該暫停

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.scout.eeeeeee;
 
import android.app.Activity;
import android.os.Bundle;
import android.app.Activity;
import android.os.Bundle;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
 
public class jiem extends Activity {
 private MyGLSurfaceView mGLSurfaceView;
 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
 
  requestWindowFeature(Window.FEATURE_NO_TITLE);
  getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
 
  mGLSurfaceView = new MyGLSurfaceView(this);
  setContentView(mGLSurfaceView);
  mGLSurfaceView.setFocusableInTouchMode(true);//設置為可觸控
  mGLSurfaceView.requestFocus();//獲取焦點
 }
 
 @Override
 protected void onResume() {
  super.onResume();
  mGLSurfaceView.onResume();
 }
 
 @Override
 protected void onPause() {
  super.onPause();
  mGLSurfaceView.onPause();
 }
}

編寫MyGLSurfaceView.java實現場景加載和渲染功能

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
package com.scout.eeeeeee;
 
/**
 * Created by liuguodong on 2017/10/29.
 */
 
import java.io.IOException;
import java.io.InputStream;
 
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
 
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;
 
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.MotionEvent;
 
public class MyGLSurfaceView extends GLSurfaceView {
 private final float suo = 180.0f/320;//角度縮放比例
 private SceneRenderer mRenderer;//場景渲染器
 private float shangY;//上次的觸控位置Y坐標
 private float shangX;//上次的觸控位置Y坐標
 private int lightAngle=90;//燈的當前角度
 
 public MyGLSurfaceView(Context context) {
  super(context);
  mRenderer = new SceneRenderer(); //創建場景渲染器
  setRenderer(mRenderer);    //設置渲染器
  setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);//設置渲染模式為主動渲染
 }
 
 //觸摸事件回調方法
 @Override
 public boolean onTouchEvent(MotionEvent e) {
  float y = e.getY();
  float x = e.getX();
  switch (e.getAction()) {
   case MotionEvent.ACTION_MOVE:
    float dy = y - shangY;//計算觸控筆Y位移
    float dx = x - shangX;//計算觸控筆Y位移
    mRenderer.cylinder.mAngleX += dy * suo;//設置沿x軸旋轉角度
    mRenderer.cylinder.mAngleZ += dx * suo;//設置沿z軸旋轉角度
    requestRender();//重繪畫面
  }
  shangY = y;//記錄觸控筆位置
  shangX = x;//記錄觸控筆位置
  return true;
 }
 
 private class SceneRenderer implements GLSurfaceView.Renderer
 {
  int textureId;//紋理名稱ID
  zhuCH cylinder;//創建圓柱體
 
  public SceneRenderer()
  {
 
  }
 
  public void onDrawFrame(GL10 gl) {
   //清除顏色緩存
   gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
   //設置當前矩陣為模式矩陣
   gl.glMatrixMode(GL10.GL_MODELVIEW);
   //設置當前矩陣為單位矩陣
   gl.glLoadIdentity();
 
   gl.glPushMatrix();//保護變換矩陣現場
 
   float lx=0; //設定光源的位置
   float ly=(float)(7*Math.cos(Math.toRadians(lightAngle)));
   float lz=(float)(7*Math.sin(Math.toRadians(lightAngle)));
   float[] positionParamsRed={lx,ly,lz,0};
   gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, positionParamsRed,0);
 
   initMaterial(gl);//初始化紋理
   gl.glTranslatef(0, 0, -10f);//平移
   initLight(gl);//開燈
   cylinder.drawSelf(gl);//繪制
   closeLight(gl);//關燈
 
   gl.glPopMatrix();//恢復變換矩陣現場
  }
 
  public void onSurfaceChanged(GL10 gl, int width, int height) {
   //設置視窗大小及位置
   gl.glViewport(0, 0, width, height);
   //設置當前矩陣為投影矩陣
   gl.glMatrixMode(GL10.GL_PROJECTION);
   //設置當前矩陣為單位矩陣
   gl.glLoadIdentity();
   //計算透視投影的比例
   float ratio = (float) width / height;
   //調用此方法計算產生透視投影矩陣
   gl.glFrustumf(-ratio, ratio, -1, 1, 1, 100);
  }
 
  public void onSurfaceCreated(GL10 gl, EGLConfig config) {
   //關閉抗抖動
   gl.glDisable(GL10.GL_DITHER);
   //設置特定Hint項目的模式,這里為設置為使用快速模式
   gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST);
   //設置屏幕背景色黑色RGBA
   gl.glClearColor(0,0,0,0);
   //設置著色模型為平滑著色
   gl.glShadeModel(GL10.GL_SMOOTH);
   //啟用深度測試
   gl.glEnable(GL10.GL_DEPTH_TEST);
 
   textureId=initTexture(gl,R.drawable.stone);//紋理ID
   cylinder=new zhuCH(10f,2f,18f,textureId);//創建圓柱體
 
  }
 }
 
 //初始化白色燈
 private void initLight(GL10 gl)
 {
  gl.glEnable(GL10.GL_LIGHTING);//允許光照
  gl.glEnable(GL10.GL_LIGHT1);//打開1號燈
 
  //環境光設置
  float[] ambientParams={0.2f,0.2f,0.2f,1.0f};//光參數 RGBA
  gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT, ambientParams,0);
 
  //散射光設置
  float[] diffuseParams={1f,1f,1f,1.0f};//光參數 RGBA
  gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, diffuseParams,0);
 
  //反射光設置
  float[] specularParams={1f,1f,1f,1.0f};//光參數 RGBA
  gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_SPECULAR, specularParams,0);
 }
 
 //關閉燈
 private void closeLight(GL10 gl)
 {
  gl.glDisable(GL10.GL_LIGHT1);
  gl.glDisable(GL10.GL_LIGHTING);
 }
 
 //初始化材質
 private void initMaterial(GL10 gl)
 {
  //環境光
  float ambientMaterial[] = {248f/255f, 242f/255f, 144f/255f, 1.0f};
  gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, ambientMaterial,0);
  //散射光
  float diffuseMaterial[] = {248f/255f, 242f/255f, 144f/255f, 1.0f};
  gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, diffuseMaterial,0);
  //高光材質
  float specularMaterial[] = {248f/255f, 242f/255f, 144f/255f, 1.0f};
  gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_SPECULAR, specularMaterial,0);
  gl.glMaterialf(GL10.GL_FRONT_AND_BACK, GL10.GL_SHININESS, 100.0f);
 }
 
 //初始化紋理
 public int initTexture(GL10 gl,int drawableId)//textureId
 {
  //生成紋理ID
  int[] textures = new int[1];
  gl.glGenTextures(1, textures, 0);
  int currTextureId=textures[0];
  gl.glBindTexture(GL10.GL_TEXTURE_2D, currTextureId);
  gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR_MIPMAP_NEAREST);
  gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR_MIPMAP_LINEAR);
  ((GL11)gl).glTexParameterf(GL10.GL_TEXTURE_2D, GL11.GL_GENERATE_MIPMAP, GL10.GL_TRUE);
  gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,GL10.GL_REPEAT);
  gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,GL10.GL_REPEAT);
 
 
 
  InputStream is = this.getResources().openRawResource(drawableId);
  Bitmap bitmapTmp;
  try
  {
   bitmapTmp = BitmapFactory.decodeStream(is);
  }
  finally
  {
   try
   {
    is.close();
   }
   catch(IOException e)
   {
    e.printStackTrace();
   }
  }
  GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmapTmp, 0);
  bitmapTmp.recycle();
 
  return currTextureId;
 }
}

編寫zgyCH.java

     *設置圓柱體的控制屬性,主要包括紋理、高度、截面半徑、截面角度切分單位和高度切分單位,這些屬性用于控制圓柱體的大小
     *定義各個圓柱體繪制類的三角形繪制方法和工具方法
     *實現圓柱體的線性會執法,線性會執法和三角形會執法頂點的獲取方法相同,只是采用的繪制頂點順序和渲染方法不同,并且先行繪制沒有光照和紋理貼圖

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
package com.scout.eeeeeee;
 
/**
 * Created by liuguodong on 2017/10/29.
 */
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
 
import javax.microedition.khronos.opengles.GL10;
 
public class zhuCH
{
 private FloatBuffer dingBuffer;//頂點坐標緩沖
 private FloatBuffer myNormalBuffer;//向量緩沖
 private FloatBuffer myTexture;//紋理緩沖
 
 int textureId;
 
 int vCount;//頂點數量
 
 float length;//圓柱長度
 float circle_radius;//圓截環半徑
 float degreespan; //圓截環每一份的度數大小
 
 public float mAngleX;
 public float mAngleY;
 public float mAngleZ;
 
 public zhuCH(float length,float circle_radius,float degreespan,int textureId)
 {
  this.circle_radius=circle_radius;
  this.length=length;
  this.degreespan=degreespan;
  this.textureId=textureId;
 
  float collength=(float)length;//圓柱每塊所占的長度
  int spannum=(int)(360.0f/degreespan);
 
  ArrayList<Float> val=new ArrayList<Float>();//頂點存放列表
  ArrayList<Float> ial=new ArrayList<Float>();//法向量存放列表
 
  for(float circle_degree=180.0f;circle_degree>0.0f;circle_degree-=degreespan)//循環行
  {
   float x1 =(float)(-length/2);
   float y1=(float) (circle_radius*Math.sin(Math.toRadians(circle_degree)));
   float z1=(float) (circle_radius*Math.cos(Math.toRadians(circle_degree)));
 
   float a1=0;
   float b1=y1;
   float c1=z1;
   float l1=getVectorLength(a1, b1, c1);//模長
   a1=a1/l1;//法向量規格化
   b1=b1/l1;
   c1=c1/l1;
 
   float x2 =(float)(-length/2);
   float y2=(float) (circle_radius*Math.sin(Math.toRadians(circle_degree-degreespan)));
   float z2=(float) (circle_radius*Math.cos(Math.toRadians(circle_degree-degreespan)));
 
   float a2=0;
   float b2=y2;
   float c2=z2;
   float l2=getVectorLength(a2, b2, c2);//模長
   a2=a2/l2;//法向量規格化
   b2=b2/l2;
   c2=c2/l2;
 
   float x3 =(float)(length/2);
   float y3=(float) (circle_radius*Math.sin(Math.toRadians(circle_degree-degreespan)));
   float z3=(float) (circle_radius*Math.cos(Math.toRadians(circle_degree-degreespan)));
 
   float a3=0;
   float b3=y3;
   float c3=z3;
   float l3=getVectorLength(a3, b3, c3);//模長
   a3=a3/l3;//法向量規格化
   b3=b3/l3;
   c3=c3/l3;
 
   float x4 =(float)(length/2);
   float y4=(float) (circle_radius*Math.sin(Math.toRadians(circle_degree)));
   float z4=(float) (circle_radius*Math.cos(Math.toRadians(circle_degree)));
 
   float a4=0;
   float b4=y4;
   float c4=z4;
   float l4=getVectorLength(a4, b4, c4);//模長
   a4=a4/l4;//法向量規格化
   b4=b4/l4;
   c4=c4/l4;
 
   val.add(x1);val.add(y1);val.add(z1);//兩個三角形,共6個頂點的坐標
   val.add(x2);val.add(y2);val.add(z2);
   val.add(x4);val.add(y4);val.add(z4);
 
   val.add(x2);val.add(y2);val.add(z2);
   val.add(x3);val.add(y3);val.add(z3);
   val.add(x4);val.add(y4);val.add(z4);
 
   ial.add(a1);ial.add(b1);ial.add(c1);//頂點對應的法向量
   ial.add(a2);ial.add(b2);ial.add(c2);
   ial.add(a4);ial.add(b4);ial.add(c4);
 
   ial.add(a2);ial.add(b2);ial.add(c2);
   ial.add(a3);ial.add(b3);ial.add(c3);
   ial.add(a4);ial.add(b4);ial.add(c4);
  }
 
  vCount=val.size()/3;//確定頂點數量
 
  //頂點
  float[] vertexs=new float[vCount*3];
  for(int i=0;i<vCount*3;i++)
  {
   vertexs[i]=val.get(i);
  }
  ByteBuffer vbb=ByteBuffer.allocateDirect(vertexs.length*4);
  vbb.order(ByteOrder.nativeOrder());
  dingBuffer=vbb.asFloatBuffer();
  dingBuffer.put(vertexs);
  dingBuffer.position(0);
 
  //法向量
  float[] normals=new float[vCount*3];
  for(int i=0;i<vCount*3;i++)
  {
   normals[i]=ial.get(i);
  }
  ByteBuffer ibb=ByteBuffer.allocateDirect(normals.length*4);
  ibb.order(ByteOrder.nativeOrder());
  myNormalBuffer=ibb.asFloatBuffer();
  myNormalBuffer.put(normals);
  myNormalBuffer.position(0);
 
  //紋理
  float[] textures=generateTexCoor(spannum);
  ByteBuffer tbb=ByteBuffer.allocateDirect(textures.length*4);
  tbb.order(ByteOrder.nativeOrder());
  myTexture=tbb.asFloatBuffer();
  myTexture.put(textures);
  myTexture.position(0);
 }
 
 public void drawSelf(GL10 gl)
 {
  gl.glRotatef(mAngleX, 1, 0, 0);//旋轉
  gl.glRotatef(mAngleY, 0, 1, 0);
  gl.glRotatef(mAngleZ, 0, 0, 1);
 
  gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//打開頂點緩沖
  gl.glVertexPointer(3, GL10.GL_FLOAT, 0, dingBuffer);//指定頂點緩沖
 
  gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);//打開法向量緩沖
  gl.glNormalPointer(GL10.GL_FLOAT, 0, myNormalBuffer);//指定法向量緩沖
 
  gl.glEnable(GL10.GL_TEXTURE_2D);
  gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
  gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, myTexture);
  gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
 
  gl.glDrawArrays(GL10.GL_TRIANGLES, 0, vCount);//繪制圖像
 
  gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);//關閉緩沖
  gl.glEnable(GL10.GL_TEXTURE_2D);
  gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
  gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
 }
 
 //法向量規格化,求模長度
 public float getVectorLength(float x,float y,float z)
 {
  float pingfang=x*x+y*y+z*z;
  float length=(float) Math.sqrt(pingfang);
  return length;
 }
 
 //自動切分紋理產生紋理數組的方法
 public float[] generateTexCoor(int bh)
 {
  float[] result=new float[bh*6*2];
  float REPEAT=2;
  float sizeh=1.0f/bh;//行數
  int c=0;
  for(int i=0;i<bh;i++)
  {
   //每行列一個矩形,由兩個三角形構成,共六個點,12個紋理坐標
   float t=i*sizeh;
 
   result[c++]=0;
   result[c++]=t;
 
   result[c++]=0;
   result[c++]=t+sizeh;
 
   result[c++]=REPEAT;
   result[c++]=t;
 
   result[c++]=0;
   result[c++]=t+sizeh;
 
   result[c++]=REPEAT;
   result[c++]=t+sizeh;
 
   result[c++]=REPEAT;
   result[c++]=t;
  }
  return result;
 }
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://blog.csdn.net/liu3364575/article/details/78384170

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产videos hd| 华人在线京东热 | 国内免费高清视频在线观看 | 亚洲成人精品久久 | 国产色司机在线视频免费观看 | 天若有情1992国语版完整版 | 国产一级在线免费观看 | 国产精品主播在线 | 精品成人网 | 特大黑人娇小亚洲女mp4 | 春意影院午夜爽爽爽免费 | 午夜爽喷水无码成人18禁三级 | 国产在线精品香蕉综合网一区 | 32d乳白色的奶罩未删除 | 日本五级床片全都免费播放 | 9420高清视频在线观看网百度 | 韩剧在线观看 | 干处女| 天天综合色天天综合色sb | 99久久99久久久精品齐齐鬼色 | 亚洲精品AV无码喷奶水糖心 | 精品一区二区三区在线成人 | 201天天爱天天做 | 暖暖暖免费观看在线观看 | a∨79成人网 | 火影忍者小南裸羞羞漫画 | 3d动漫美女被吸乳羞羞有 | 韩国女主播在线大尺无遮挡 | 国产欧美又粗又猛又爽老 | 日韩欧美综合在线二区三区 | 国产欧美视频高清va在线观看 | 1919gogo女厕盗摄 | 国产91青青成人a在线 | 15同性同志18 | 169pp美女| 息与子中文字幕bd | 鞋奴的视频VK | 女女性恋爱视频入口 | 91中文在线| 亚洲 综合 欧美在线 热 | 乌克兰粉嫩摘花第一次 |