图解-安卓中调用OpenGL
游戏开发中经常使用到OpenGL,当然很多人都喜欢直接用现有的游戏引擎,但相信了解的更多对你没有坏处
安卓开发中,采用的OpenGL ex2的规范,前几天看了下这个规范,整体上难度比1.0规范难度加大了很多。
全面采用shader进行开发,不在是以前的固定管线方式了。是个很大的提升,估计在速度上也会有很大的提升。
(本人还没有亲自做这个实验,到底快多少)但是难度却是比之前大了很多,你至少要自己编写shader代码,对
数学有很大的要求了,废话不多说,进入正题。
首先建立一个andriod的项目,这个过程在前两篇中都有介绍,不知道了,可以看下(安卓环境搭建)或者
图解安卓-c++开发-通过java 调用c++ jni的使用 这两篇文章。

到NDK的目录下 C:\andriod\android-ndk-r9b\samples\hello-gl2\src\com\android\gl2jni ,将GL2JNILib.java GL2JNIView.java加入到刚刚建立的工程中,可以直接通过
鼠标拖到工程中。
修改如下程序:
package com.example.gldemo;
// Wrapper for native library public class GL2JNILib { static {
System.loadLibrary("gl2jni");
} /**
* @param width the current view width
* @param height the current view height
*/
public static native void init(int width, int height);
public static native void step();
}
修改 GL2JNIView.java中的代码:红色部分
/*
* Copyright (C) 2009 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.
*/ package com.example.gldemo;
/*
* Copyright (C) 2008 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.
*/ import android.content.Context;
然后在MainActivity.java中增加调用程序:
package com.example.gldemo; import android.os.Bundle;
import android.app.Activity;
import android.view.Menu; public class MainActivity extends Activity { GL2JNIView mView; @Override protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
mView = new GL2JNIView(getApplication());
setContentView(mView);
} @Override protected void onPause() {
super.onPause();
mView.onPause();
} @Override protected void onResume() {
super.onResume();
mView.onResume();
} }
到目前为止,java的部分就做完了。‘
然后增加对Jni的支持,调用OpenGL的代码,JNI部分可以参考 [置顶]图解安卓-c++开发-通过java 调用c++ jni的使用

在Andriod.mak中增加库支持:LOCAL_LDLIBS := -llog -lGLESv2

c++ 代码如下:
/*
* Copyright (C) 2009 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.
*/ // OpenGL ES 2.0 code #include <jni.h>
#include <android/log.h> #include <GLES2/gl2.h>
#include <GLES2/gl2ext.h> #include <stdio.h>
#include <stdlib.h>
#include <math.h> #define LOG_TAG "libgl2jni"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) 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);
}
} static const char gVertexShader[] =
"attribute vec4 vPosition;\n"
"void main() {\n"
" gl_Position = vPosition;\n"
"}\n"; static const char gFragmentShader[] =
"precision mediump float;\n"
"void main() {\n"
" gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
"}\n"; GLuint loadShader(GLenum shaderType, const char* pSource) {
GLuint shader = glCreateShader(shaderType);
if (shader) {
glShaderSource(shader, , &pSource, NULL);
glCompileShader(shader);
GLint compiled = ;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if (!compiled) {
GLint infoLen = ;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen) {
char* buf = (char*) malloc(infoLen);
if (buf) {
glGetShaderInfoLog(shader, infoLen, NULL, buf);
LOGE("Could not compile shader %d:\n%s\n",
shaderType, buf);
free(buf);
}
glDeleteShader(shader);
shader = ;
}
}
}
return shader;
} GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
if (!vertexShader) {
return ;
} GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
if (!pixelShader) {
return ;
} GLuint program = glCreateProgram();
if (program) {
glAttachShader(program, vertexShader);
checkGlError("glAttachShader");
glAttachShader(program, pixelShader);
checkGlError("glAttachShader");
glLinkProgram(program);
GLint linkStatus = GL_FALSE;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
if (linkStatus != GL_TRUE) {
GLint bufLength = ;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
if (bufLength) {
char* buf = (char*) malloc(bufLength);
if (buf) {
glGetProgramInfoLog(program, bufLength, NULL, buf);
free(buf);
}
}
glDeleteProgram(program);
program = ;
}
}
return program;
} GLuint gProgram;
GLuint gvPositionHandle; bool setupGraphics(int w, int h) {
printGLString("Version", GL_VERSION);
printGLString("Vendor", GL_VENDOR);
printGLString("Renderer", GL_RENDERER);
printGLString("Extensions", GL_EXTENSIONS); LOGI("setupGraphics(%d, %d)", w, h);
gProgram = createProgram(gVertexShader, gFragmentShader);
if (!gProgram) {
LOGE("Could not create program.");
return false;
}
gvPositionHandle = glGetAttribLocation(gProgram, "vPosition");
checkGlError("glGetAttribLocation");
LOGI("glGetAttribLocation(\"vPosition\") = %d\n",
gvPositionHandle); glViewport(, , w, h);
checkGlError("glViewport");
return true;
} const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f,
0.5f, -0.5f }; void renderFrame() {
static float grey;
grey += 0.01f;
if (grey > 1.0f) {
grey = 0.0f;
}
glClearColor(grey, grey, grey, 1.0f);
checkGlError("glClearColor");
glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
checkGlError("glClear"); glUseProgram(gProgram);
checkGlError("glUseProgram"); glVertexAttribPointer(gvPositionHandle, , GL_FLOAT, GL_FALSE, , gTriangleVertices);
checkGlError("glVertexAttribPointer");
glEnableVertexAttribArray(gvPositionHandle);
checkGlError("glEnableVertexAttribArray");
glDrawArrays(GL_TRIANGLES, , );
checkGlError("glDrawArrays");
} extern "C" {
JNIEXPORT void JNICALL Java_com_example_gldemo_GL2JNILib_init(JNIEnv * env, jobject obj, jint width, jint height);
JNIEXPORT void JNICALL Java_com_example_gldemo_GL2JNILib_step(JNIEnv * env, jobject obj);
}; JNIEXPORT void JNICALL Java_com_example_gldemo_GL2JNILib_init(JNIEnv * env, jobject obj, jint width, jint height)
{
setupGraphics(width, height);
} JNIEXPORT void JNICALL Java_com_example_gldemo_GL2JNILib_step(JNIEnv * env, jobject obj)
{
renderFrame();
}
编译运行效果如下所示:

完成 。
图解-安卓中调用OpenGL的更多相关文章
- [转]用多线程方法实现在MFC/WIN32中调用OpenGL函数并创建OpenGL窗口
原文链接: 1.用多线程方法实现在MFC/WIN32中调用OpenGL函数并创建OpenGL窗口 2.Windows MFC 两个OpenGL窗口显示与线程RC问题
- Eclipse中通过Android模拟器调用OpenGL ES2.0函数操作步骤
原文地址: Eclipse中通过Android模拟器调用OpenGL ES2.0函数操作步骤 - 网络资源是无限的 - 博客频道 - CSDN.NET http://blog.csdn.net/fen ...
- Unity调用安卓中的方法遇到的问题
最近在用U3D做一个简单的迷宫游戏,在项目中利用Unity制作游戏场景,在android中调用游戏场景,并在游戏结束后调用安卓方法,传递参数,退出游戏场景 查找网上资料,基本上Unity调用安卓的写法 ...
- js中如果遇到低版本安卓设备调用setTimeout不生效解决办法
工作中会遇到低版本安卓设备调用setTimeout不生效,既不会报错,里面的函数也不会执行,这里po一个解决办法,如果不执行则执行安卓自己封装的原生的setTimeout方法:sdk.setTimeo ...
- OpenGL在图形管道中调用了什么用户模式图形驱动程序(UMD)?
OpenGL在图形管道中调用了什么用户模式图形驱动程序(UMD)? 图形硬件供应商,需要为显示适配器编,编写用户模式显示驱动程序.用户模式显示驱动程序,是由Microsoft Direct3D运行时加 ...
- 图解安卓-c++开发-通过java 调用c++ jni的使用
接着上一节 ,很多事情用java做,效率要差一点(尤其是游戏),所以要用c++来实现,那么java如何调用c++ 首先建议一个工程 HelloJni如下图: 按照默认的配置下一步,直到完成 . 如下图 ...
- 安卓中的Model-View-Presenter模式介绍
转载自:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0425/2782.html 英文原文:Introduction to M ...
- android ndk调用OpenGL 实现纹理贴图Texture
android ndk调用OpenGL 实现纹理贴图Texture 时间 2014-06-25 05:24:39 CSDN博客 原文 http://blog.csdn.net/chrisfxs/a ...
- 安卓中AIDL的使用方法快速入门
1.AIDL是什么? AIDL全称是Android Interface Definition Language,即安卓接口定义语言. 2.AIDL是用来做什么的?(为什么要有AIDL) AIDL是用来 ...
随机推荐
- Last Defence (2014 西安现场赛)
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=94237#problem/K Last Defence Time Limit:3000MS ...
- PAT甲 1007. Maximum Subsequence Sum (25) 2016-09-09 22:56 41人阅读 评论(0) 收藏
1007. Maximum Subsequence Sum (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Y ...
- Intellij IDEA 14的注册机(Java版)
import java.math.BigInteger; import java.util.Date; import java.util.Random; import java.util.zip.CR ...
- 用注册表禁止windows添加新用户
运行 regedt32.exe 打开你的注册表,里面有一个目录树:打开其中目录 HKEY_LOCAL_MACHINE再打开其中目录 SAM再打开其中目录 SAM再打开其中目录 Domains再打开其中 ...
- ASP.NET下使用Combres对JS、CSS合并和压缩
记录一下,如何简单快捷压缩js和css,通过合并来减少请求次数. 用到的网址: http://www.nuget.org/packages/combres/ https://github.com/bu ...
- C# 委托和事件,简单示例说明问题
先看看示例效果 按照国际惯例,得先说说概念. 委托(C# 编程指南) 事件(C# 编程指南) 以上内容来自MSDN. 委托源码 [委托] 概念和代码都有了.剩下的就是应用了,要是只知道概念不会用,那还 ...
- pageadmin CMS网站制作教程:
pageadmin CMS网站建设教程:模板中如何实现信息数据共享 很多时候信息数据需要共享,一个最常用的应用场景就是手机版(独立手机,非响应式)本共享pc版本数据,下面以这个场景为例讲解. 假设手机 ...
- 检查网卡是否支持 SR-IOV
[root@node1 ~]# lspci -nn | grep Eth 08:00.0 Ethernet controller [0200]: Intel Corporation I350 Giga ...
- jzoj5996
我們可以枚舉每一個串的最短回文後綴,這樣一定不會算重. 雖然一個字符串可能會有多個回文後綴,但是答案只會在最短的後綴被計算 記f[i]表示長度為i回文串中,沒有長度>1的回文後綴的個數,將總個數 ...
- Spring配置项<context:annotation-config>的解释说明
今天在闲逛CSDN论坛时,看到一位博主写的一篇关于<Spring中IOC的Annotation的实现>的文章, 于是点击进去看了下, 发现在说明中对Spring配置文件中的有些配置节点模凌 ...