【问题标题】:image of size 1000x800 unable to render properly尺寸为 1000x800 的图像无法正确渲染
【发布时间】:2016-08-01 14:20:48
【问题描述】:

我需要在 Android 设备上渲染大小为 1000x800 的图像。如果我创建 2x2 图像的宽度和高度,则可以正确渲染。如果任何超过此尺寸(即 2x2)的图像无法正确显示,则纹理似乎被抓取。我正在使用 Opengl ES 2.0。我尝试以各种方式设置 orthoM 矩阵,但在 2x2 宽度和高度之上,一切都显得很糟糕。如何将图像像素映射到设备像素。我为从 (0,0) 开始并向上延伸到宽度和高度的图像创建了网格网格。这意味着我的坐标不是从左上角开始的中心开始的。

我已经创建了这样的顶点缓冲区、短索引(绘制三角形的顺序列表)和纹理坐标。

public  MeshGrid(int width, int height) {
  vertices = new float[(width) * (height) * 2];
  indices = new short[(width-1) * (height-1) * 6];
  textu = new float[(width-1) * (height-1) * 8];

  float xOffset = width / -2;
  float yOffset = height / -2;
  int currentVertex = 0;
  int currentIndex = 0;
  int currentTexIndex = 0;

  short w = (short) (width );
  for (int y = 0; y < height ; y++) {
    for (int x = 0; x < width ; x++) {
      vertices[currentVertex] = x;
      vertices[currentVertex + 1] = y  ;
      currentVertex += 2;

      int n = y * (width ) + x;

      if (y < width-1 && x < height-1) {
        // Face one
        indices[currentIndex] = (short) n;
        indices[currentIndex + 1] = (short) (n + 1);
        indices[currentIndex + 2] = (short) (n + w);
        // Face two
        indices[currentIndex + 3] = (short) (n + 1);
        indices[currentIndex + 4] = (short)(n + 1 + w);
        indices[currentIndex + 5] = (short)  (n + 1 + w - 1);

        currentIndex += 6;

        textu[currentTexIndex] = x;
        textu[currentTexIndex+1] = y+1;
        textu[currentTexIndex+2] = x+1;
        textu[currentTexIndex+3] = y+1;
        textu[currentTexIndex+4] = x;
        textu[currentTexIndex+5] = y;
        textu[currentTexIndex+6] = x+1;
        textu[currentTexIndex+7] = y;
        currentTexIndex+= 8;
      }
    }
  }
}

我已经这样设置了

ByteBuffer bb = ByteBuffer.allocateDirect( // (#个坐标值 * 每个浮点数 4 字节) imgVertices.length * 4); bb.order(ByteOrder.nativeOrder()); 顶点缓冲区 = bb.asFloatBuffer(); vertexBuffer.put(imgVertices); vertexBuffer.position(0);

ByteBuffer vbb = ByteBuffer.allocateDirect(imgIndices.length * 2);
vbb.order(ByteOrder.nativeOrder());
indicesBuffer = vbb.asShortBuffer();
indicesBuffer.put(imgIndices);
indicesBuffer.position(0);
mNumOfIndices = imgIndices.length;


ByteBuffer byteBuf = ByteBuffer
        .allocateDirect(imgTexture.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
textureBuffer = byteBuf.asFloatBuffer();
textureBuffer.put(imgTexture);
mTextureSize = imgTexture.length;
textureBuffer.position(0);

这是我的顶点着色器代码

private final String vertexShaderCode =

"uniform mat4 uMVPMatrix;" +
"attribute vec2 a_TexCoordinate;" +
"attribute vec2 a_Position;" +
"varying vec2 v_TexCoordinate;" +
"varying vec3 v_Position;" +
"void main() {" +

"  v_TexCoordinate = a_TexCoordinate;" +


"gl_Position = uMVPMatrix*vec4(a_Position.x,a_Position.y,1.0,1.0);"+
 "}";

这是我的片段着色器代码

private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
"uniform sampler2D u_Texture;" +
"varying vec2 v_TexCoordinate;" +
"void main() {" +
"  gl_FragColor = texture2D(u_Texture, v_TexCoordinate);" +
"}";

这就是我设置投影和视图矩阵的方式

Matrix.setIdentityM(mProjectionMatrix, 0);
float ratio = (float)mwidth/mheight;
Matrix.orthoM(mProjectionMatrix,0,0f,ratio,0f,1,1,-1);
Matrix.setIdentityM(mViewMatrix, 0);
Matrix.setLookAtM(mViewMatrix, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);

这是我的绘图功能

void drawImg() {
  // Add program to OpenGL environment
  GLES20.glUseProgram(mProgram);

  // get handle to vertex shader's vPosition member
  mPositionHandle = GLES20.glGetAttribLocation(mProgram, "a_Position");

  GLES20.glVertexAttrib2fv(mPositionHandle, vertexBuffer);

  // Enable a handle to the triangle vertices
  GLES20.glEnableVertexAttribArray(mPositionHandle);

  // Prepare the triangle coordinate data
  GLES20.glVertexAttribPointer(
          mPositionHandle, COORDS_PER_VERTEX,
          GLES20.GL_FLOAT, false,
          vertexStride, vertexBuffer);

  // get handle to fragment shader's vColor member
  mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");


  // Set color for drawing the triangle
  GLES20.glUniform4fv(mColorHandle, 1, color, 0);

  // get handle to shape's transformation matrix
  mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
  checkGlError("glGetUniformLocation");

  // Apply the projection and view transformation
  GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
  checkGlError("glUniformMatrix4fv");

  mTxetureaformHandle = GLES20.glGetAttribLocation(mProgram, "a_TexCoordinate");
  // Pass in the texture coordinate information
  GLES20.glActiveTexture(GLES20.GL_TEXTURE0);

  // Bind the texture to this unit.
  GLES20.glEnable(GLES20.GL_TEXTURE_2D);
  textureBuffer.position(0);
  GLES20.glVertexAttribPointer(mTxetureaformHandle, 2, GLES20.GL_FLOAT, false,
          0, textureBuffer);


  GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTxetureHandle);
  GLES20.glEnableVertexAttribArray(mTxetureaformHandle);

  GLES20.glUniform1i(mTextureUniformHandle, 0);


  // Point out the where the color buffer is.
  GLES20.glDrawElements(GL10.GL_TRIANGLES, mNumOfIndices,
          GL10.GL_UNSIGNED_SHORT, indicesBuffer);


  // Disable vertex array
  GLES20.glDisableVertexAttribArray(mPositionHandle);
}

【问题讨论】:

    标签: android opengl-es


    【解决方案1】:

    如果您只想绘制图像,则无需在屏幕上绘制整个顶点网格(但如果您想绘制图像的子部分,请参见下文)。你需要做的就是画一个屏幕大小的矩形。将屏幕宽度用于 orthoM 中的“right”变量,将高度用于“top”变量:

    Matrix.orthoM(someMatrix, 0, 0f, width, 0.0f, height, 0, 50);
    

    那么你的顶点可以是这样的:

     vertices = new float[] {
                0.0f, 0.0f,
                0.0f, height,
                width, height,
                width, 0.0f
        };
    

    还有你的纹理坐标:

     uvs = new float[] {
                0.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 1.0f,
                1.0f, 0.0f
        };
    

    请注意,与默认图像编辑器相比,Android 中的 y 轴是倒置的,但是当您的图像倒置显示时,您会很快注意到这一点。

    现在我不确定你为什么要制作这么大的顶点网格。可能您只想要屏幕某些角落的图像的某些部分。在这种情况下,您必须调整顶点和/或纹理坐标。例如,如果您想要填充屏幕的 1/8,则将顶点坐标除以 8。如果您只想要四分之一的纹理将所有 1.0f 替换为 0.5f,您将获得图像的左上角(取决于如果你的 y 轴是倒置的)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多