android ndk调用OpenGL 实现纹理贴图Texture
android ndk调用OpenGL 实现纹理贴图Texture
首先必须说,国内在OpenGL这方面特别是ndk上的分享太太太少
这中间遇到很多问题,而这些问题需要在书上,在网上,在各种资料上找,而且书上是java层调用,网上的缺少各种文件案例,只有在java层研究,在各种案例中找需要的知识点,遇到问题最终只有google搜外国网站才能解决。
顺便说下,虽然现在google被墙,除了翻墙还有个很简单的办法上google。
http://www.gfsoso.com/
谷粉搜搜
接下来正文
——————————————————————————————
学习ndk应该都是从google配有的案例开始的吧:GL2JNIActivity
这个案例就是一个会变颜色的背景加一个绿色三角形
因为我开始学习纹理贴图,所以打算将三角形换成贴图
首先需要配置纹理
在GL2JNIView.java中修改Renderer类
private static class Renderer implements GLSurfaceView.Renderer {
public void onDrawFrame(GL10 gl) {
GL2JNILib.step();
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
GL2JNILib.init(width, height);
}
private Context mContext;
int textureId;
private int[] TextureString = new int[1];
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
mContext = GL2JNIActivity.getContext();
//Bitmap bitmap = getBitmap(mContext,R.drawable.bac);
Bitmap bitmap = getBitmap(mContext,R.drawable.wall);
if(bitmap != null)
{
Log.e("step", "bing the texture succeed!");
gl.glEnable(GLES20.GL_TEXTURE_2D);
gl.glGenTextures(1, TextureString,0);
textureId= TextureString[0];
Log.e("textureId", String.valueOf(textureId));
gl.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
gl.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
gl.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
gl.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
GLES20.GL_CLAMP_TO_EDGE);
gl.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
GLES20.GL_CLAMP_TO_EDGE);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
GL2JNILib.setTextures(TextureString);
// GL2JNILib.setTextures(textureId);
bitmap.recycle();
}
}
private Bitmap getBitmap(Context context,int resId)
{
//getBitmap by decodeResources()
// BitmapFactory.Options options = new BitmapFactory.Options();
// options.inScaled = false;
// return BitmapFactory.decodeResource(context.getResources(), resId,options);
//getBitmap by decodeStream()
InputStream bitmapStream = null;
bitmapStream = context.getResources().openRawResource(R.drawable.bac);
return BitmapFactory.decodeStream(bitmapStream);
//经验证上面两种方法都可以
}
}
因为这部分之前一直有问题,纹理试过一直闪烁,一直黑色,修改了很多地方,也不确定那些才是导致问题的根本原因,但是我尽可能贴出来,大家也多交流交流:
1.图片格式要是2的倍数*2的倍数,而且有的说不超过1024有点不超过512,做测试还是用256*256的好了。
2.
gl.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
要在
gl.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
gl.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
gl.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
GLES20.GL_CLAMP_TO_EDGE);
gl.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
GLES20.GL_CLAMP_TO_EDGE);
之前
3.
gl.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
GLES20.GL_CLAMP_TO_EDGE);
最后的参数要是
GLES20.GL_CLAMP_TO_EDGE
貌似跟mipmap有关
4.
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
这个一定要放最后
5.
GL2JNILib.setTextures(TextureString);
传给C++层的参数一定要是int数组
接着是c++层的代码
首先是脚本修改
static const char gVertexShader[] =
"attribute vec4 vPosition;\n"
"attribute vec2 vTexCoords;\n"
"varying vec2 colorVarying;\n"
"void main() {\n"
" gl_Position = vPosition;\n"
" colorVarying = vTexCoords;\n"
"}\n"; static const char gFragmentShader[] =
"precision mediump float;\n"
"varying vec2 colorVarying;\n"
"uniform sampler2D sampler;\n"
"void main() {\n"
" //gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
"gl_FragColor = texture2D(sampler,colorVarying);\n"
"}\n";
添加了定点纹理坐标和传递给pixelShader变量
pixelShader添加了接收vertexShader传过来的参数
bool setupGraphics(int w, int h)的修改
GLuint gProgram;
GLuint gvPositionHandle;
GLuint gvTexCoorHandle; 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);
gvTexCoorHandle = glGetAttribLocation(gProgram, "vTexCoords");
checkGlError("glGetAttribLocation");
LOGI("glGetAttribLocation(\"vTexCoords\") = %d\n",
gvTexCoorHandle); glViewport(0, 0, w, h);
checkGlError("glViewport");
return true;
}
添加了
gvTexCoorHandle = glGetAttribLocation(gProgram, "vTexCoords");
获取纹理坐标属性引用id
void renderFrame() 的修改
const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f,
0.5f, -0.5f };
const GLfloat gTexCoor[] = { 0.5f,0, 0,1,
1,1 };
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);
//glClear( GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
checkGlError("glClear");
glUseProgram(gProgram);
checkGlError("glUseProgram");
glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
checkGlError("glVertexAttribPointer");
glVertexAttribPointer(gvTexCoorHandle, 2, GL_FLOAT, GL_FALSE, 0, gTexCoor);
checkGlError("glVertexAttribPointer");
glEnableVertexAttribArray(gvPositionHandle);
checkGlError("glEnableVertexAttribArray");
glEnableVertexAttribArray(gvTexCoorHandle);
checkGlError("glEnableVertexAttribArray");
glActiveTexture(GL_TEXTURE0);
checkGlError("glActiveTexture");
glBindTexture(GL_TEXTURE_2D,mTexture[0]);
checkGlError("glBindTexture");
glDrawArrays(GL_TRIANGLES, 0, 3);
checkGlError("glDrawArrays");
}
添加了纹理坐标的数据,绑定纹理,最后画带有纹理的三角形
添加接收Java层传递过来的纹理id
JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_setTextures(JNIEnv * env, jobject obj,jintArray texture)
{
mTexture = (GLuint *)env->GetIntArrayElements(texture,0);
// m_texture = (unsigned int)env->GetIntArrayElements(texture,0);//it doesnt work!!!!what the fuck dont try this anymore!!!
// const char *v = (const char *) m_texture;
// LOGI("GL %s = %s\n", "m_texture:", v);
// v = (const char *) mTexture;
// LOGI("GL %s = %s\n", "mTexture:", v);
}
这里有个问题就是导致后面黑色纹理的主要原因:
接收Java传过来的id时要用GLuint*类型。这样在上面
<pre name="code" class="cpp"> glBindTexture(GL_TEXTURE_2D,mTexture[0]);
传进去才不会错。
都怪我c++基础不好...
最后希望大家能多点分享,像我这样刚接触OpenGL特别是在ndk上真的太少资料
android ndk调用OpenGL 实现纹理贴图Texture的更多相关文章
- Eclipse中通过Android模拟器调用OpenGL ES2.0函数操作步骤
原文地址: Eclipse中通过Android模拟器调用OpenGL ES2.0函数操作步骤 - 网络资源是无限的 - 博客频道 - CSDN.NET http://blog.csdn.net/fen ...
- Opengl ES 1.x NDK实例开发之六:纹理贴图
开发框架介绍请參见:Opengl ES NDK实例开发之中的一个:搭建开发框架 本章在第三章(Opengl ES 1.x NDK实例开发之三:多边形的旋转)的基础上演示怎样使用纹理贴图,分别实现了三角 ...
- Android OpenGL ES 开发(九): OpenGL ES 纹理贴图
一.概念 一般说来,纹理是表示物体表面的一幅或几幅二维图形,也称纹理贴图(texture).当把纹理按照特定的方式映射到物体表面上的时候,能使物体看上去更加真实.当前流行的图形系统中,纹理绘制已经成为 ...
- OpenGL入门1.4:纹理/贴图Texture
每一个小步骤的源码都放在了Github 的内容为插入注释,可以先跳过 前言 游戏玩家对Texture这个词应该不陌生,我们已经知道了怎么为每个顶点添加颜色来增加图形的细节,但,如果想让图形看起来更真实 ...
- opengl学习笔记(四):openCV读入图片,openGL实现纹理贴图
在opengl中实现三维物体的纹理贴图的第一步就是要读入图片,然后指定该图片为纹理图片. 首先利用opencv的cvLoadImage函数把图像读入到内存中 img = cvLoadImage(); ...
- OpenGL之纹理贴图(Texture)
学习自: https://learnopengl-cn.github.io/01%20Getting%20started/06%20Textures/ 先上一波效果图: 实际上就是:画了一个矩形,然后 ...
- 〖Linux〗Android NDK调用已编译好的C/C++动态连接库(so文件)
一.背景:假定已有应用程序zigbeeclient.cpp,内容如下: ... extern "C" { int getresult(int argc, char **argv); ...
- Android +NDK+eclipse+opengl ES2.0 开启深度測试
參考:https://www.opengl.org/discussion_boards/showthread.php/172736-OpenGL-ES-Depth-Buffer-Problem 环境: ...
- 关于Android NDK中调用第三方的动态库
因为最近在整合Android 上RTSP播放器的网络库,因需要调用自己编译的网络库,调用一直出现问题,开始时是直接在Android.mk 中加入LOCAL_SHARED_LIBRARIES := li ...
随机推荐
- ElasticSearch(8)-分布式搜索
分布式搜索的执行方式 在继续之前,我们将绕道讲一下搜索是如何在分布式环境中执行的. 它比我们之前讲的基础的增删改查(create-read-update-delete ,CRUD)请求要复杂一些. 注 ...
- Oracle 锁模式
0:none 1:null 空 2:Row-S 行共享(RS):共享表锁 3:Row-X 行专用(RX):用于行的修改 4:Share 共享锁(S):阻止其他DML操作 5:S/Row-X ...
- Oracle新建实例后,修改sys和system密码。
sqlplus/nolog connect sys as sysdba alert user sys identified by pwd;
- 面试题-Java基础-垃圾回收
1.Java中垃圾回收有什么目的?什么时候进行垃圾回收? 垃圾回收的目的是识别并且丢弃应用不再使用的对象来释放和重用资源. 2.System.gc()和Runtime.gc()会做什么事情? 这两个方 ...
- HTML5 <meta> 标签属性
基本标签SEO 优化为移动设备添加 viewportWindows 8其他 禁止数字识自动别为电话号码不让android识别邮箱每 8 秒刷新一次页面移动端的头部标签和meta 基本标签 声明文档使用 ...
- springmvc获取jar中的静态资源与jar包中的资源互相引用问题
1.首先看jar中的文件位置 2.在web工程中引用该jar 并且在springmvc文件中配置路径 如果有多个路径可用逗号隔开 3.在web工程找jsp页面如何引用 这样就可以了 关于jar中的资源 ...
- 8、关于viewWithTag
1.viewWithTag检索tag的方法问题viewWithTag方法会对当前View和其子View进行搜索,查找符合tag的对象,但如果view和其多个子view中都含有相同tag值对象时,该方法 ...
- select空间提交form表单传递参数
如下, 到了 <form name="modelForm" action="/portal/defectinfo/toDefectPage?projectname= ...
- gvim窗口根据gnome-terminal位置定位
gvim启动位置固定的话容易挡到东西,所以写了一段vimscript根据gnome-terminal的位置启动gvim,这样被遮住的概率就一些了. fun! g:get_xterm_pos ()&qu ...
- EF Codefirst 初步学习(二)—— 程序管理命令 更新数据库
前提:搭建成功codefirst相关代码,参见EF Codefirst 初步学习(一)--设置codefirst开发模式 具体需要注意点如下: 1.确保实体类库程序生成成功 2.确保实体表类库不缺少 ...