2013-08-27 43 views
4

我有一個渲染器,它試圖將點繪製爲紋理正方形。沒有什麼是崩潰的,我有其他項目正在繪製好,但這些正方形沒有被渲染,我相信它與在drawTexturedPoint()函數中傳遞給着色器程序的數據有關。如何將正確的數據傳遞給OpenGL-ES 2.0着色器程序Android

我有一個FloatBuffer geometryBuffer持有vertice位置。 6個頂點座標完全相同的頂點,兩個三角形的每個角點都有一個頂點。這個緩衝區有多個點。

着色器程序將獲取這些頂點並根據傳遞給着色器的點(或方形)大小將它們操作到正確的位置。

protected String getPointVertexShader() 
{ 
    // Define a simple shader program for our points. 
    final String pointVertexShader = 
    "uniform vec2 u_pointSize; 
    + "uniform mat4 u_MVPMatrix;   \n"  
    + "attribute vec4 a_Position;    \n" 
    + "attribute vec2 a_TexCoordinate;   \n" 

    + "varying vec2 v_TexCoordinate;   \n" // Passed into the fragment shader. 

    + "void main()         \n" 
    + "{            \n" 
    + " v_TexCoordinate = a_TexCoordinate; \n" // Pass through the texture coordinate. 
    + " gl_Position = u_MVPMatrix * a_Position;  \n"  // gl_Position is a special variable used to store the final position. 
    + " gl_Position += vec4(gl_Position.w * u_pointSize * (a_TexCoordinate - vec2(0.5,0.5)), 0, 0);\n" 
    + "}            \n"; 
    return pointVertexShader; 
} 

protected String getPointFragmentShader() 
{ 
    final String pointFragmentShader = 
    "precision mediump float;  \n" 
    + "uniform sampler2D u_Texture; \n" // The input texture. 

    + "varying vec2 v_TexCoordinate;\n" // Interpolated texture coordinate per fragment. 

    + "void main()     \n" // The entry point for our fragment shader. 
    + "{       \n" 
    + " gl_FragColor = (texture2D(u_Texture, v_TexCoordinate));\n" // Pass the color directly through the pipeline.   
    + "}       \n"; 
    return pointFragmentShader; 
} 

請注意,u_pointSize是標準化設備座標中的vec2;該值應該是以像素爲單位的大小除以視口大小(以像素爲單位)。

以下是將數據傳遞給着色器並進行繪製的功能。

private void drawTexturedPoint(final FloatBuffer geometryBuffer) 
{ 
    //GeometryBuffer holds all the points in one buffer. 

    GLES20.glUseProgram(mPointsProgramHandle); 

    mPointSizeHandle = GLES20.glGetAttribLocation(mPointsProgramHandle, "u_pointSize"); 
    mPointMVPMatrixHandle = GLES20.glGetUniformLocation(mPointsProgramHandle, "u_MVPMatrix"); 
    mTextureUniformHandle = GLES20.glGetUniformLocation(mPointsProgramHandle, "u_Texture"); 
    mPointPositionHandle = GLES20.glGetAttribLocation(mPointsProgramHandle, "a_Position"); 
    mTextureCoordinateHandle = GLES20.glGetAttribLocation(mPointsProgramHandle, "a_TexCoordinate"); 

    // Pass in the texture coordinate information 
    mPointSize.position(0); 
    GLES20.glVertexAttribPointer(mPointSizeHandle, mVec2DataSize, GLES20.GL_FLOAT, false, 0, mPointSize); 

    GLES20.glEnableVertexAttribArray(mPointSizeHandle); 

    // Pass in the position information 
    geometryBuffer.position(0); 
    GLES20.glVertexAttribPointer(mPointPositionHandle, mPositionDataSize, GLES20.GL_FLOAT, false, mPositionFloatStrideBytes, geometryBuffer); 

    GLES20.glEnableVertexAttribArray(mPointPositionHandle); 

    // Pass in the texture coordinate information 
    mSquareTextureCoordinates.position(0); 
    GLES20.glVertexAttribPointer(mTextureCoordinateHandle, mVec2DataSize, GLES20.GL_FLOAT, false, 0, mSquareTextureCoordinates); 

    GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle); 


    GLES20.glUniformMatrix4fv(mPointMVPMatrixHandle, 1, false, mMVPMatrix, 0); 

    // Draw the cube. 
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, geometryBuffer.capacity()/mPositionDataSize);        
} 

這裏有抽獎功能

private final int mBytesPerFloat = 4; 
private final int mPositionOffset = 0; 
private final int mPositionDataSize = 3; 
private final int mPositionFloatStrideBytes = mPositionDataSize * mBytesPerFloat; 
private FloatBuffer mPointSize; 
private final int mVec2DataSize = 2; 

//紋理座標數據時使用的一些其他相關變量。

final float[] squareTextureCoordinateData = 
{ 
    // Front face 
    0.0f, 0.0f,     
    0.0f, 1.0f, 
    1.0f, 0.0f, 
    0.0f, 1.0f, 
    1.0f, 1.0f, 
    1.0f, 0.0f 
}; 

這是我設置方形尺寸(現在是硬編碼)的方式。

float psize = 25f/480f; 
mPointSize.position(0); 
mPointSize.put(psize); 
mPointSize.put(psize); 
mPointSize.flip(); 

最好的一些援助!

[編輯] @ user2359247好,我明白你的意思,我會保持它作爲統一的,所以我已經改變: mPointSizeHandle = GLES20.glGetUniformLocation(mPointsProgramHandle, 「u_pointSize」);

不太清楚如何通過緩衝區通過然而,我以前沒有遇到過。

另一個友好的問題是,你明白我想完成什麼,我只問,因爲我想知道我的mPointSize緩衝區是否有正確的數據呢? 這個渲染點紋理方塊的解決方案來自其他人,所以我試圖將它拼湊在一起。

所以,我真的不知道如何設置點大小變量值或應該使用什麼類型的功能,把它傳遞到着色器:

u_pointSize is a vec2 in normalised device coordinates; the value should be the size in pixels divided by the viewport size in pixels.

嘗試交換:

mPointSize.position(0); 
GLES20.glVertexAttribPointer(mPointSizeHandle, mVec2DataSize, GLES20.GL_FLOAT, false, 0, mPointSize); //Error code gets sent back after this line. 
GLES20.glEnableVertexAttribArray(mPointSizeHandle); 

GLES20.glUniform2fv(mPointSizeHandle, 1, mPointSize); 

這是目前表面: enter image description here
應該更多類似這樣的實物模型: enter image description here

+0

我懷疑從glGetUniformLocation()或glGetAttribLocation()返回的句柄有問題。你應該測試這些並使用glGetError()更多。 – ClayMontgomery

+0

@ClayMontgomery放置在我的drawTexturedPoint()函數中的下列行開始捕獲錯誤的一堆錯誤。錯誤:1281 – Hank

+0

GLES20.glVertexAttribPointer(mPointSizeHandle,mVec2DataSize,GLES20.GL_FLOAT,false,0,mPointSize); – Hank

回答

1

您正在試圖得到一個屬性的位置,而你點大小均勻:

final String pointVertexShader = 
"uniform vec2 u_pointSize; 

...

mPointSizeHandle = GLES20.glGetAttribLocation(mPointsProgramHandle, "u_pointSize"); 

無論是將點大小更改爲屬性或使用glGetUniformLocation。

+0

謝謝我已在上面添加了一個編輯 – Hank

+0

您還在嗎? – Hank

相關問題