知識(shí)
不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價(jià)值,我們?cè)谧非笃湟曈X(jué)表現(xiàn)的同時(shí),更側(cè)重于功能的便捷,營(yíng)銷(xiāo)的便利,運(yùn)營(yíng)的高效,讓網(wǎng)站成為營(yíng)銷(xiāo)工具,讓軟件能切實(shí)提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序?yàn)楹笃谏?jí)提供便捷的支持!
OpenglES1.xNDK實(shí)例開(kāi)發(fā)之八:旋轉(zhuǎn)的紋理金字塔
發(fā)表時(shí)間:2020-11-21
發(fā)布人:葵宇科技
瀏覽次數(shù):63
開(kāi)發(fā)框架介紹請(qǐng)參見(jiàn):Opengl ES NDK實(shí)例開(kāi)發(fā)之一:搭建開(kāi)發(fā)框架
本章在第六章(Opengl ES 1.x NDK實(shí)例開(kāi)發(fā)之六:紋理貼圖)的基礎(chǔ)上繪制一個(gè)旋轉(zhuǎn)的紋理金字塔,原理和紋理貼圖一樣,需要注意的是定好金字塔的頂點(diǎn)數(shù)組和紋理數(shù)組。
【實(shí)例講解】
[img]http://img.blog.csdn.net/20150107114535933?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbW5vcnN0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
【實(shí)例源碼】
[GLJNIActivity.java]
/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * author: [email protected] */ package com.android.gljni; import java.text.DecimalFormat; import com.android.gljni.GLJNIView; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.ViewGroup.LayoutParams; import android.widget.TextView; public class GLJNIActivity extends Activity { GLJNIView mView; TextView mTextView; @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); mView = new GLJNIView(getApplication()); setContentView(mView); mView.setHandler(new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); // ???fps mTextView.setText("fps:"+msg.what); } } ); mTextView = new TextView(this); mTextView.setText("fps:0"); addContentView(mTextView, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); } @Override protected void onPause() { super.onPause(); mView.onPause(); } @Override protected void onResume() { super.onResume(); mView.onResume(); } }
[GLJNIView.java]
/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * author: [email protected] */ package com.android.gljni; import java.io.IOException; import java.io.InputStream; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import com.android.gljni.GLJNILib; import com.android.gljnidemo08.R; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.opengl.GLSurfaceView; import android.opengl.GLUtils; import android.os.Handler; import android.util.Log; /** * A simple GLSurfaceView sub-class that demonstrate how to perform * OpenGL ES 1.x rendering into a GL Surface. */ public class GLJNIView extends GLSurfaceView { private static final String LOG_TAG = GLJNIView.class.getSimpleName(); private Renderer renderer; public GLJNIView(Context context) { super(context); // setEGLConfigChooser會(huì)對(duì)fps產(chǎn)生影響 setEGLConfigChooser(8, 8, 8, 8, 16, 0); renderer = new Renderer(context); setRenderer(renderer); } public void setHandler( Handler handler){ renderer.setHandler(handler); } private static class Renderer implements GLSurfaceView.Renderer { //用于紋理映射的綁定,并把綁定后的ID傳遞給C++代碼,供其調(diào)用 private int[] mTexture = new int[2]; //用于加載Bitmap的context private Context mContext; // 統(tǒng)計(jì)fps private Handler mHandler; private long mStartMili; private long mEndMili; private int mFps = 0; public Renderer(Context ctx) { mContext = ctx; mStartMili =System.currentTimeMillis(); } public void setHandler( Handler handler){ mHandler = handler; } public void onDrawFrame(GL10 gl) { GLJNILib.step(); // 以一分鐘繪制的幀數(shù)來(lái)統(tǒng)計(jì)fps mEndMili = System.currentTimeMillis(); if( mEndMili - mStartMili > 1000 ){ mHandler.sendEmptyMessageDelayed(mFps, 100); mStartMili = mEndMili; mFps = 0; } mFps++; } public void onSurfaceChanged(GL10 gl, int width, int height) { GLJNILib.resize(width, height); } public void onSurfaceCreated(GL10 gl, EGLConfig config) { //用來(lái)綁定Bitmap紋理 genTexture(gl, mContext); //調(diào)用本地setTexture方法,把紋理綁定的ID傳遞給C++代碼,以供其調(diào)用 GLJNILib.setTexture(mTexture); GLJNILib.init(); } /** * 加載Bitmap的方法, * 用來(lái)從res中加載Bitmap資源 * */ private Bitmap loadBitmap(Context context, int resourceId) { InputStream is = context.getResources().openRawResource(resourceId); Bitmap bitmap = null; try { // 利用BitmapFactory生成Bitmap bitmap = BitmapFactory.decodeStream(is); } finally { try { // 關(guān)閉流 is.close(); is = null; } catch (IOException e) { e.printStackTrace(); } } return bitmap; } /** * 綁定Bitmap紋理 * */ private void genTexture(GL10 gl, Context context) { //生成紋理 gl.glGenTextures(2, mTexture, 0); //加載Bitmap Bitmap bitmap = loadBitmap(context, R.drawable.logo); if (bitmap != null) { //如果bitmap加載成功,則生成此bitmap的紋理映射 gl.glBindTexture(GL10.GL_TEXTURE_2D, mTexture[0]); //設(shè)置紋理映射的屬性 gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST); //生成紋理映射 GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); //釋放bitmap資源 bitmap.recycle(); } } } }
[GLJNILib.java]
/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * author: [email protected] */ package com.android.gljni; //Wrapper for native library public class GLJNILib { static { System.loadLibrary("gljni"); } /** * @param width the current view width * @param height the current view height */ public static native void resize(int width, int height); /** * render */ public static native void step(); /** * init */ public static native void init(); /** * set the texture * @param texture texture id */ public static native void setTexture(int[] texture); }
[gl_code.cpp]
/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * author: [email protected] * created: 2015/01/06 * purpose: 旋轉(zhuǎn)的紋理金字塔 */ // OpenGL ES 1.x code #include <jni.h> #include <android/log.h> #include <GLES/gl.h> #include <GLES/glext.h> #include <stdio.h> #include <stdlib.h> #include <math.h> /************************************************************************/ /* 定義 */ /************************************************************************/ #define LOG_TAG "libgljni" #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) //初始化紋理數(shù)組 GLuint *gTexture = 0; // 定義π const GLfloat PI = 3.1415f; // 定義頂點(diǎn)坐標(biāo) #define pos 1.0f // 定義頂點(diǎn)坐標(biāo) const GLfloat gVertices[] = { // 底面 -1.0f,-1.0f,1.0f, 1.0f,-1.0f,1.0f, 1.0f,-1.0f, -1.0f, 1.0f,-1.0f,-1.0f, -1.0f,-1.0f,-1.0f, -1.0f,-1.0f,1.0f, // 側(cè)面 0.0f, 1.0f, 0.0f, -1.0f,-1.0f, 1.0f, 1.0f,-1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,-1.0f, 1.0f, 1.0f,-1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f,-1.0f, -1.0f, -1.0f,-1.0f, -1.0f, 0.0f, 1.0f, 0.0f, -1.0f,-1.0f,-1.0f, -1.0f,-1.0f, 1.0f }; // 定義紋理坐標(biāo) // 紋理坐標(biāo)原點(diǎn)會(huì)因不同系統(tǒng)環(huán)境而有所不同。 // 比如在iOS以及Android上,紋理坐標(biāo)原點(diǎn)(0, 0)是在左上角 // 而在OS X上,紋理坐標(biāo)的原點(diǎn)是在左下角 static GLfloat texCoords[] = { // 地面拼接成一張整紋理 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, }; // 旋轉(zhuǎn)角度 static GLfloat gAngle = 0.0f; /************************************************************************/ /* C++代碼 */ /************************************************************************/ static void printGLString(const char *name, GLenum s) { const char *v = (const char *) glGetString(s); LOGI("GL %s = %s\n", name, v); } static void checkGlError(const char* op) { for (GLint error = glGetError(); error; error = glGetError()) { LOGI("after %s() glError (0x%x)\n", op, error); } } bool init() { printGLString("Version", GL_VERSION); printGLString("Vendor", GL_VENDOR); printGLString("Renderer", GL_RENDERER); printGLString("Extensions", GL_EXTENSIONS); // 啟用陰影平滑 glShadeModel(GL_SMOOTH); // 黑色背景 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // 設(shè)置深度緩存 glClearDepthf(1.0f); // 啟用深度測(cè)試 glEnable(GL_DEPTH_TEST); // 所作深度測(cè)試的類(lèi)型 glDepthFunc(GL_LEQUAL); // 對(duì)透視進(jìn)行修正 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); return true; } static void _gluPerspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar) { GLfloat top = zNear * ((GLfloat) tan(fovy * PI / 360.0)); GLfloat bottom = -top; GLfloat left = bottom * aspect; GLfloat right = top * aspect; glFrustumf(left, right, bottom, top, zNear, zFar); } void resize(int width, int height) { // 防止被零除 if (height==0) { height=1; } // 重置當(dāng)前的視口 glViewport(0, 0, width, height); // 選擇投影矩陣 glMatrixMode(GL_PROJECTION); // 重置投影矩陣 glLoadIdentity(); // 設(shè)置視口的大小 _gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); // 選擇模型觀察矩陣 glMatrixMode(GL_MODELVIEW); // 重置模型觀察矩陣 glLoadIdentity(); } void renderFrame() { // 清除屏幕和深度緩存 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 重置當(dāng)前的模型觀察矩陣 glLoadIdentity(); glTranslatef(0,0,-10.0f); glRotatef(gAngle, 0, 1.0F, 0); glRotatef(gAngle, 0, 0, 1.0F); // 啟用頂點(diǎn)數(shù)組 glEnableClientState(GL_VERTEX_ARRAY); //glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); // 啟用紋理映射 glEnable(GL_TEXTURE_2D); // 選擇紋理 glBindTexture(GL_TEXTURE_2D, gTexture[0]); glVertexPointer(3,GL_FLOAT,0,gVertices); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); glDrawArrays(GL_TRIANGLES, 0, 18); // 關(guān)閉頂點(diǎn)數(shù)組 glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); //glDisableClientState(GL_OLOR_ARRAY); gAngle += 2.f; } /************************************************************************/ /* JNI代碼 */ /************************************************************************/ extern "C" { JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_resize(JNIEnv * env, jobject obj, jint width, jint height); JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_step(JNIEnv * env, jobject obj); JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_init(JNIEnv * env, jobject obj); JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_setTexture(JNIEnv * env, jclass obj, jintArray tex); }; JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_resize(JNIEnv * env, jobject obj, jint width, jint height) { resize(width, height); } JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_step(JNIEnv * env, jobject obj) { renderFrame(); } JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_init(JNIEnv * env, jobject obj) { init(); } JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_setTexture(JNIEnv * env, jclass obj, jintArray tex) { gTexture = (GLuint *)env->GetIntArrayElements(tex,0); }
相關(guān)案例查看更多
相關(guān)閱讀
- 小程序設(shè)計(jì)
- 小程序表單
- 網(wǎng)站優(yōu)化公司
- 云南網(wǎng)站建設(shè)特性
- 云南網(wǎng)站建設(shè)專(zhuān)家
- 網(wǎng)頁(yè)制作
- 搜索排名
- 云南網(wǎng)站開(kāi)發(fā)哪家好
- 云南網(wǎng)站設(shè)計(jì)
- 分銷(xiāo)系統(tǒng)
- 文山小程序開(kāi)發(fā)
- 云南網(wǎng)站建設(shè)列表網(wǎng)
- 網(wǎng)站小程序
- 網(wǎng)站建設(shè)首選
- 云南小程序哪家好
- 報(bào)廢車(chē)管理系統(tǒng)
- 報(bào)廢車(chē)拆解管理系統(tǒng)
- 小程序退款
- 汽車(chē)報(bào)廢軟件
- 支付寶小程序被騙
- 軟件定制公司
- 云南網(wǎng)站建設(shè)公司
- 小程序密鑰
- 小程序分銷(xiāo)商城
- 貴州小程序開(kāi)發(fā)
- 云南軟件公司
- 軟件定制
- 云南網(wǎng)站建設(shè)服務(wù)公司
- web開(kāi)發(fā)技術(shù)
- 云南網(wǎng)站建設(shè)快速優(yōu)化