zoukankan      html  css  js  c++  java
  • android ndk调用OpenGL 实现纹理贴图Texture

    版权声明:本文为博主原创文章,未经博主同意不得转载。

    https://blog.csdn.net/chrisfxs/article/details/34359265

    首先必须说。国内在OpenGL这方面特别是ndk上的分享太太太少


    这中间遇到非常多问题,而这些问题须要在书上。在网上,在各种资料上找。并且书上是java层调用。网上的缺少各种文件案例。仅仅有在java层研究,在各种案例中找须要的知识点,遇到问题终于仅仅有google搜外国站点才干解决。

    顺便说下,尽管如今google被墙,除了翻墙还有个非常easy的办法上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;
    "
    	"attribute vec2 vTexCoords;
    "
    	"varying vec2 colorVarying;
    "
        "void main() {
    "
        "  gl_Position = vPosition;
    "
    	"  colorVarying = vTexCoords;
    "
        "}
    ";
    
    static const char gFragmentShader[] = 
    	"precision mediump float;
    "
    	"varying vec2 colorVarying;
    "
    	"uniform sampler2D sampler;
    "
        "void main() {
    "
        "  //gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
    "
    	"gl_FragColor = texture2D(sampler,colorVarying);
    "
        "}
    ";

    加入了定点纹理坐标和传递给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
    ",
                gvPositionHandle);
        gvTexCoorHandle = glGetAttribLocation(gProgram, "vTexCoords");
        checkGlError("glGetAttribLocation");
        LOGI("glGetAttribLocation("vTexCoords") = %d
    ",
        		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
    ", "m_texture:", v);
    //    v = (const char *) mTexture;
    //    LOGI("GL %s = %s
    ", "mTexture:", v);
    }
    这里有个问题就是导致后面黑色纹理的主要原因:

    接收Java传过来的id时要用GLuint*类型。这样在上面

    <pre name="code" class="cpp"> glBindTexture(GL_TEXTURE_2D,mTexture[0]);

    
    

    传进去才不会错。

    都怪我c++基础不好...

    最后希望大家能多点分享。像我这样刚接触OpenGL特别是在ndk上真的太少资料


    项目下载链接:

    http://download.csdn.net/detail/chrisfxs/7547637


查看全文
  • 相关阅读:
    推荐一款稳定快速免费的前端开源项目 CDN 加速服务
    MySQL限时解答
    OneProxy的功能与限制
    MySQL浮点计算存在的问题与解决方案
    DAS、SAN、NAS的区别
    气质
    受制于人
    mysqlbinlog flashback 5.6完全使用手册与原理
    Innodb引擎 compact模式下元组的磁盘存储结构
    数据迁移程序
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10735662.html
  • Copyright © 2011-2022 走看看