使用不透明度渲染的Android OpenGL ES2三角形

时间:2016-08-01 15:26:22

标签: android opengl-es-2.0

我从服务器加载模型作为JSON格式,我在Three.js BufferGeometry中创建,存储位置和uv属性在JSON文件中,当我加载到openGL ES2时,一切都很好,但有些面孔在我旋转之前不会出现查看是否有纹理,如果有颜色则显示为半透明。 从Three.js生成的顶点值和顺序没有任何变化,所以我假设有正确的顺序,所以它应该没有反面。 enter image description here

enter image description here 这是片段着色器:

precision mediump float;

varying vec4 v_Color;
uniform sampler2D u_TextureUnit;
varying vec2 v_TextureCoordinates;

void main() {
    vec4 tex=texture2D(u_TextureUnit, v_TextureCoordinates);
    gl_FragColor=v_Color+tex;
}

和渲染代码:

    private static final int BYTES_PER_FLOAT = 4;
// private static final int BYTES_PER_SHORT = 2;
private static final int POSITION_COMPONENT_COUNT = 3;
private static final int COLOR_COMPONENT_COUNT = 4;
private static final int UV_COMPONENT_COUNT = 2;
private static final int ALL_COMPONENT_COUNT = POSITION_COMPONENT_COUNT + COLOR_COMPONENT_COUNT + UV_COMPONENT_COUNT;
private static final int STRIDE = ALL_COMPONENT_COUNT * BYTES_PER_FLOAT;

private VertexArray vertexArray;

private float[] modelMatrix = new float[16];
private final float[] modelViewProjectionMatrix = new float[16];

TextureShaderProgram shaderProgram;
int textureid;
// ShortBuffer indexBuffer;

public Geometry(Context context, JSONObject element) throws JSONException {     
    /*
     * JSONArray indecies = element.getJSONArray("indexes"); short[] indexes
     * = new short[indecies.length()]; for (int y = 0; y <
     * indecies.length(); y++) { indexes[y] = (short) indecies.getInt(y); }
     */
    // indexBuffer = ByteBuffer.allocateDirect(indexes.length *
    // BYTES_PER_SHORT).order(ByteOrder.nativeOrder()).asShortBuffer();
    // indexBuffer.put(indexes).position(0);
    JSONArray vertices = element.getJSONArray("vertices");
    JSONArray uvs = element.getJSONArray("uvs");
    JSONArray matrix = element.getJSONArray("matrix");
    for (int y = 0; y < matrix.length(); y++) {
        modelMatrix[y] = (float) matrix.getDouble(y);
    }
    JSONObject material = element.getJSONObject("material");
    int color = Color.parseColor(material.getString("color"));
    String bmpString = material.getString("map");
    int n = vertices.length() / 3;
    float[] data;
    data = new float[n * STRIDE];
    int k = 0;
    for (int i = 0; i < n; i++) {
        data[i * ALL_COMPONENT_COUNT] = (float) vertices.getDouble(i * 3);
        data[i * ALL_COMPONENT_COUNT + 1] = (float) vertices.getDouble(i * 3 + 1);
        data[i * ALL_COMPONENT_COUNT + 2] = (float) vertices.getDouble(i * 3 + 2);
        data[i * ALL_COMPONENT_COUNT + 3] = Color.red(color) / 255f;
        data[i * ALL_COMPONENT_COUNT + 4] = Color.green(color) / 255f;
        data[i * ALL_COMPONENT_COUNT + 5] = Color.blue(color) / 255f;
        data[i * ALL_COMPONENT_COUNT + 6] = Color.alpha(color) / 255f;
        data[i * ALL_COMPONENT_COUNT + 7] = bmpString.equals("") ? 0f : (float) uvs.getDouble(k);
        data[i * ALL_COMPONENT_COUNT + 8] = bmpString.equals("") ? 0f : (float) uvs.getDouble(k + 1);
        k += 2;
    }
    vertexArray = new VertexArray(data);

    shaderProgram = new TextureShaderProgram(context, R.raw.texture_vertex_shader, R.raw.texture_fragment_shader);
    textureid = bmpString.equals("") ? 0 : TextureHelper.loadTexture(TextureHelper.decodeBase64(bmpString));
}

private void bindData(TextureShaderProgram shaderProgram) {
    vertexArray.setVertexAttribPointer(0, shaderProgram.getPositionAttributeLocation(), POSITION_COMPONENT_COUNT, STRIDE);
    vertexArray.setVertexAttribPointer(POSITION_COMPONENT_COUNT, shaderProgram.getColorAttributeLocation(), COLOR_COMPONENT_COUNT, STRIDE);
    vertexArray.setVertexAttribPointer(POSITION_COMPONENT_COUNT + COLOR_COMPONENT_COUNT, shaderProgram.getTextureCoordinatesAttributeLocation(), UV_COMPONENT_COUNT, STRIDE);
}

public void draw(float[] projectionMatrix) {
    multiplyMM(modelViewProjectionMatrix, 0, projectionMatrix, 0, modelMatrix, 0);
    shaderProgram.useProgram();
    shaderProgram.setUniforms(modelViewProjectionMatrix, textureid);
    bindData(shaderProgram);
    glDrawArrays(GL_TRIANGLES, 0, vertexArray.getCapacity() / ALL_COMPONENT_COUNT);
    // glDrawElements(GL_TRIANGLES, indexBuffer.capacity(),
    // GL_UNSIGNED_SHORT, indexBuffer);
}

vertexData类:

    private final FloatBuffer floatBuffer;
private final int capacity;

public VertexArray(float[] vertexData) {
    floatBuffer = ByteBuffer.allocateDirect(vertexData.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer().put(vertexData);
    capacity = floatBuffer.capacity();
}

public void setVertexAttribPointer(int dataOffset, int attributeLocation, int componentCount, int stride) {
    floatBuffer.position(dataOffset);
    glVertexAttribPointer(attributeLocation, componentCount, GL_FLOAT, false, stride, floatBuffer);
    glEnableVertexAttribArray(attributeLocation);
    floatBuffer.position(0);
}

public final int getCapacity() {
    return capacity;
}

1 个答案:

答案 0 :(得分:1)

未设置深度功能,因此OpenGL ES基于索引数据按三角形顺序绘制。您必须启用深度测试,该测试将根据摄像机的深度信息对三角形进行排序。

glEnable(GL_DEPTH_TEST);