如下程序将一张图片显示到屏幕上。

首先是android jni程序公共头文件:

#include <jni.h>
#include <time.h>
#include <android/log.h>
#include <android/bitmap.h>

用宏来控制是否使用es1.x

//#define USING_ES11

分别包含两种情况下的头文件:

#ifdef USING_ES11
#include <GLES/gl.h>
#include <GLES/glext.h>
#else
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#endif

接着添加一些公共头文件:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

下面是一些通用函数, 主要是一些错误处理函数:

/***********************common function*************************/
#define  LOG_TAG    "libtexture_test.so"
#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 static GLfloat PI = 3.1415f;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);}
}

然后是相关数据定义:

//data
const GLfloat gVertices[] = { -1, -1, 1, -1, -1, 1, 1, 1 };
const GLfloat gTexCoords[] = { 0, 1, 1, 1, 0, 0, 1, 0};

定义纹理ID:

GLuint textureID;

定义es2.0相关的Shader和函数:

#ifndef USING_ES11
static const char gVertexShader[] ="attribute vec4 a_Position;\n""attribute vec2 a_TexCoords; \n""varying vec2 v_TexCoords; \n""void main() {\n""  gl_Position = a_Position;\n"" v_TexCoords = a_TexCoords; \n""}\n";static const char gFragmentShader[] ="precision mediump float;\n""uniform sampler2D u_Texture; \n""varying vec2 v_TexCoords; \n""void main() {\n""  gl_FragColor = texture2D(u_Texture, v_TexCoords);\n""}\n";GLuint loadShader(GLenum shaderType, const char* pSource) {GLuint shader = glCreateShader(shaderType);if (shader) {glShaderSource(shader, 1, &pSource, NULL);glCompileShader(shader);GLint compiled = 0;glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);if (!compiled) {GLint infoLen = 0;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 = 0;}}}return shader;
}GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);if (!vertexShader) {return 0;}GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);if (!pixelShader) {return 0;}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 = 0;glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);if (bufLength) {char* buf = (char*) malloc(bufLength);if (buf) {glGetProgramInfoLog(program, bufLength, NULL, buf);LOGE("Could not link program:\n%s\n", buf);free(buf);}}glDeleteProgram(program);program = 0;}}return program;
}GLuint gProgram;
GLuint gPositionHandle;
GLuint gTexCoordsHandle;
GLuint gTexHandle;#endif

下面是我们的初始化函数:

首先第一部分是加载纹理数据:

static void init(JNIEnv * env, jobject bitmap)
{AndroidBitmapInfo  info;void*  pixels;int format;int ret;if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) {LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);return;}if (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888) {LOGI("Bitmap format is  RGBA_8888 !");format = GL_RGBA;} else if (info.format == ANDROID_BITMAP_FORMAT_RGB_565) {LOGI("Bitmap format is  RGB_565 !");format = GL_RGB;}if ((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) {LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);}glGenTextures(1, &textureID);glBindTexture(GL_TEXTURE_2D, textureID);// Set filteringglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);glTexImage2D(GL_TEXTURE_2D, 0, format, info.width, info.height, 0, format, GL_UNSIGNED_BYTE, pixels);AndroidBitmap_unlockPixels(env, bitmap);

接着是es1.x相关的初始化:

#ifdef USING_ES11glShadeModel(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);          // 告诉系统对透视进行修正
#endif

接下来是es2.0相关始化:

#ifndef USING_ES11gProgram = createProgram(gVertexShader, gFragmentShader);if (!gProgram) {LOGE("Could not create program.");return ;}gPositionHandle = glGetAttribLocation(gProgram, "a_Position");checkGlError("glGetAttribLocation");LOGI("glGetAttribLocation(\"a_Position\") = %d\n",gPositionHandle);gTexCoordsHandle = glGetAttribLocation(gProgram, "a_TexCoords");checkGlError("glGetAttribLocation");LOGI("glGetAttribLocation(\"a_TexCoords\") = %d\n",gTexCoordsHandle);gTexHandle = glGetUniformLocation(gProgram, "u_Texture");checkGlError("glGetUniformLocation");LOGI("glGetUniformLocation(\"u_Texture\") = %d\n",gTexHandle);
#endif}

定义es1.x下的视角设置函数:

#ifdef USING_ES11
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);
}
#endif

接下来定义视口大小:

static void resize(int w, int h)
{if (h==0)                                // 防止被零除{h=1;                          // 将Height设为1}glViewport(0, 0, w, h);                   // 重置当前的视口#if USING_ES11glMatrixMode(GL_PROJECTION);                        // 选择投影矩阵glLoadIdentity();                          // 重置投影矩阵GLfloat ratio = (GLfloat)w/(GLfloat)h;// 设置视口的大小_gluPerspective(45.0f,(GLfloat)w/(GLfloat)h,0.1f,100.0f);//    glOrthof(-2.0f, 2.0f, -2.0f, 2.0f, -2.0f, 2.0f);glMatrixMode(GL_MODELVIEW);                        // 选择模型观察矩阵glLoadIdentity();                            // 重置模型观察矩阵
#endif}

接下来是绘制函数:

static void update()
{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);#ifdef USING_ES11glLoadIdentity();glTranslatef(0, 0, -3.0f);glEnable(GL_TEXTURE_2D);glEnableClientState(GL_VERTEX_ARRAY);glEnableClientState(GL_TEXTURE_COORD_ARRAY);glVertexPointer(2, GL_FLOAT, 0, gVertices);glTexCoordPointer(2, GL_FLOAT, 0, gTexCoords);glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
#elseglUseProgram(gProgram);checkGlError("glUseProgram");glVertexAttribPointer(gPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gVertices);checkGlError("glVertexAttribPointer");glEnableVertexAttribArray(gPositionHandle);checkGlError("glEnableVertexAttribArray");glVertexAttribPointer(gTexCoordsHandle, 2, GL_FLOAT, GL_FALSE, 0, gTexCoords);checkGlError("glVertexAttribPointer");glEnableVertexAttribArray(gTexCoordsHandle);checkGlError("glEnableVertexAttribArray");glActiveTexture(GL_TEXTURE0);glUniform1i(gTexHandle, 0);glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);#endif
}

转载于:https://my.oschina.net/fuyajun1983cn/blog/263859

对比es1.x和es2.0纹理加载方法相关推荐

  1. three.js加载和使用纹理-加载DDS、PVR、TGA格式的纹理(vue中使用three.js73)

    加载DDS.PVR.TGA格式的纹理 1.demo效果 2. 实现要点 2.1 加载DDS格式纹理 2.2 加载PVR格式纹理 2.3 加载TGA格式纹理 3. demo代码 1.demo效果 以上三 ...

  2. 每天学一点flash (20) flash cs3.0 外部加载图片

    今天开始看了一些外部加载图片的,因为as3.0 外部加载已经没有没有了loadMovie类,所以as3.0要转变思想了.可是迷惘的事情特别多,之前看了一些关于容器的那些东西,看不懂.也许我还没有入门吧 ...

  3. VB6.0动态加载ActiveX控件漫谈[转]

    [转帖]VB6.0动态加载ActiveX控件漫谈http://www.7880.com/Info/Article-4b559560.html 熟悉VB的朋友对使用ActiveX控件一定不会陌生,众多控 ...

  4. CSS 3.0实现加载动画

    给大家分享一个用CSS 3.0实现加载动画,效果如下: 以下是代码实现,欢迎大家复制.粘贴和收藏. <!DOCTYPE html> <html lang="en" ...

  5. 未能从程序集“**\Microsoft.Build.Tasks.v12.0.dll”加载任务工厂“CodeTaskFactor”

    1.vs2013 打开项目,运行时碰到报错. error MSB4175: 未能从程序集"C:\Program Files (x86)\MSBuild\12.0\bin\Microsoft. ...

  6. vivo oppo 手机8.1.0 webview加载H5白屏问题

    记录一个webview 的深坑. vivo oppo 手机8.1.0 webview加载H5白屏问题 查看log发现: 神奇的报错 解决办法: 删除掉配置文件里的8.0的新特性适配: 感谢stacko ...

  7. postgresql源码学习(57)—— pg中的四种动态库加载方法

    一. 基础知识 1. 什么是库 库其实就是一些通用代码,可以在程序中重复使用,比如一些数学函数,可以不需要自己编写,直接调用相关函数即可实现,避免重复造轮子. 在linux中,支持两种类型的库: 1. ...

  8. react路由按需加载方法

    使用router4之后以前的按需加载方法require.ensure 是不好使了. 所以我们改用react-loadable插件做按需加载. 第一步: yarn add react-loadable ...

  9. iOS控制器与视图加载方法

    转载记录, 请看原文: 1. iOS中的各种加载方法(initWithNibName,loadNibNamed,initWithCoder,awakeFromNib等等)简单使用   http://w ...

最新文章

  1. Java面向对象之USB接口实例
  2. python操作excel之 模块 xlrd
  3. 收藏本站html,加入收藏代码_加入收藏代码 -收藏本站的代码
  4. ngrok布置外网访问环境
  5. 函数学习-abs()
  6. NSCoding和NSCopy
  7. hdu 3308 线段树
  8. 【CodeForces - 124D】Squares (旋转坐标系,计算几何,思维)
  9. xcode8 快捷键失效
  10. Linux Crontab 安装使用详细说明
  11. android handler3--post源码解析
  12. Java——类的继承
  13. Navicat 创建mysql事件
  14. 华中科技大学2005年计算机组成原理试题,华中科技大学2005年计算机组成原理试题...
  15. jquery focus() 手机端无效
  16. 【笔记】关于OpenCV中的去畸变代码
  17. Mysql 5.6 慢日志配制
  18. UDS协议的项目应用
  19. 一阶广义差分模型_计量经济学第10讲(时间序列计量经济学模型:序列相关性)...
  20. 【转载】参数返回值及NRV优化

热门文章

  1. Linux下php5.3编译oracle客户端
  2. 大数据虚拟化零起点-4基础运维第三步-部署vCenter Server Virtual Appliance 5.1
  3. xenapp 发布到外网更改公网IP。
  4. 祛除雀斑的健康方法 - 健康程序员,至尚生活!
  5. 几款最新的解谜单机小游戏
  6. 使用yeoman搭建脚手架并发布到npm
  7. 2019年六大新兴信息安全方向
  8. hadoop生态搭建(3节点)
  9. Java记录 -1- 基础JDK
  10. nginx和fpm的进程数配置和502,504错误