2012-07-15 216 views
0

我已经看到过这样的几个问题,但迄今没有任何帮助我。我制作了GLTriangle和GLRectangle类。我可以用颜色绘制这两个形状没有问题。我试图在它们中实现纹理,并且无法使它工作(和调试)。OpenGL ES 2.0纹理显示黑色

我会尝试发布迄今为止我所拥有的相关代码,如果您需要了解更多信息,请告诉我。

编辑:好的,所以在修复texcoord处理程序的错误后,我仍然得到一个黑色的方块。 glGetError报告任何事情的唯一时间是在调用GLES20.glEnable(GLES20.GL_TEXTURE_2D)之后;

GLRectangle相关代码:

@Override 
public void onSurfaceCreated() { 
    ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(vertices.length * 4); 
    vertexByteBuffer.order(ByteOrder.nativeOrder()); 
    vertexBuffer = vertexByteBuffer.asFloatBuffer(); 
    vertexBuffer.put(vertices); 
    vertexBuffer.position(0); 

    vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode); 
    fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode); 

    mProgram = createAndLinkProgram(VertexShaderHandle(), FragmentShaderHandle(), new String[] { "uMVPMatrix", "vPosition", "a_TexCoordinate" }); 
    muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); 
    maPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition"); 
    loadTexture(context, imageId); 
    ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2); 
ibb.order(ByteOrder.nativeOrder()); 
indexBuffer = ibb.asShortBuffer(); 
indexBuffer.put(indices); 
indexBuffer.position(0); 

ByteBuffer tbb = ByteBuffer.allocateDirect(texCoords.length * 4); 
tbb.order(ByteOrder.nativeOrder()); 
textureCoordBuffer = tbb.asFloatBuffer(); 
textureCoordBuffer.put(texCoords).position(0); 
} 

而且在onDrawFrame:

GLES20.glUseProgram(mProgram); 
GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, 12, vertexBuffer); 
GLES20.glEnableVertexAttribArray(maPositionHandle); 
Matrix.multiplyMM(mMVPMatrix, 0, projMatrix, 0, mvMatrix, 0); 
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0); 
mTextureUniformHandle = GLES20.glGetUniformLocation(mProgram, "u_Texture"); 
     mTextureCoordinateHandle = GLES20.glGetAttribLocation(mProgram, "a_TexCoordinate"); 

GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle); 
GLES20.glUniform1i(mTextureUniformHandle, 0); 
GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length, GLES20.GL_UNSIGNED_SHORT, indexBuffer); 

我知道,或者至少我相当肯定的是,位图被加载,因为我得到的INT手柄加载时返回(如果int为0,将导致运行时错误)。

我猜测它与纹理坐标有关。

这里就是我有我特坐标:

texCoords = new float[] { 
    0, 0, 
    0, 1, 
    1, 1, 
    1, 0 
}; 

以防万一,这是值得与纹理加载器,在这里它是:

int[] textureHandle = new int[1]; 

      GLES20.glGenTextures(1, textureHandle, 0); 

      if (textureHandle[0] != 0) { 
       final BitmapFactory.Options options = new BitmapFactory.Options(); 
       options.inScaled = false; 

       final Bitmap bitmap = BitmapFactory.decodeResource(view.getContext().getResources(), resourceId, options); 



       GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);     

       GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); 
       GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 


       GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); 


       bitmap.recycle(); 

      } 

      if (textureHandle[0] == 0) { 
       throw new RuntimeException("Unable to load texture!"); 
      } 
      mTextureDataHandle = textureHandle[0]; 

编辑:忘了补充我的着色器,我只是通过代码设置字符串现在:

setVertexShader( 
       "uniform mat4 uMVPMatrix; \n" + 
       "uniform mat4 MVMatrix;  \n" + 
       "attribute vec4 vPosition; \n" + 
       "attribute vec2 a_TexCoordinate; \n" +     
       "varying vec2 v_TexCoordinate; \n" + 

       "void main() {  \n" + 

       "v_TexCoordinate = a_TexCoordinate; \n" + 
       "gl_Position = uMVPMatrix * vPosition; \n" + 
       "} \n");     

     setFragmentShader("precision mediump float; \n" + 
       "uniform sampler2D u_Texture; \n" +     
       "varying vec2 v_TexCoordinate; \n" + 
       "void main() {    \n" + 
       "gl_FragColor = texture2D(u_Texture, v_TexCoordinate); \n" + 
       "}       \n"); 
+1

'if(textureHandle [0]!= 0){'是**不是**检查错误的方法 - 使用'glGetError'来代替。 – 2012-07-15 06:04:08

+0

你说得对。我已经这样做了,并且我在GLES20.glEnable上获得了错误代码1280(GLES20.GL_TEXTURE_2D) – Ryan 2012-07-15 21:52:59

+1

当您使用着色器时,不使用glEnable作为纹理。 glEnable(GL_TEXTURE_2D)仅用于固定功能流水线,因此在opengles2.0中不是有效的操作。只需完全删除线。 – Tim 2012-07-17 17:10:12

回答

3
mTextureCoordinateHandle = GLES20.glGetUniformLocation(mProgram, "u_Texture"); 
mTextureUniformHandle = GLES20.glGetAttribLocation(mProgram, "a_TexCoordinate"); 

GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle); 

这都是落后的。你得到了德克萨斯的位置,并将其设置为制服,并获得统一的位置并将其设置为texcoord。另外,你甚至没有对texcoord属性做任何事情。

+0

谢谢,不能相信我错过了。 – Ryan 2012-07-15 22:29:06

+0

此外,texcoord绑定在createandlinkProgram方法中。 – Ryan 2012-07-17 20:26:29

+0

问题解决了吗? @Ryan – Tim 2012-07-17 20:27:06

1

您可能没有在第一时间获取图像数据。检查你的代码,你在哪里采取PNG/JPEG文件来填补你的纹理。