2017-06-19 2 views
0

Ich versuche, Text und ein Quadrat mit OpenGL ES 2.0 zu zeichnen. Jeder könnte in jeder Position sein.Projektionsproblem - Zeichnung Text und Quadrat

Aber bisher kann ich nur einen von ihnen sehe auf dem Projektionsmodus abhängig ich wählen:

  • ich nur den Platz sehen, ob ich „Matrix.setLookAtM“ verwenden, um die Kamera zu machen (0, -3 0,) zu buchen (0, 0, 0)
  • ich sehe nur den Text, wenn ich "Matrix.orthoM" verwenden, um eine orthogonale Projektion von "Texample2Renderer.java"

cf Code haben an der Unterseite .

Ich möchte beide sehen, wie ist es möglich? Ich habe darüber nachgedacht, die Square-Klasse zu modifizieren, damit sie mit dem orthogonalen Projektionsmodus funktioniert, aber ich habe keine Ahnung, wie ich das machen soll.

Für den Text, verwende ich diesen Code (es gibt eine Menge Code, so dass ich lieber den Repo schreiben):

https://github.com/d3alek/Texample2

Und für den Platz, verwende ich diesen Code :

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 
    } 
} 

ich habe gerade modif den Code in Texample2Renderer.java verwendet, um ein Quadrat zu zeichnen. Ich habe auch einen booleschen Wert hinzugefügt, um zwischen den Projektionsmodi zu wechseln.

Jede Hilfe wäre sehr geschätzt, vielen Dank im Voraus!

Antwort

0

Eigentlich ist ich nur den Platz vergrößern erforderlich, und es funktionierte mit orthogonale Projektion. Da die Quadratgröße "1" war, war sie fast nicht sichtbar.

0

Versuchen Sie, die Reihenfolge der Eckpunkte in Ihrem Platz Schnüre zu umkehren:

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 

Seine propably andere Richtung zeigt dann Ihre Kamera