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-r9d\samples\hello-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


二、框架介绍

src\com\android\gljni\GLJNIActivity.java     显示界面

src\com\android\gljni\GLJNILib.java           JNI库

src\com\android\gljni\GLJNIView.java   Opengl ES View  

\jni\Android.mk                                            NDK编译文件   

\jni\gl_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\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);	

	// 设置深度缓存	
	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)  


转载于:https://www.cnblogs.com/SunkingYang/p/11049185.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值