投影问题 - 绘图文本和正方形

时间:2017-06-19 11:30:43

标签: android matrix opengl-es opengl-es-2.0

我试图用OpenGL ES 2.0绘制文字和正方形。 每个人都可以处于任何位置。

但到目前为止,根据我选择的投影模式,我只能看到其中一个:

  • 如果我使用" Matrix.setLookAtM"我只能看到广场。使相机(0,-3,0)看(0,0,0)
  • 我只看到文字,如果我使用" Matrix.orthoM"有一个正交投影

来自" Texample2Renderer.java"的代码在底部。

我想看到两者,怎么可能?我正在考虑修改Square类以使其适用于正交投影模式,但我不知道如何做到这一点。

对于文字,我使用此代码(有很多代码,所以我更喜欢发布回购):

https://github.com/d3alek/Texample2

对于广场,我使用此代码:

public class Square {

    // number of coordinates per vertex in this array
    static final int COORDS_PER_VERTEX = 3;

    static float squareCoords[] = {
            -0.5f, 0.5f, 0.0f,   // top left
            -0.5f, -0.5f, 0.0f,   // bottom left
            0.5f, -0.5f, 0.0f,   // bottom right
            0.5f, 0.5f, 0.0f}; // top right

    private final String vertexShaderCode =
            // This matrix member variable provides a hook to manipulate
            // the coordinates of the objects that use this vertex shader
            "uniform mat4 uMVPMatrix;" +
                    "attribute vec4 vPosition;" +
                    "void main() {" +
                    // The matrix must be included as a modifier of gl_Position.
                    // Note that the uMVPMatrix factor *must be first* in order
                    // for the matrix multiplication product to be correct.
                    "  gl_Position = uMVPMatrix * vPosition;" +
                    "}";

    private final String fragmentShaderCode =
            "precision mediump float;" +
                    "uniform vec4 vColor;" +
                    "void main() {" +
                    "  gl_FragColor = vColor;" +
                    "}";

    private final FloatBuffer vertexBuffer;
    private final ShortBuffer drawListBuffer;
    private final int mProgram;
    private final short drawOrder[] = {0, 1, 2, 0, 2, 3}; // order to draw vertices
    private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex
    float color[] = {0.2f, 0.709803922f, 0.898039216f, 1.0f};
    private int mPositionHandle;
    private int mColorHandle;
    private int mMVPMatrixHandle;

    /**
     * Sets up the drawing object data for use in an OpenGL ES context.
     */
    public Square() {
        // BUFFER FOR SQUARE COORDS
        // 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);

        // BUFFER FOR DRAW ORDER
        // 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);

        // prepare shaders and OpenGL program
        int vertexShader = Utilities.loadShader(
                GLES20.GL_VERTEX_SHADER,
                vertexShaderCode);
        int fragmentShader = Utilities.loadShader(
                GLES20.GL_FRAGMENT_SHADER,
                fragmentShaderCode);
        mProgram = GLES20.glCreateProgram();             // create empty OpenGL Program
        GLES20.glAttachShader(mProgram, vertexShader);   // add the vertex shader to program
        GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
        GLES20.glLinkProgram(mProgram);                  // create OpenGL program executables
    }

    /**
     * Encapsulates the OpenGL ES instructions for drawing this shape.
     *
     * @param mvpMatrix - The Model View Project matrix in which to draw
     *                  this shape.
     */
    public void draw(float[] mvpMatrix) {
        // Add program to OpenGL environment
        GLES20.glUseProgram(mProgram);
        // get handle to vertex shader's vPosition member
        mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
        // Enable a handle to the triangle vertices
        GLES20.glEnableVertexAttribArray(mPositionHandle);
        // Prepare the triangle coordinate data
        GLES20.glVertexAttribPointer(
                mPositionHandle, COORDS_PER_VERTEX,
                GLES20.GL_FLOAT, false,
                vertexStride, vertexBuffer);
        // get handle to fragment shader's vColor member
        mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
        // Set color for drawing the triangle
        GLES20.glUniform4fv(mColorHandle, 1, color, 0);
        // get handle to shape's transformation matrix
        mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
        //Utilities.checkEglErrorEGL14Android("glGetUniformLocation");
        // Apply the projection and view transformation
        GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
        //Utilities.checkEglErrorEGL14Android("glUniformMatrix4fv");
        // Draw the square
        GLES20.glDrawElements(
                GLES20.GL_TRIANGLES, drawOrder.length,
                GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
        // Disable vertex array
        GLES20.glDisableVertexAttribArray(mPositionHandle);
    }
} 

Texample2Renderer.java:

public class Texample2Renderer implements GLSurfaceView.Renderer  {

    private static final String TAG = "TexampleRenderer";
    private Square square;
    private GLText glText;                             // A GLText Instance
    private Context context;                           // Context (from Activity)

    private int width = 100;                           // Updated to the Current Width + Height in onSurfaceChanged()
    private int height = 100;
    private float[] mProjMatrix = new float[16];
    private float[] mVMatrix = new float[16];
    private float[] mVPMatrix = new float[16];

    private boolean usesOrtho = false;

    public Texample2Renderer(Context context)  {
        super();
        this.context = context;                         // Save Specified Context
    }

    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
        // Set the background frame color
        GLES20.glClearColor( 0.4f, 0.3f, 0.6f, 1.0f );

        // Create the GLText
        glText = new GLText(context.getAssets());

        square = new Square();
        // Load the font from file (set size + padding), creates the texture
        // NOTE: after a successful call to this the font is ready for rendering!
        glText.load( "Roboto-Regular.ttf", 20*3, 2, 2 );  // Create Font (Height: 14 Pixels / X+Y Padding 2 Pixels)

        // enable texture + alpha blending
        GLES20.glEnable(GLES20.GL_BLEND);
        GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);
    }

    public void onSurfaceChanged(GL10 unused, int width, int height) { //        gl.glViewport( 0, 0, width, height );
        GLES20.glViewport(0, 0, width, height);
        float ratio = (float) width / height;

        // Take into account device orientation
        if (width > height) {
            Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 1, 10);
        }
        else {
            Matrix.frustumM(mProjMatrix, 0, -1, 1, -1/ratio, 1/ratio, 1, 10);
        }

        // Save width and height
        this.width = width;                             // Save Current Width
        this.height = height;                           // Save Current Height

        if(usesOrtho) {
            int useForOrtho = Math.min(width, height);

            //TODO: Is this wrong?
            Matrix.orthoM(mVMatrix, 0,
                    -useForOrtho / 2,
                    useForOrtho / 2,
                    -useForOrtho / 2,
                    useForOrtho / 2, 0.1f, 100f);
        }
    }

    public void onDrawFrame(GL10 unused) {
        // Redraw background color
        int clearMask = GLES20.GL_COLOR_BUFFER_BIT;

        GLES20.glClear(clearMask);

        if(!usesOrtho)
            Matrix.setLookAtM(mVMatrix,
                    0, // offset
                    0, 0, -3f, // eye (camera's position)
                    0f, 0f, 0f, // center (where to look at)
                    0f, 1.0f, 0.0f); // up

        Matrix.multiplyMM(mVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);

        if(square != null)
            square.draw(mVPMatrix);

        // TEST: render the entire font texture
        glText.drawTexture( width/2, height/2, mVPMatrix);            // Draw the Entire Texture

        // TEST: render some strings with the font
        glText.begin( 1.0f, 1.0f, 1.0f, 1.0f, mVPMatrix );         // Begin Text Rendering (Set Color WHITE)
        glText.drawC("Test String 3D!", 0f, 0f, 0f, 0, -30, 0);
//        glText.drawC( "Test String :)", 0, 0, 0 );          // Draw Test String
        glText.draw( "Diagonal 1", 40, 40, 40);                // Draw Test String
        glText.draw( "Column 1", 100, 100, 90);              // Draw Test String
        glText.end();                                   // End Text Rendering

        glText.begin( 0.0f, 0.0f, 1.0f, 1.0f, mVPMatrix );         // Begin Text Rendering (Set Color BLUE)
        glText.draw( "More Lines...", 50, 200 );        // Draw Test String
        glText.draw( "The End.", 50, 200 + glText.getCharHeight(), 180);  // Draw Test String
        glText.end();                                   // End Text Rendering
    }
} 

我刚修改了Texample2Renderer.java中的代码以绘制正方形。我还添加了一个布尔值来在投影模式之间切换。

非常感谢任何帮助,非常感谢!

2 个答案:

答案 0 :(得分:0)

尝试颠倒方形线中顶点的顺序:

 static float squareCoords[] = {
        0.5f, 0.5f, 0.0f}; // top right
        0.5f, -0.5f, 0.0f,   // bottom right
        -0.5f, -0.5f, 0.0f,   // bottom left
        -0.5f, 0.5f, 0.0f,   // top left

它可以面向其他方向然后你的相机

答案 1 :(得分:0)

实际上我只需要放大正方形,它就可以使用正交投影。由于方形尺寸为“1”,因此几乎看不到。

相关问题