2013-05-10 222 views
0

拉丝工艺纹理我一直有与Android设备上的OpenGL ES的2拉丝质感约3天的问题,最后决定后,我的所有研发导致死角我应该帮助。问题是纹理被绘制成一个黑色的矩形而不是实际的图像。在OpenGL ES 2.0的

public class Sprite 
{ 
    private static final Shader spriteShader = ShaderManager.getInstance().getShader(1); 
    private static final short[] drawOrder = { 0, 1, 2, 0, 2, 3 }; 
    private static ShortBuffer drawListBuffer; 

    static 
    { 
     ByteBuffer bb = ByteBuffer.allocateDirect(drawOrder.length * 2); 
     bb.order(ByteOrder.nativeOrder()); 

     drawListBuffer = bb.asShortBuffer(); 
     drawListBuffer.put(drawOrder); 
     drawListBuffer.position(0);  
    } 

    private Context m_context; 
    private int m_textureId = 0; 
    private FloatBuffer m_vertexBuffer; 
    private float[] m_coords = 
     { 
      -0.5f, 0.5f, 0.0f, // Position 0 
      0.0f, 0.0f, // TexCoord 0 
      -0.5f, -0.5f, 0.0f, // Position 1 
      0.0f, 1.0f, // TexCoord 1 
      0.5f, -0.5f, 0.0f, // Position 2 
      1.0f, 1.0f, // TexCoord 2 
      0.5f, 0.5f, 0.0f, // Position 3 
      1.0f, 0.0f // TexCoord 3 
     }; 


    public Sprite(Context context) 
    { 
     m_context = context; 

     ByteBuffer bb = ByteBuffer.allocateDirect(m_coords.length * 4); 
     bb.order(ByteOrder.nativeOrder()); 

     m_vertexBuffer = bb.asFloatBuffer(); 
     m_vertexBuffer.put(m_coords); 
     m_vertexBuffer.position(0); 
    } 

    public void initialize(String file) 
    { 
     InputStream inputStream = null; 

     try 
     { 
      inputStream = m_context.getAssets().open(file); 
      m_textureId = loadTexture(inputStream); 
     } 
     catch (IOException e) 
     {} 
     finally 
     { 
      Util.closeStream(inputStream); 
     } 
    } 

    public void draw() 
    { 
     spriteShader.use(); 

     int position = spriteShader.getAttribLocation("vPosition"); 
     int textureCoords = spriteShader.getAttribLocation("aTexCoords"); 
     int texture = spriteShader.getUniformLocation("uTexture"); 

     m_vertexBuffer.position(0); 
     GLES20.glVertexAttribPointer(position, 3, GLES20.GL_FLOAT, false, 20, m_vertexBuffer); 
     Util.checkGlError("vertex pointer poistion"); 
     m_vertexBuffer.position(3); 
     GLES20.glVertexAttribPointer(textureCoords, 2, GLES20.GL_FLOAT, false, 20, m_vertexBuffer); 
     Util.checkGlError("vertex pointer textureCoords"); 
     GLES20.glEnableVertexAttribArray(position); 
     GLES20.glEnableVertexAttribArray(textureCoords); 

     GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
     Util.checkGlError("active trexture"); 
     GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, m_textureId); 
     Util.checkGlError("bind texture"); 

     GLES20.glUniform1i(texture, 0); 
     Util.checkGlError("uniform1i"); 
     GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length, GLES20.GL_UNSIGNED_SHORT, drawListBuffer); 
     Util.checkGlError("drawelements"); 

    } 

    private int loadTexture(InputStream inputStream) 
    { 
     int[] texture = new int[1]; 
     GLES20.glGenTextures(1, texture, 0); 

     GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture[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_NEAREST); 
     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); 

     Bitmap bitmap = BitmapFactory.decodeStream(inputStream); 
     GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); 
     bitmap.recycle(); 

     return texture[0]; 
    } 
} 

顶点着色器

attribute vec2 aTexCoords; 
attribute vec4 vPosition; 

varying vec2 vTexCoords; 

void main() 
{ 
vTexCoords = aTexCoords; 
gl_Position = vPosition; 
} 

片段着色器

precision mediump float; 

uniform sampler2D uTexture; 
varying vec2 vTexCoords; 

void main() 
{ 
gl_FragColor = texture2D(uTexture, vTexCoords); 
} 

回答

1

你可以尝试使用不同的阵列存储vertexcoords和texcoords。

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

并为纹理坐标创建单独的浮动缓冲区。您也可以在glVertexAtrribPointer调用中使用stride值为0,这意味着该数组被认为是紧密排列的。

+0

+1的答复,但结果很例外,我无视了正在初始化(字符串)又防止loadTexture(InputStream的),即使从被称为抛出。我所做的只是将图像粘贴到我的assest文件夹中,并停止投掷。 Android或日食只是被奇怪出于某种原因.. – DevGuy 2013-05-10 07:16:36

0

您的问题是在这条线:

GLES20.glVertexAttribPointer(textureCoords, 2, GLES20.GL_FLOAT, false, 20, m_vertexBuffer); 

有了这个,你基本上设置纹理坐标是相同的顶点坐标。因为这是第一个纹理坐标的地址,所以您需要设置为m_vertexBuffer+3而不是m_vertexBuffer

虽然我必须说,如果这是唯一的错误,你应该至少看到纹理的一部分。为了测试的目的,将纹理参数设置为不夹到边缘但重复。如果重复给你一些奇怪的结果,那很可能只有纹理坐标有问题。如果不是,纹理本身可能存在问题。

+0

我解决了这个问题,但是,为了回答你的问题FloatBuffer.position(INT)是glVertexAttributePointer(...) – DevGuy 2013-05-10 07:20:09

+1

哦之前打电话,现在我看到你重新定位的缓冲区,并且还有在这一点上没有任何错误.. – 2013-05-10 07:21:53

+0

是啊,我猜只是被损坏当我把它移动到RES /原始文件夹,然后回资产,或者类似的东西的图片。 – DevGuy 2013-05-10 07:29:26

0

原来很例外,我无视了正在初始化(字符串)又防止loadTexture(InputStream的),即使从被称为抛出。我所做的只是将图像粘贴到我的assest文件夹中,并停止投掷。 Android或日食只是被奇怪出于某种原因