2016-06-08 115 views
0

我在这里给你一个简单的问题。我正在使用纹理来渲染位图,并且一切都很正常。不过,我想在上述纹理上绘制一条线。我知道vert/tex坐标如何工作,但由于某些未知原因,我无法做到这一点。我打电话在调用绘制位图到纹理之后绘制线,但只有位图仍然显示。达到此目的的最佳方法是什么?我使用texure2D在我的片段着色器中绘制位图,是否需要添加一些东西来绘制具有指定颜色的行?任何帮助将不胜感激。在纹理中画一条线Open GL ES 2.0 Android

谢谢。

代码相关的位图纹理:

private final String vertexTextureShaderCode = 
       "attribute vec4 aPosition;"+ // Position of out Vertex 
       "attribute vec2 aTexPosition;"+ // Position of our texture contained in the vertex 
       "varying vec2 vTexPosition;"+ // 
       "void main(){"+ 
       " gl_Position = aPosition;"+ 
       " vTexPosition = aTexPosition;"+ 
       "}"; 


private final String fragmentTextureShaderCode = 
       "precision mediump float;" + 
       "uniform sampler2D uTexture;" + // Our Background Image (Our uploaded image) 
       "varying vec2 vTexPosition;" + 
       "void main() {" + 
       " gl_FragColor = texture2D(uTexture, vTexPosition);" + 
       "}"; 

public void draw(float[] m ,ImageEffectFactory effectFactory,int currentEffect){ 
    // add program to OpenGl ES Environment; 
    this.imageEffectFactory = effectFactory; 
    boolean effectChanged = false; 
    if(currentEffect != mCurrentEffect){ 
     mCurrentEffect = currentEffect; 
     effectChanged = true; 
    } 

    int whichTexture = 0; 
    if(currentEffect > 0 && currentEffect < 6){ 
     whichTexture = 1; 
     if(effectChanged) { 
      imageEffectFactory.applyEffect(mTexturePointer, ImageEffectFactory.FILTER.values()[currentEffect], mTextureImageWidth, mTextureImageHeight); 
      effectChanged = false; 
     } 
    } 

    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); 

    GLES20.glUseProgram(mProgram); 
    GLES20.glEnable(GLES20.GL_BLEND); 
    GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA); 

    GLES20.glViewport(0,0,mViewWidth, mViewHeight); 

    // get handle to vertex shader vPosition member 
    mPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition"); 
    mTextureHandle = GLES20.glGetUniformLocation(mProgram, "uTexture"); 
    mTexturePositionHandle = GLES20.glGetAttribLocation(mProgram, "aTexPosition"); 


    GLES20.glVertexAttribPointer(mTexturePositionHandle, 2, GLES20.GL_FLOAT, false, 0, mTextureBuffer); 
    GLES20.glEnableVertexAttribArray(mTexturePositionHandle); 

    GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexturePointer[whichTexture]); 
    GLES20.glUniform1i(mTextureHandle,0); 

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

    // enable a handle to the triangle vertice 
    GLES20.glEnableVertexAttribArray(mPositionHandle); 


    // Draw the square 
    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, vertexCount); 

    // Disbale the vertex array 
    GLES20.glDisableVertexAttribArray(mPositionHandle); 


} 

正如我刚才所说,这工作正常。我尝试加载的位图将显示并看起来很完美。但在绘制完成后,我试图画出线条。这里是该行的设置:

private static final String vsShader = 
     "uniform mat4 uMVPMatrix;"+ 
     "attribute vec4 vPosition; " + 
     "void main() { " + 
     " gl_Position = uMVPMatrix * vPosition;" + 
     " }"; 

private static final String fsShader = 
     "precision mediump float;" 
     + "uniform vec4 vColor;" 
     + "void main() {" 
     + "gl_FragColor = vColor;" + 
     "}"; 

private float[] pathCoords = { 
     -0.5f, 0.5f,0.0f, 
     -0.5f, -0.5f, 0.0f 
}; 


private short[] pathDrawOrder = {0,1}; 
    private float[] color = {1.0f, 0.0f, 0.0f, 1.0f}; // - red for testing 
    private final FloatBuffer mVertBuffer; 
private final ShortBuffer mDrawListBuffer; 


private int mCropProgram; 

private int vPositionHandle; 
private int vColorHandle; 
private int uMVPMatrixHandle; 

public CropFrameRect(Context context){ 
    this.context = context; 

    // Allocat a byteBuffer for our Vertex Array; 
    ByteBuffer bb = ByteBuffer.allocateDirect(pathCoords.length * 4); 

    // ORder those Bytes correctly depending on the device (ie. BIG-ENDIAN vs. LITTLE-ENDIAN 
    bb.order(ByteOrder.nativeOrder()); 

    // Lets now store those vertex points into a FloatBuffer please. 
    mVertBuffer = bb.asFloatBuffer(); 
    mVertBuffer.put(pathCoords); 
    mVertBuffer.position(0); 

    ByteBuffer dlb = ByteBuffer.allocateDirect(pathDrawOrder.length*2); 
    dlb.order(ByteOrder.nativeOrder()); 

    mDrawListBuffer = dlb.asShortBuffer(); 
    mDrawListBuffer.put(pathDrawOrder); 
    mDrawListBuffer.position(0); 

    int vertexShader = ImageGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER, vsShader); 

    int fragmentShader = ImageGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER, fsShader); 

    // We've compiled our vertex and our texture shader programs. Let us create the program.. 
    mCropProgram = GLES20.glCreateProgram(); 

    // Attach the vertex shader string 
    GLES20.glAttachShader(mCropProgram, vertexShader); 

    // Attach the shader program string 
    GLES20.glAttachShader(mCropProgram, fragmentShader); 

    // Link the program code to the OpenGL Context 
    GLES20.glLinkProgram(mCropProgram); 

    Log.d(TAG, "Crop Program Linked: " + mCropProgram); 
} 

public void draw(float[] matrix){ 
    GLES20.glUseProgram(mCropProgram); 



    vPositionHandle = GLES20.glGetAttribLocation(mCropProgram, "vPosition"); 
    GLES20.glEnableVertexAttribArray(vPositionHandle); 
    GLES20.glVertexAttribPointer(vPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, 0, mVertBuffer); 

    // set the color 
    vColorHandle = GLES20.glGetUniformLocation(mCropProgram, "vColor"); 
    GLES20.glUniform4fv(vColorHandle, 1, color, 0); 

    // set the Matrix projection for the View; 
    uMVPMatrixHandle = GLES20.glGetUniformLocation(mCropProgram, "uMVPMatrix"); 
    GLES20.glUniformMatrix4fv(uMVPMatrixHandle, 1, false, matrix, 0); 

    GLES20.glLineWidth(2.7f); 


    // Draw those elements 
    GLES20.glDrawElements(GLES20.GL_LINES, pathDrawOrder.length, GLES20.GL_UNSIGNED_SHORT, mDrawListBuffer); 

    GLES20.glDisableVertexAttribArray(vPositionHandle); 
    GLES20.glDisable(vColorHandle); 

} 
+0

mDrawListBuffer的位置和内容,与pathDrawOrder相同; mCropProgram是否有效并对应于fsShader和vsShader中的源代码?手柄是否有效(vPositionHandle)与非负值相同?什么是矩阵值? –

+0

mDrawListBuffer是我将绘制顺序列表存储在其中的shortBuffer。我不认为这可能是需要的,但我也不认为它可能会受到伤害。我为这个示例添加了更多代码。 mCropProgram是有效的,并且对应于fsShader和vsShader,我肯定是99%。我很抱歉,这不是第一次更完整。我会尽快更新矩阵值谢谢。 – Devsil

回答

0

首先,你在做什么的一些代码可能会证明是有用的。如果纹理正确显示,我只能猜测绘制线有问题。但是绘图失败的原因很多。

第二个问题标题是“如何绘制纹理线”,而描述似乎是要求如何在绘制的纹理上绘制线条。请注意,这些2是非常不同的,因为绘制纹理很常见。

所以,如果你已经成功地将纹理绘制到视图上,但是你没有画出线条,那么我想最好开始调试问题。您应该先尝试绘制没有纹理的线条并查看是否绘制线条。 如果没有:

  • 检查坐标意义
  • 检查矩阵意义,甚至禁止他们(使用标识)用于调试
  • 检查你的shader绘制线条,你会最可能需要一个单独的着色器绘制纯色,而不是纹理的
  • 检查线宽设定
  • 如果所有的失败,然后创建一个新的着色器输出的硬编码纯色(白色为实例)和节选什么,但位置,创建顶点(0,0), (1,1)并将它们绘制为一条线。没有其他东西应该绘制,并且没有调用,但是清除缓冲区应该被做成openGL。在这个工作之后,你可以从这里开始建立起来,看看你的错误在哪里。

如果它确实直接从删除调用来绘制纹理,那么我最好的猜测就是你已经启用了深度测试并且该纹理位于纹理之后。尝试禁用深度测试或尝试使线更接近。

+0

感谢您的回复和信息。我已经更新了我的问题,以及相关的代码段。这里必须断开连接。我确信我犯了一个愚蠢的错误,但嘿,这只是有时学习的方式。谢谢你的帮助! – Devsil

+0

很多代码都没有意义。你是否会检查错误,因为有些行很可能会产生错误。所以看第二部分(线条):带纹理的部分不应该在那里,纹理句柄甚至不对应于这个着色器。 GLES20.glDisable(vColorHandle)是一个NO-NO。你在开始时清除缓冲区,所以如果你在这之前绘制纹理,它应该不可见...... –

+0

纹理句柄在我的结尾是一个错误。过去的试验和错误的遗留物。我已经更新了示例以反映我目前正在使用的内容,但未获成功。 – Devsil