草庐IT

android - 黑屏而不是多纹理

coder 2023-12-15 原文

我已经单独检查了纹理,它们工作正常。 每个纹理都是 128*128 像素,我在摩托罗拉 MILESTONE 手机上工作, 并测试了所有基本示例(从线到立方体贴图),在多纹理处理时卡住了 长方形。

如果我不绑定(bind)任何一个纹理,着色器运行良好,但问题始于两个用于多纹理的纹理。

private float[] myRotateMatrix = new float[16];
private float[] myViewMatrix = new float[16];
private float[] myProjectionMatrix = new float[16];
private float[] myMVPMatrix = new float[16];
private int aPositionLocation;
private int uMVPLocation;
private int aTextureCoordLocation;
private FloatBuffer rectangleVFB;
private ShortBuffer rectangleISB;
private FloatBuffer textureCFB;
private int program;
private int textureId1;
private int textureId2;
private int uSampler1Location;
private int uSampler2Location;

private void initShapes()  {
    float[] rectangleVFA = {-1,-1,0,  1,-1,0,  1,1,0, -1,1,0};
    short[] rectangleISA = {0,1,2,  0,3,2};
    float[] textureCFA = {0,0,  1,0,  1,1, 0,1};

    ByteBuffer rectangleVBB = ByteBuffer.allocateDirect(rectangleVFA.length * 4);
    rectangleVBB.order(ByteOrder.nativeOrder());
    rectangleVFB = rectangleVBB.asFloatBuffer();
    rectangleVFB.put(rectangleVFA);
    rectangleVFB.position(0);

    ByteBuffer rectangleIBB = ByteBuffer.allocateDirect(rectangleISA.length * 2);
    rectangleIBB.order(ByteOrder.nativeOrder());
    rectangleISB = rectangleIBB.asShortBuffer();
    rectangleISB.put(rectangleISA);
    rectangleISB.position(0);

    ByteBuffer textureCBB = ByteBuffer.allocateDirect(textureCFA.length * 4);
    textureCBB.order(ByteOrder.nativeOrder());
    textureCFB = textureCBB.asFloatBuffer();
    textureCFB.put(textureCFA);
    textureCFB.position(0);
}

public void onSurfaceChanged(GL10 gl, int width, int height)  {
    GLES20.glViewport(0, 0, width, height);
    checkError("glViewport");
    float ratio = (float) width / height;
    Matrix.setLookAtM(myViewMatrix, 0, 0, 0, 6, 0, 0, 0, 0, 1, 0);
    Matrix.frustumM(myProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);

    aPositionLocation = GLES20.glGetAttribLocation(program, "aPosition");
    checkError("glGetAttribLocation");

    uMVPLocation = GLES20.glGetUniformLocation(program, "uMVP");
    checkError("glGetUniformLocation");

    aTextureCoordLocation = GLES20.glGetAttribLocation(program, "aTextureCoord");
    checkError("glGetAttribLocation");

    uSampler1Location = GLES20.glGetUniformLocation(program, "uSampler1");
    checkError("glGetUniformLocation");

    uSampler2Location = GLES20.glGetUniformLocation(program, "uSampler2");
    checkError("glGetUniformLocation");

    int[] textures = new int[2];

    GLES20.glGenTextures(2, textures, 0);
    checkError("glGenTextures");

    textureId1 = textures[0];
    textureId2 = textures[1];

    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId1);
    checkError("glBindTexture");

    InputStream is1 = context.getResources().openRawResource(R.drawable.brick1);
    Bitmap img1;
    try  {
        img1 = BitmapFactory.decodeStream(is1);
    }finally  {
        try {
            is1.close();
        }catch (IOException ioe) {
        }
    }
    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, img1, 0);

    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId2);
    checkError("glBindTexture");

    InputStream is2 = context.getResources().openRawResource(R.drawable.brick2);
    Bitmap img2;
    try  {
        img2 = BitmapFactory.decodeStream(is2);
    }finally  {
        try  {
            is2.close();
        }catch (IOException ioe) {
        }
    }
    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, img2, 0);

    GLES20.glPixelStorei(GLES20.GL_UNPACK_ALIGNMENT, 1);
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
}

public void onDrawFrame(GL10 gl)  {
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
    checkError("glClear");

    GLES20.glUseProgram(program);
    checkError("glUseProgram");

    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    checkError("glActiveTexture");
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId1);
    checkError("glBindTexture");

    GLES20.glUniform1i(uSampler1Location, 0);
    checkError("glUniform1i");

    GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
    checkError("glActiveTexture");
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId2);
    checkError("glBindTexture");

    GLES20.glUniform1i(uSampler2Location, 1);
    checkError("glUniform1i");

    Matrix.setIdentityM(myRotateMatrix, 0);
    Matrix.rotateM(myRotateMatrix, 0, touchX, 0, 1, 0);
    Matrix.rotateM(myRotateMatrix, 0, touchY, 1, 0, 0);
    Matrix.multiplyMM(myMVPMatrix, 0, myViewMatrix, 0, myRotateMatrix, 0);
    Matrix.multiplyMM(myMVPMatrix, 0, myProjectionMatrix, 0, myMVPMatrix, 0);

    GLES20.glVertexAttribPointer(aPositionLocation, 3, GLES20.GL_FLOAT, false, 12, rectangleVFB);
    checkError("glVertexAttribPointer");

    GLES20.glEnableVertexAttribArray(aPositionLocation);
    checkError("glEnableVertexAttribArray");

    GLES20.glVertexAttribPointer(aTextureCoordLocation, 2, GLES20.GL_FLOAT, false, 8, textureCFB);
    checkError("glVertexAttribPointer");

    GLES20.glEnableVertexAttribArray(aTextureCoordLocation);
    checkError("glEnableVertexAttribArray");

    GLES20.glUniformMatrix4fv(uMVPLocation, 1, false, myMVPMatrix, 0);
    checkError("glUniformMatrix4fv");

    GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, rectangleISB);
    checkError("glDrawElements");
}

最佳答案

在 OpenGL ES 2.0 中,在每次调用 glBindTexture 之后和 texImage2D 之前,必须单独指定该纹理的参数。

因此,如果有 2 个纹理(如在多纹理中),则纹理 1 和 2 各需要 4 个 glTexParameterf,总共 8 个。

关于android - 黑屏而不是多纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10462699/

有关android - 黑屏而不是多纹理的更多相关文章

  1. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  2. 【Java 面试合集】HashMap中为什么引入红黑树,而不是AVL树呢 - 2

    HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候

  3. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  4. ruby-on-rails - 只有当不是 nil 时才执行映射? - 2

    如果names为nil,则以下中断。我怎样才能让这个map只有在它不是nil时才执行?self.topics=names.split(",").mapdo|n|Topic.where(name:n.strip).first_or_create!end 最佳答案 其他几个选项:选项1(在其上执行map时检查split的结果):names_list=names.try(:split,",")self.topics=names_list.mapdo|n|Topic.where(name:n.strip).first_or_create!e

  5. ruby-on-rails - Rails 格式验证——字母数字,但不是纯数字 - 2

    什么是测试格式验证的最佳方法让我们说一个用户名,使用字母数字的正则表达式,但不是纯数字?我一直在我的模型中使用以下验证validates:username,:format=>{:with=>/^[a-z0-9]+[-a-z0-9]*[a-z0-9]+$/i}数字用户名(例如“342”)通过了验证,这是我不想要的。 最佳答案 您想“向前看”一封信:/\A(?=.*[a-z])[a-z\d]+\Z/i 关于ruby-on-rails-Rails格式验证——字母数字,但不是纯数字,我们在Sta

  6. ruby - 强制浏览器下载文件而不是打开文件 - 2

    我要下载http://foobar.com/song.mp3作为song.mp3,而不是让Chrome在其native中打开它浏览器中的播放器。我怎样才能做到这一点? 最佳答案 您只需要确保发送这些header:Content-Disposition:attachment;filename=song.mp3;Content-Type:application/octet-streamContent-Transfer-Encoding:binarysend_file方法为您完成:get'/:file'do|file|file=File.

  7. ruby - 更改 $LOAD_PATH 时,为什么使用 unshift 而不是 push? - 2

    我发现ruby加载路径是一个数组,很多项目都是这样使用的:$:.unshift(File.expand_path("../../lib",__FILE__))可以将本地文件添加到ruby路径数组的前面,方便我们require或者load。所以,我希望知道为什么我们不使用push将文件添加到数组的末尾? 最佳答案 假设您有一个“date.rb”文件(为什么不呢)并且您想要加载这个文件,而不是标准库日期。如果您使用追加,当您调用require'date'时您的文件将永远不会被加载,因为它位于数组的末尾并且标准日期会在之前找到。因此,如果

  8. ruby - 如何排序不是简单的哈希(哈希的哈希) - 2

    我有一个这样的哈希{55=>{:value=>61,:rating=>-147},89=>{:value=>72,:rating=>-175},78=>{:value=>64,:rating=>-155},84=>{:value=>90,:rating=>-220},95=>{:value=>39,:rating=>-92},46=>{:value=>97,:rating=>-237},52=>{:value=>73,:rating=>-177},64=>{:value=>69,:rating=>-167},86=>{:value=>68,:rating=>-165},53=>{:va

  9. ruby - Unicorn 使用 `reload` 而不是 `restart`? - 2

    我在这里对我的部署策略有点困惑,在什么情况下部署时我想向unicorn发送reload信号?例如在我的例子中它会是这样的:sudokill-sUSR2`cat/home/deploy/apps/my_app/current/tmp/pids/unicorn.pid`我一直在通过杀死那个pid来部署我的应用程序,然后通过类似的东西再次启动unicorn:bundleexecunicorn-cconfig/unicorn/production.rb-Eproduction-D我只是想知道为什么要使用重新加载?我可以通过这样做获得部署的任何性能吗? 最佳答案

  10. ruby - 使用 Ruby FileUtils 而不是 Bash 命令的好处? - 2

    使用FileUtils方法有什么好处http://ruby-doc.org/core/classes/FileUtils.html比等效的Bash命令? 最佳答案 除此之外,您不必担心确保您的目标平台安装了您正在使用的特定工具这一事实,以及正确引用shell异常的问题(如果您的目标是特别有问题的)Windows和Unix-alikes——尽管有Cygwin、GNUWin32等),如果你使用Ruby的FileUtils,你有一个Ruby函数调用的中等大小的开销,而如果你使用外部实用程序,你有相当大的开销来启动一个外部进程的每一次“调用

随机推荐