图解-安卓中调用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是用来 ...
随机推荐
- (最小生成树)Constructing Roads -- poj -- 2421
链接: http://poj.org/problem?id=2421 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 2113 ...
- follow me
IM InfoSphere Information Server for Data Integration Fundamentals Bootcamp 7月15日 5 北京 IM InfoSphere ...
- Spring 注入集合类型
定义了一个类: @Service public class StringTest implements CachedRowSet,SortedSet<String>,Cloneable @ ...
- SoapUI5.1.2安装和破解教程
一.SoapUI简介 soapui提供一个工具通过soap/http来检查,调用,实现web service和web service的功能/负载/符合性测试. 该工具既可作为一个桌面应用软件使用,也可 ...
- Mono For Android 之 配置环境
下载 Xamarin Mono For Android 4.6.07004 完整离线破解版 (包括除 Android SDK 外的所有文件) Android SDK. 资源源自 http://www. ...
- c# list修改某一个属性的值
public class info() { public string name{get;set;} public string age{get;set;} } list<info> li ...
- C# 基础篇
全篇依据 C#高级编程(第9版) 内容记录: 基础知识C# 5.0 基础 分为15章内容来介绍 核心C# 对象和类型 继承 泛型 数组 运算符和类型强制转换 委托和lambda表达式,事件 字符串和正 ...
- sqlServer存储过程与sql语句的区别
sqlServer 存储过程与sql语句的区别 sql存储过程与sql语句的区别: 从以下几个方面考虑: 1.编写: 存储过程:编写比较难: sql语句:相对简单: 2.性能: 存储过程:高,可移 ...
- KEUC首次落地中国,网易云深度剖析Kubernetes优化与实践
本文由 网易云发布. 10 月 15 日,聚焦 Kubernetes 中国行业应用与技术落地的首届中国 Kubernetes 用户大会(KEUC)在杭州成功举办.本次大会吸引了来自全球各地的技术精英 ...
- Day 42 协程. IO 并发
一.什么是协程? 是单线程下的并发,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的. 协程相比于线程切换效率更快了. ...