Android - 在OpenGL ES Surface Render上叠加颜色

时间:2014-03-02 02:00:59

标签: java android opengl-es opengl-es-2.0 glsurfaceview

这将是一个非常简短的问题,没有任何代码,所以我觉得我不应该问它,但我在网上找不到任何关于它的信息。我想在整个屏幕上放置一种颜色,或者在android中更正确的术语是表面渲染。例如,我有一个简单的白色背景,然后我在它上面放置一个绿色覆盖,使它显示为绿色。就像使用视图矩阵来移动场景中的所有内容一样。有没有办法可以在表面渲染上叠加颜色?再次,抱歉不得不问,但我在其他地方找不到任何关于它的信息。

2 个答案:

答案 0 :(得分:1)

有很多事情,我认为是开放式的。 简而言之,您应该有一个自我实现的GLSurfaceView,您可以将渲染器传递给它。 在渲染器中,您可以使用此代码覆盖具有绿色背景的onSurfaceCreated:

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    // Set the background frame color
    gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    mSquare = new Square();

}

mSquare.draw(gl);

中致电onDrawFrame

您可以定义自己的形状类,并将其传递给渲染器,指定它的颜色。 例如:

package com.example.example;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.opengles.GL10;

public class Square {

    private final FloatBuffer vertexBuffer;
    private final ShortBuffer drawListBuffer;

    // number of coordinates per vertex in this array
    static final int COORDS_PER_VERTEX = 3;
    static float squareCoords[] = {
            -1f, 1f, 0f,   // top left
            -1f,-1f, 0f,   // bottom left
             1f,-1f, 0f,   // bottom right
             1f, 1f, 0f};  // top right

    // order to draw vertices
    private final short drawOrder[] = {0, 1, 2, 0, 2, 3};

    float color[] = {0f, 1f, 0f, 1f};

    /**
     * Sets up the drawing object data for use in an OpenGL ES context.
     */
    public Square() {
        // initialize vertex byte buffer for shape coordinates
        ByteBuffer bb = ByteBuffer.allocateDirect(
                // (# of coordinate values * 4 bytes per float)
                squareCoords.length * 4);
        bb.order(ByteOrder.nativeOrder());
        vertexBuffer = bb.asFloatBuffer();
        vertexBuffer.put(squareCoords);
        vertexBuffer.position(0);

        // initialize byte buffer for the draw list
        ByteBuffer dlb = ByteBuffer.allocateDirect(
                // (# of coordinate values * 2 bytes per short)
                drawOrder.length * 2);
        dlb.order(ByteOrder.nativeOrder());
        drawListBuffer = dlb.asShortBuffer();
        drawListBuffer.put(drawOrder);
        drawListBuffer.position(0);
    }

    /**
     * Encapsulates the OpenGL ES instructions for drawing this shape.
     *
     * @param gl - The OpenGL ES context in which to draw this shape.
     */
    public void draw(GL10 gl) {
        // Since this shape uses vertex arrays, enable them
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

        // draw the shape
        gl.glColor4f(       // set color
                color[0], color[1],
                color[2], color[3]);
        gl.glVertexPointer( // point to vertex data:
                COORDS_PER_VERTEX,
                GL10.GL_FLOAT, 0, vertexBuffer);
        gl.glDrawElements(  // draw shape:
                GL10.GL_TRIANGLES,
                drawOrder.length, GL10.GL_UNSIGNED_SHORT,
                drawListBuffer);

        // Disable vertex array drawing to avoid
        // conflicts with shapes that don't use it
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    }
}

答案 1 :(得分:0)

覆盖(非半透明)颜色与使用该颜色本身绘制所有颜色相同。在这种情况下,您应该使用该颜色本身绘制每个对象。

另一方面,如果您的意思是用半透明颜色覆盖(调制),那么您需要修改每个像素的输出颜色,通常使用片段着色器。例如,假设您使用红色绘制所有内容,然后想要使用从应用程序传递的另一种颜色作为制服进行调制,您在片段着色器主函数中的确如下所示:

  
    

inputcolor = vec4(1.0,0.0,0.0,0.0);

         

gl_FragColor = inputcolor * modulating_color;

  

如果您担心全屏,而不仅仅是对象,那么您还需要使用glClear()功能来处理背景颜色。

或者,您可以绘制全屏矩形并进行混合,但与片段着色器中的本地化函数相比,它的代码太多了。假设您使用的是OpenGLES2.0。