2014-02-24 51 views
3

首先,讓我說我今天很抱歉提出這麼多問題。 所以,我有一個圈子類。我有一個3圓形實例的數組列表,每個實例都有一個不同的x座標來繪製。無論出於何種原因,OpenGL ES 2.0只是繪製其中一個,即使我將它們全部繪製成圖。我查看了幾個小時的代碼,嘗試了很多不同的東西,但無濟於事。所以,我的問題是:爲了讓OpenGL ES 2.0繪製多個對象,有什麼特別的要做嗎? 這裏是我的代碼(我知道它的一個爛攤子,我會解決這個問題以後:)): 這裏是我的GLCircle類:OpenGL ES 2.0只繪製對象一次

package com.background.gl.objects; 
import static android.opengl.GLES20.GL_TRIANGLE_FAN; 
import static android.opengl.GLES20.glDrawArrays; 
import static android.opengl.Matrix.multiplyMM; 
import static android.opengl.Matrix.setIdentityM; 
import static android.opengl.Matrix.translateM; 
import static com.background.gl.glcirclebackgroundanimation.Constants.BYTES_PER_FLOAT; 

import java.util.Random; 

import android.opengl.Matrix; 

import com.background.gl.data.VertexArray; 
import com.background.gl.helper.TextureShaderProgram; 

public class GLCircle { 
    private static final int POSITION_COMPONENT_COUNT = 2; 
    private static final int TEXTURE_COORDINATES_COMPONENT_COUNT = 2; 
    private static final int STRIDE = (POSITION_COMPONENT_COUNT 
    + TEXTURE_COORDINATES_COMPONENT_COUNT) * BYTES_PER_FLOAT; 

    public float x; 
    public float y; 
    protected float[] wallBounds; 
    protected boolean positiveX, positiveY; 
    public boolean nullify; 
    protected float xCounter = 0f; 
    protected float yCounter = 0f; 
    public float[] bounds; 
    protected Random ran; 

    private float[] VERTEX_DATA = { 
     // Order of coordinates: X, Y, S, T 
     // Triangle Fan 
     0f, 0f, 0.5f, 0.5f, 
     -0.25f, -0.25f, 0f, 0.9f, 
     0.25f, -0.25f, 1f, 0.9f, 
     0.25f, 0.25f, 1f, 0.1f, 
     -0.25f, 0.25f, 0f, 0.1f, 
     -0.25f, -0.25f, 0f, 0.9f }; 

    private final VertexArray vertexArray; 

    public GLCircle(float x, float y) { 
     vertexArray = new VertexArray(VERTEX_DATA); 
     ran = new Random(); 
     wallBounds = new float[4]; 
     nullify = false; 
     this.x = x; 
     this.y = y; 
    } 

    public void bindData(TextureShaderProgram textureProgram) { 
     //Bind the position data to the shader attribute 
     vertexArray.setVertexAttribPointer(
      0, 
      textureProgram.getPositionAttributeLocation(), 
      POSITION_COMPONENT_COUNT, 
      STRIDE); 
     //Bind the texture coordinate data to the shader attribute 
     vertexArray.setVertexAttribPointer(
       POSITION_COMPONENT_COUNT, 
       textureProgram.getTextureCoordinatesAttributeLocation(), 
       TEXTURE_COORDINATES_COMPONENT_COUNT, 
       STRIDE); 
     } 

    public void drawCircle() { 
     glDrawArrays(GL_TRIANGLE_FAN, 0, 6); 
    } 


    public float getX() { 
     return this.x; 
    } 

    public float getY() { 
     return this.y; 
    } 



    public boolean isPositiveX() { 
     return positiveX; 
    } 



    public boolean isPositiveY() { 
     return positiveY; 
    } 


    public float[] getBounds(float ranX, float ranY) { 
     if(!positiveX) { 
      /*if(ranX >= 0f) { 
       wallBounds[0] = 1.05f + ranX; 
      } else {*/ 
       this.wallBounds[0] = 1.05f + ranX; 
      //} 
     } else { 
      /* 
      if(ranX >= 0f) { 
       wallBounds[0] = 1.05f - ranX; 
      } else {*/ 
       this.wallBounds[1] = 1.05f - ranX; 
      //} 
     } 
     if(!positiveY) { 
      this.wallBounds[2] = 1.75f + ranY; 
     } else { 
      this.wallBounds[3] = 1.75f - ranY; 
     } 

     return this.wallBounds; 
    } 

    public void setPos(float[] modelMatrix, 
      float[] projectionMatrix, TextureShaderProgram textureProgram, 
      int texture, float x, float y) { 
     setIdentityM(modelMatrix, 0); 
     translateM(modelMatrix, 0, 0f, 0.01f, 0f); 
     final float[] temp = new float[16]; 
     multiplyMM(temp, 0, projectionMatrix, 0, modelMatrix, 0); 
     System.arraycopy(temp, 0, projectionMatrix, 0, temp.length); 

     textureProgram.useProgram(); 
     textureProgram.setUniforms(projectionMatrix, texture); 
     bindData(textureProgram); 

     drawCircle(); 
    } 

public void scaleCircle(float[] modelMatrix, float x, float y, float z) { 
     Matrix.scaleM(modelMatrix, 0, x, y, z); 
    } 


    public void translateCircle(float x, float[] modelMatrix) { 
     translateM(modelMatrix, 0, /*-0.001f*/ x, -3f, -2f); 
    } 

}

} 
在我的渲染器類

所以,這就是我在做onSurfaceCreated()來實例化這些對象(我知道我所說的generateRanFloats兩次,浪費內存這樣做):

for(int i = 0; i < 3; i++) { 
      GLCircle circle = new GLCircle(generateRanFloats()[0], generateRanFloats()[1]); 
      circles.add(circle); 
} 

所以我創造我的三個OBJE CTS。現在,我每一個圓圈翻譯成onSurfaceChanged方法的x位置:

for(int i = 0; i < circles.size(); i++) { 
      circles.get(i).translateCircle(circles.get(i).x, modelMatrix); 
} 

然後我在onDrawFrame更新它們()方法:

circles.get(i).setPos(modelMatrix, projectionMatrix, textureProgram, texture, circles.get(i).x, circles.get(i).y); 

現在,這個問題不僅是我看到我的一個圈子正在翻譯屏幕,當我有三個。據我所知,我應該能夠在屏幕上繪製多個對象。那麼爲什麼只有一個被繪製?我也嘗試添加一個名爲circle2的單獨的GLCircle對象,並且對這個對象也做了相同的處理,但它也沒有顯示出來。我需要做些什麼才能在屏幕上繪製多個對象?任何幫助表示讚賞,如果您需要查看更多代碼,請告訴我。 :)

編輯:整個渲染器類

package com.background.gl.glcirclebackgroundanimation; 

import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT; 
import static android.opengl.GLES20.glClear; 
import static android.opengl.GLES20.glClearColor; 
import static android.opengl.GLES20.glViewport; 
import static android.opengl.Matrix.multiplyMM; 
import static android.opengl.Matrix.setIdentityM; 
import static android.opengl.Matrix.translateM; 

import java.util.ArrayList; 
import java.util.List; 
import java.util.Random; 

import javax.microedition.khronos.egl.EGLConfig; 
import javax.microedition.khronos.opengles.GL10; 

import android.content.Context; 
import android.opengl.GLSurfaceView.Renderer; 
import android.util.Log; 

import com.background.gl.helper.TextureShaderProgram; 
import com.background.gl.objects.GLCircle; 
import com.background.gl.objects.Mallet; 
import com.background.gl.objects.Table; 
import com.background.gl.util.MatrixHelper; 
import com.background.gl.util.TextureHelper; 

public class CircleDynamicBackgroundRenderer implements Renderer { 
private final Context context; 

    private final float[] projectionMatrix = new float[16]; 
    private final float[] modelMatrix = new float[16]; 
    protected static float ranX, ranY, ranSignX, ranSignY, ranSignVeloX, ranSignVeloY; 

    private Table table; 
    private Mallet mallet; 
    private List<GLCircle> circles; 
    private GLCircle circle2; 
    float xPos, yPos; 
    int x = 1; 
    float[] bounds; 
    Random ran; 

    private TextureShaderProgram textureProgram; 

    private int texture; 


    public CircleDynamicBackgroundRenderer(Context context) { 
     this.context = context; 
     circles = new ArrayList<GLCircle>(); 
     xPos = 0.1f; 
     ran = new Random(); 
    } 

    @Override 
    public void onSurfaceChanged(GL10 glUnused, int width, int height) { 
     glViewport(0, 0, width, height); 
     Log.w("Width and height", Integer.toString(width) + ", " + Integer.toString(height)); 
     MatrixHelper.perspectiveM(projectionMatrix, 90, (float) width 
       /(float) height, 1f, 10f); 

     setIdentityM(modelMatrix, 0); 
     for(int i = 0; i < circles.size(); i++) { 
      circles.get(i).translateCircle(circles.get(i).x, modelMatrix); 
     } 
     circle2.translateCircle(circle2.x, modelMatrix); 
     final float[] temp = new float[16]; 
     multiplyMM(temp, 0, projectionMatrix, 0, modelMatrix, 0); 
     System.arraycopy(temp, 0, projectionMatrix, 0, temp.length); 
    } 

    @Override 
    public void onSurfaceCreated(GL10 glUnused, EGLConfig config) { 
     glClearColor(0.0f, 0.0f, 1.0f, 0.0f); 

     table = new Table(); 
     mallet = new Mallet(); 

     textureProgram = new TextureShaderProgram(context); 

     texture = TextureHelper.loadTexture(context, R.drawable.air_hockey_surface); 
     //texture2 = TextureHelper.loadTexture(context, R.drawable.air_hockey_surface_2); 
     for(int i = 0; i < 3; i++) { 
      GLCircle circle = new GLCircle(generateRanFloats()[0], generateRanFloats()[1]); 
      circles.add(circle); 
      /*circle[i].x = circle[i].getX(); 
      circle[i].y = circle[i].getY(); 
      circle[i].bounds = circle[i].getBounds();*/ 
     } 
      circle2 = new GLCircle(generateRanFloats()[0], generateRanFloats()[1]); 
     Log.d("Circles size", Integer.toString(circles.size())); 
     Log.d("circles", Float.toString(circles.get(1).getX()) + " " + Float.toString(circles.get(2).getX())); 
    } 

    @Override 
    public void onDrawFrame(GL10 glUnused) { 
     //Clear the rendering surface 
     glClear(GL_COLOR_BUFFER_BIT); 
     for(int i = 0; i < circles.size(); i++) { 
     circles.get(i).setPos(modelMatrix, projectionMatrix, textureProgram, texture, circles.get(i).x, circles.get(i).y); 
     Log.d("Circles", Float.toString(circles.get(i).x)); 
     } 

     circle2.setPos(modelMatrix, projectionMatrix, textureProgram, texture, ranSignVeloX, circle2.x); 
     Log.d("Circle2", Float.toString(circle2.x)); 


     //Pass data into our shaders(u_matrix) and enable/bind the texture 
     //textureProgram.setUniforms2(projectionMatrix, texture, texture2); 
     //Bind our [vertex array] data to our shaders(attribute data) 
     //Draw it 
     /* 
     // Draw the mallets. 
     colorProgram.useProgram(); 
     colorProgram.setUniforms(projectionMatrix); 
     mallet.bindData(colorProgram); 
     mallet.draw();*/ 
    } 

    public float[] generateRanFloats() { 
     ranSignX = ran.nextFloat(); 
     ranSignY = ran.nextFloat(); 
     ranSignX = ranSignX > 0.5f? -1:1; 
     ranSignY = ranSignY > 0.5f? -1:1; 
     ranSignVeloX = ran.nextFloat(); 
     ranSignVeloY = ran.nextFloat(); 
     ranX = ran.nextFloat() * 1.05f; 
     ranY = ran.nextFloat() * 1.75f; 
     ranX = ranSignX > 0.5? -ranX:ranX; 
     ranY = ranSignY > 0.5? -ranY:ranY; 
     Log.d("Generated", Float.toString(ranX)); 
     return new float[] {ranX, ranY}; 
    } 

} 

回答

0

公共無效畫圓(){ (4,8 GL_TRIANGLE_FAN,0,6); }

上面代碼繪製一個風扇。剩下的代碼在哪裏?

如果您在循環中調用此函數,那麼在setPos()中發生的翻譯在哪裏 - 因爲x,y似乎沒有在任何地方使用,並且translateM(modelMatrix, 0, 0f, 0.01f, 0f)總是翻譯相同的偏移量。

+0

我使用translateCircle()方法設置原始位置,無論出於何種原因,都沒有發佈在我的代碼片段中。我會添加它。我用它來設置它的位置,並且setPos()方法實際上將它在y軸上每幀移動0.001f。就像我說的那樣,它適用於出現的一個圓圈。我生成它的x位置並將其設置爲使用translateCircle(),然後在setPos()中將它移動0.001f。我只需要畫出不止一個。 – user2082169

+1

'0.001f'太小 - 即使在1080時也幾乎不能管理1個像素,除非您再次縮放某處。將其改爲更大的y偏移量,比如說0.3f。 – prabindh

+0

這是我的另一個問題。在0.001秒的範圍內進行翻譯,可以在大約10秒鐘的時間內在屏幕上,從上到下,橫向移動。從我的測試中,屏幕高度爲3.5f,其中1.75f爲頂部,-1.75f爲底部 – user2082169

0

可能有點晚了,但是......

對我來說,似乎所有的圈子正在繪製的,但他們對彼此頂部繪製,因爲沒有施加translateM。

您正在從onSurfaceChanged調用translateCircle。

但是,然後在OnDrawFrame中通過調用setIdentityM來還原模型矩陣。

setIdentityM(modelMatrix, 0); 
translateM(modelMatrix, 0, 0f, 0.01f, 0f); 
final float[] temp = new float[16]; 
multiplyMM(temp, 0, projectionMatrix, 0, modelMatrix, 0); 
... 

刪除translateCircle和修改

translateM(modelMatrix, 0, 0f, 0.01f, 0f); 

translateM(modelMatrix, 0, x, 0.01f, 0f); 

應該工作。