【问题标题】:Rendering an image texture into a cubemap in openGL android在openGL android中将图像纹理渲染到立方体贴图中
【发布时间】:2016-02-14 23:19:28
【问题描述】:

我的设备上有一个位图(这是一个 6x1 立方体贴图),我想在立方体的所有面上渲染它

 InputStream is = getContext().getResources().openRawResource(R.raw.photo);
 Bitmap bitmap = BitmapFactory.decodeStream(is);
 int bytes = bitmap.getByteCount();
 ByteBuffer pixels = ByteBuffer.allocate(bytes);
 bitmap.copyPixelsToBuffer(pixels);

这是我的顶点着色器:

uniform mat4 uMVPMatrix;
uniform mat4 uSTMatrix;

attribute vec4 aPosition;
attribute vec4 aTextureCoord;
attribute vec4 aColor;
varying vec2 vTextureCoord;
varying vec4 vColor;

void main() {
  gl_Position = uMVPMatrix * aPosition;
  vTextureCoord = (uSTMatrix * aTextureCoord).xy;
  vColor = aColor;
}

这是我的片段着色器:

precision mediump float;

varying vec2 vTextureCoord;
varying vec4 vColor;

uniform samplerCube sTexture;

void main() {
    gl_FragColor = textureCube(sTexture, vec3(vTextureCoord, 1.0)) * vColor;
}

这是我在 onSurfaceCreated() 的渲染器中所做的:

GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
int[] texIds = new int[1];
GLES20.glGenTextures(1, texIds, 0);
m360PhotoTextureId = texIds[0];

GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(
    GLES20.GL_TEXTURE_CUBE_MAP,
    mTextureId);

for (int i = 0 ; i < 6 ; i++ ){
  pixels.position(0);
  GLES20.glTexImage2D(
      GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
      0,
      GLES20.GL_RGBA,
      1,
      1,
      0,
      GLES20.GL_RGBA,
      GLES20.GL_UNSIGNED_BYTE,
      pixels);
}

GLES20.glTexParameteri(
        GLES20.GL_TEXTURE_CUBE_MAP,
        GLES20.GL_TEXTURE_MIN_FILTER,
        GLES20.GL_LINEAR);
GLES20.glTexParameteri(
        GLES20.GL_TEXTURE_CUBE_MAP,
        GLES20.GL_TEXTURE_MAG_FILTER,
        GLES20.GL_LINEAR);
GLES20.glTexParameteri(
        GLES20.GL_TEXTURE_CUBE_MAP,
        GLES20.GL_TEXTURE_WRAP_S,
        GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(
        GLES20.GL_TEXTURE_CUBE_MAP,
        GLES20.GL_TEXTURE_WRAP_T,
        GLES20.GL_CLAMP_TO_EDGE);
GLES20.glBindTexture(GLES20.GL_TEXTURE_CUBE_MAP, 0);

我在纹理视图中看到的只是黑屏,而我希望看到一张照片(以像素为单位)正在立方体的所有面上呈现。

任何指针或帮助将不胜感激。

我试过了: 顶点着色器:

uniform mat4 uMVPMatrix;
attribute vec4 aPosition;
varying vec3 vTextureCoord;

void main() {
  gl_Position = uMVPMatrix * aPosition;
  vTextureCoord = aPosition.xyz;
}

片段着色器:

precision mediump float;
varying vec3 vTextureCoord;
uniform samplerCube sTexture;

void main() {
    gl_FragColor = textureCube(sTexture, vTextureCoord);
}

但我得到同样的黑屏。

【问题讨论】:

  • 位图中的第一个像素是什么颜色?由于这是您使用的唯一像素,因此结果应该完全以该颜色呈现。另外,您是否通过在片段着色器中简单地设置一个常量颜色来验证几何图形是否正确渲染?
  • @RetoKoradi 是的,我尝试在片段着色器中设置单一颜色。但是很难想象,因为所有的脸都是相同的颜色。是的,第一个像素是黑色的。但我只是想将缓冲区指针设置为 0。pixels.position(0);不做我想做的事?我希望每张脸都加载整个图像。
  • 从文档中,它说“宽度×高度纹素是从内存中读取的,从位置数据开始。”khronos.org/opengles/sdk/docs/man/xhtml/glTexImage2D.xml
  • 是的,但是您为宽度和高度参数都传递了 1。
  • 好吧,传入正确的尺寸将是一个开始。如果您传入完全错误的尺寸,不知道为什么您期望得到更好的结果。 1536 可能大于支持的最大大小。您可以查询MAX_CUBE_MAP_TEXTURE_SIZE的值来找出最大尺寸。

标签: android opengl-es opengl-es-2.0


【解决方案1】:

cubemap texture 是一种纹理,其图像代表立方体的面。立方体贴图纹理的“纹理坐标”是从立方体中心指向您要使用的颜色的矢量方向。

您正在尝试使用常规的旧 2D 纹理坐标,可能添加了第三个组件以使编译器静音。您必须提供方向,而不是二维坐标。您可以从您的位置在顶点着色器中生成它们。但这需要知道aPosition 是什么空间,而你没有告诉我。所以我不能告诉你怎么做。

无论如何,顶点着色器需要为纹理坐标提供 3D 方向。它应该由 VS 输入生成或传递。

请注意,您的程序可能还有其他问题。但这是可以从您的代码中推断出的问题。

【讨论】:

  • 我用我试过的 vs 和 fs 更新了我的答案,但我仍然得到同样的黑屏
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-15
  • 2010-10-02
  • 1970-01-01
  • 1970-01-01
  • 2018-07-29
  • 2015-10-12
相关资源
最近更新 更多