zoukankan      html  css  js  c++  java
  • Opengl ES 1.x NDK实例开发之一:搭建开发框架

    转自:http://blog.csdn.net/mnorst/article/details/39578909

    大家好,我是无敌兔,从这一章开始讲在Android上进行Opengl ES 1.x的NDK开发实例,首先对这套开发实例教程的背景做一下说明。

    Android SDK 提供了一套 OpenGL ES 接口,但该接口是基于 Java 的,速度非常慢,往往很难满足需要,所以采用NDK进行开发,底层的实现全部采用C++来编写。

    该实例教程的java框架采用了Android NDK源码中的android-ndk-r9dsampleshello-gl2,开发实例的编写采用了《Nehe的OpenGL中文教程》中的例子。本实例教程重在演示如何在NDK框架下进行Opengl ES的编程,关于实例的原理大家可以参考《Nehe的OpenGL中文教程》,本教程中的实例基本上在《Nehe的OpenGL中文教程》中可以找到相应的解释。

    《Nehe的OpenGL中文教程》的在线地址:Nehe的OpenGL中文教程


    一、开发环境

    Eclipse 3.7.1

    android-sdk_r23.0.0-windows

    android-ndk-r9d

    cygwin 1.7.9


    二、框架介绍

    srccomandroidgljniGLJNIActivity.java     显示界面

    srccomandroidgljniGLJNILib.java           JNI库

    srccomandroidgljniGLJNIView.java   Opengl ES View  

    jniAndroid.mk                                            NDK编译文件   

    jnigl_code.cpp                                           JNI实现代码


    三、实例介绍




    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: mnorst@foxmail.com
     */
    
    package com.android.gljni;
    
    import com.android.gljni.GLJNIView;
    
    import android.app.Activity;
    import android.os.Bundle;
    
    public class GLJNIActivity extends Activity {
    	GLJNIView mView;
    
    	@Override
    	protected void onCreate(Bundle icicle) {
    		super.onCreate(icicle);
    		mView = new GLJNIView(getApplication());
    		setContentView(mView);
    	}
    
    	@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: mnorst@foxmail.com
     */
    
    package com.android.gljni;
    
    import javax.microedition.khronos.egl.EGLConfig;
    import javax.microedition.khronos.opengles.GL10;
    
    import com.android.gljni.GLJNILib;
    
    import android.content.Context;
    import android.opengl.GLSurfaceView;
    
    /**
     * 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会对fps产生影响
    		setEGLConfigChooser(8, 8, 8, 8, 16, 0);
    
    		renderer = new Renderer(context);
    		setRenderer(renderer);
    	}
    
    	private static class Renderer implements GLSurfaceView.Renderer {
    
    		public Renderer(Context ctx) {
    
    		}
    
    		public void onDrawFrame(GL10 gl) {
    			GLJNILib.step();
    		}
    
    		public void onSurfaceChanged(GL10 gl, int width, int height) {
    			GLJNILib.resize(width, height);
    		}
    
    		public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    			GLJNILib.init();
    		}
    	}
    
    }
    

    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: mnorst@foxmail.com
     */
    
    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); 
    	
        public static native void step();  
        
        public static native void init();  
    }

    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: 	mnorst@foxmail.com
     * created:	2014/09/26
     * purpose:	搭建Opengl es 1.x NDK 开发框架
     */
    
    // 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__)
    
    // 定义π
    const GLfloat PI = 3.1415f;
    
    // 顶点数组
    const GLfloat gVertices[] = {
    	0.0f, 1.0f, 0.0f,
    	-1.0f,-1.0f, 1.0f,
    	1.0f,-1.0f, 1.0f,
    };
    
    /************************************************************************/
    /*                             C++代码                                  */
    /************************************************************************/
    
    static void printGLString(const char *name, GLenum s) {
    	const char *v = (const char *) glGetString(s);
    	LOGI("GL %s = %s
    ", name, v);
    }
    
    static void checkGlError(const char* op) {
    	for (GLint error = glGetError(); error; error
    		= glGetError()) {
    			LOGI("after %s() glError (0x%x)
    ", 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);	
    
    	// 设置深度缓存	
    	glClearDepthf(1.0f);
    
    	// 启用深度测试
    	glEnable(GL_DEPTH_TEST);	
    
    	// 所作深度测试的类型	
    	glDepthFunc(GL_LEQUAL);	
    
    	// 告诉系统对透视进行修正	
    	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;
    	}
    
    	// 重置当前的视口
    	glViewport(0, 0, width, height);	
    	// 选择投影矩阵	
    	glMatrixMode(GL_PROJECTION);	
    	// 重置投影矩阵	
    	glLoadIdentity();							
    
    	GLfloat ratio = (GLfloat)width/(GLfloat)height;
    
    	// 设置视口的大小
    	_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);  
    	// 设置背景颜色为黑色
    	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    	// 重置当前的模型观察矩阵
    	glLoadIdentity();	
    	// 移入屏幕 6.0
    	glTranslatef(0.0f,0.0f,-6.0f);		
    
    	// 启用顶点数组
    	glEnableClientState(GL_VERTEX_ARRAY);
    
    	// 绘制三角形,图形的颜色默认为白色
    	glVertexPointer(3, GL_FLOAT, 0, gVertices);
    	glDrawArrays(GL_TRIANGLES, 0, 3);
    
    	// 关闭顶点数组
    	glDisableClientState(GL_VERTEX_ARRAY);
    }
    
    /************************************************************************/
    /*                          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_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();
    }
    

    Android.mk

    LOCAL_PATH:= $(call my-dir)  
      
    include $(CLEAR_VARS)  
      
    LOCAL_MODULE    := libgljni  
    LOCAL_CFLAGS    := -Werror
    LOCAL_SRC_FILES := gl_code.cpp  
    LOCAL_LDLIBS    := -llog -lGLESv1_CM  
      
    include $(BUILD_SHARED_LIBRARY)  


  • 相关阅读:
    [luoguU48834][count]
    [ZROJ110][假如战争今天爆发]
    [luogu4860][Roy&October之取石子II]
    [luogu4018][Roy&October之取石子]
    [luoguU48574][藏妹子之处]
    [20181025晚][模拟赛]
    [20181025上午][模拟赛]
    ElasticSearch业务逻辑案例
    ElasticSearch安装及使用
    面试必问:ACID/CAP
  • 原文地址:https://www.cnblogs.com/SunkingYang/p/11049185.html
Copyright © 2011-2022 走看看