4

我有一个渲染器,它试图将点绘制为带纹理的正方形。什么都没有崩溃,我还有其他项目被绘制得很好,但是这些方块没有被渲染,我相信这与在我的 drawTexturedPoint() 函数中传递给着色器程序的数据有关。

我有一个 FloatBuffer geometryBuffer 来保存顶点位置。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 是标准化设备坐标中的 vec2;该值应该是以像素为单位的大小除以以像素为单位的视口大小。

尝试交换:

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);

这是目前的表面: 在此处输入图像描述
应该更像这个模型: 在此处输入图像描述

4

1 回答 1

1

您正在尝试在点大小一致的情况下获取属性位置:

final String pointVertexShader =
"uniform vec2 u_pointSize;  

...

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

将点大小更改为属性或使用 glGetUniformLocation。

于 2013-08-28T08:31:27.827 回答