2016-06-08 117 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