OpenGL ES 2.0的只能绘制对象一次 [英] OpenGL ES 2.0 only draws the object once

查看:415
本文介绍了OpenGL ES 2.0的只能绘制对象一次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,请允许我说我是问今天这么多问题抱歉。
所以,我有一个圆圈的一类。我有3圈例如一个ArrayList,每一个不同的x坐标绘制。无论出于何种原因,OpenGL ES 2.0的只是图纸其中之一,尽管我叫他们都绘制。我看了看我的code几个小时,尝试了很多不同的东西,但无济于事。所以,我的问题是:是否有什么特别的我必须做的就是OpenGL ES 2.0的绘制多个对象?
这里是我的code(我知道它的一个烂摊子稍后我会解决这个问题:)):
这里是我GLCircle类:

 包com.background.gl.objects;
引入静态android.opengl.GLES20.GL_TRIANGLE_FAN;
引入静态android.opengl.GLES20.glDrawArrays;
引入静态android.opengl.Matrix.multiplyMM;
引入静态android.opengl.Matrix.setIdentityM;
引入静态android.opengl.Matrix.translateM;
引入静态com.background.gl.glcirclebackgroundanimation.Constants.BYTES_PER_FLOAT;进口了java.util.Random;进口android.opengl.Matrix;进口com.background.gl.data.VertexArray;
进口com.background.gl.helper.TextureShaderProgram;公共类GLCircle {
    私有静态最终诠释POSITION_COMPONENT_COUNT = 2;
    私有静态最终诠释TEXTURE_COORDINATES_COMPONENT_COUNT = 2;
    私有静态最终诠释STRIDE =(POSITION_COMPONENT_COUNT
    + TEXTURE_COORDINATES_COMPONENT_COUNT)* BYTES_PER_FLOAT;    公众持股量X;
    公众持股量ÿ;
    保护浮法[] wallBounds;
    保护布尔positiveX,positiveY;
    公共布尔抵消;
    保护浮球xCounter = 0F;
    保护浮球yCounter = 0F;
    公众持股量[]界限;
    保护随机RAN;    私人浮动[] = VERTEX_DATA {
        //坐标顺序:X,Y,S,T
        //三角形扇
        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};    私人最终VertexArray vertexArray;    公共GLCircle(浮点X,浮法Y){
        vertexArray =新VertexArray(VERTEX_DATA);
        跑=新的随机();
        wallBounds =新的浮动[4];
        废掉= FALSE;
        this.x = X;
        this.y = Y;
    }    公共无效bindData(TextureShaderProgram textureProgram){
        //位置数据绑定到着色器属性
        vertexArray.setVertexAttribPointer(
            0,
            textureProgram.getPositionAttributeLocation(),
            POSITION_COMPONENT_COUNT,
            STRIDE);
        //绑定纹理坐标数据着色器属性
        vertexArray.setVertexAttribPointer(
                POSITION_COMPONENT_COUNT,
                textureProgram.getTextureCoordinatesAttributeLocation(),
                TEXTURE_COORDINATES_COMPONENT_COUNT,
                STRIDE);
        }    公共无效画圆(){
        (4,8 GL_TRIANGLE_FAN,0,6);
    }
    公众持股量的getX(){
        返回this.x;
    }    公众持股量的getY(){
        返回this.y;
    }    公共布尔isPositiveX(){
        返回positiveX;
    }    公共布尔isPositiveY(){
        返回positiveY;
    }
    公众持股量[]的getBounds(浮动ranX,浮ranY){
        如果(!positiveX){
            / *如果(ranX> = 0F){
                wallBounds [0] = 1.05f + ranX;
            }其他{* /
                this.wallBounds [0] = 1.05f + ranX;
            //}
        }其他{
            / *
            如果(ranX> = 0F){
                wallBounds [0] = 1.05f - ranX;
            }其他{* /
                this.wallBounds [1] = 1.05f - ranX;
            //}
        }
        如果(!positiveY){
            this.wallBounds [2] = 1.75f + ranY;
        }其他{
            this.wallBounds [3] = 1.75f - ranY;
        }        返回this.wallBounds;
    }    公共无效setPos(浮动[] modelMatrix,
            浮动[] projectionMatrix,TextureShaderProgram textureProgram,
            INT质感,浮法X,浮法Y){
        setIdentityM(modelMatrix,0);
        translateM(modelMatrix,0,0F,0.01F,0F);
        最终浮动[] TEMP =新的浮动[16];
        multiplyMM(温度,0,projectionMatrix,0,modelMatrix,0);
        System.arraycopy(温度,0,projectionMatrix,0,temp.length);        textureProgram.useProgram();
        textureProgram.setUniforms(projectionMatrix,纹理);
        bindData(textureProgram);        画圆();
    }公共无效scaleCircle(浮动[] modelMatrix,浮法X,浮法Y,浮动Z){
        Matrix.scaleM(modelMatrix,0,X,Y,Z);
    }
    公共无效translateCircle(浮法X,浮法[] modelMatrix){
        translateM(modelMatrix,0,/*-0.001f*/的x,-3F,-2f);
    }

}

 }

所以在我的渲染器类,这是我在onSurfaceCreated(做)来实例化这些对象(我知道我把做这个的两倍generateRanFloats和浪费内存):

 的for(int i = 0;我3;;我++){
            GLCircle圆=新GLCircle(generateRanFloats()[0],generateRanFloats()[1]);
            circles.add(圈);
}

所以我创造我的三个对象。现在,我每一个圆圈翻译成他们的x位置在onSurfaceChanged方法:

 的for(int i = 0; I< circles.size();我++){
            circles.get(I).translateCircle(circles.get(我).X,modelMatrix);
}

然后我在onDrawFrame更新它们()方法:

  circles.get(I).setPos(modelMatrix,projectionMatrix,textureProgram,质地,circles.get(I).X,circles.get(我).Y);

现在的问题是,我只看到我的社交圈中的一个被翻译了屏幕,当我应该有三个。据我知道,我应该能够在屏幕上绘制多个对象。那么,为什么只有一个正在制定?我也尝试添加一个单独的GLCircle命名对象CIRCLE2,做了这一个,以及相同的,但它并没有任何露面。是我做的,在屏幕上绘制多个对象的东西吗?任何帮助是AP preciated,如果您需要查看更多code,让我知道。 :)

编辑:整个渲染器类

 包com.background.gl.glcirclebackgroundanimation;引入静态android.opengl.GLES20.GL_COLOR_BUFFER_BIT;
引入静态android.opengl.GLES20.glClear;
进口静态android.opengl.GLES20.glClearColor;
引入静态android.opengl.GLES20.glViewport;
引入静态android.opengl.Matrix.multiplyMM;
引入静态android.opengl.Matrix.setIdentityM;
引入静态android.opengl.Matrix.translateM;进口的java.util.ArrayList;
进口的java.util.List;
进口了java.util.Random;进口javax.microedition.khronos.egl.EGLConfig;
进口javax.microedition.khronos.opengles.GL10;进口android.content.Context;
进口android.opengl.GLSurfaceView.Renderer;
进口android.util.Log;进口com.background.gl.helper.TextureShaderProgram;
进口com.background.gl.objects.GLCircle;
进口com.background.gl.objects.Mallet;
进口com.background.gl.objects.Table;
进口com.background.gl.util.MatrixHelper;
进口com.background.gl.util.TextureHelper;公共类CircleDynamicBackgroundRenderer实现渲染{
私人最终上下文的背景下;    私人最终浮动[] = projectionMatrix新的浮动[16];
    私人最终浮动[] = modelMatrix新的浮动[16];
    受保护的静态浮ranX,ranY,ranSignX,ranSignY,ranSignVeloX,ranSignVeloY;    私人表的表;
    私人槌槌;
    私人列表< GLCircle>界;
    私人GLCircle CIRCLE2;
    浮XPOS,yPos;
    INT X = 1;
    浮动[]界限;
    随机RAN;    私人TextureShaderProgram textureProgram;    私人诠释质感;
    公共CircleDynamicBackgroundRenderer(上下文的背景下){
        this.context =背景;
        圈=新的ArrayList< GLCircle>();
        XPOS = 0.1F;
        跑=新的随机();
    }    @覆盖
    公共无效onSurfaceChanged(GL10 glUnused,诠释的宽度,高度INT){
        glViewport(0,0,宽度,高度);
        Log.w(宽度和高度,Integer.toString(宽)+,+ Integer.toString(高度));
        MatrixHelper.perspectiveM(projectionMatrix,90,(浮点)宽度
                /(浮点)的高度,1F,10F);        setIdentityM(modelMatrix,0);
        的for(int i = 0; I< circles.size();我++){
            circles.get(I).translateCircle(circles.get(我).X,modelMatrix);
        }
        circle2.translateCircle(circle2.x,modelMatrix);
        最终浮动[] TEMP =新的浮动[16];
        multiplyMM(温度,0,projectionMatrix,0,modelMatrix,0);
        System.arraycopy(温度,0,projectionMatrix,0,temp.length);
    }    @覆盖
    公共无效onSurfaceCreated(GL10 glUnused,EGLConfig配置){
        glClearColor(0.0,0.0,1.0F,0.0);        表=新表();
        槌=新槌();        textureProgram =新TextureShaderProgram(背景);        质地= TextureHelper.loadTexture(背景下,R.drawable.air_hockey_surface);
        //纹理2 = TextureHelper.loadTexture(背景下,R.drawable.air_hockey_surface_2);
        的for(int i = 0;我3;;我++){
            GLCircle圆=新GLCircle(generateRanFloats()[0],generateRanFloats()[1]);
            circles.add(圈);
            /*circle[i].x =圈子[I] .getX();
            圈子[I] .Y =圈子[I] .getY();
            圈子[I] .bounds =圈子[I] .getBounds(); * /
        }
            CIRCLE2 =新GLCircle(generateRanFloats()[0],generateRanFloats()[1]);
        Log.d(圈子的大小,Integer.toString(circles.size()));
        Log.d(圈子,Float.toString(circles.get(1).getX())++ Float.toString(circles.get(2).getX()));
    }    @覆盖
    公共无效onDrawFrame(GL10 glUnused){
        //清除渲染表面
        glClear(GL_COLOR_BUFFER_BIT);
        的for(int i = 0; I< circles.size();我++){
        circles.get(ⅰ).setPos(modelMatrix,projectionMatrix,textureProgram,纹理,circles.get(ⅰ).X,circles.get(ⅰ).Y);
        Log.d(圈子,Float.toString(circles.get(一).X));
        }        circle2.setPos(modelMatrix,projectionMatrix,textureProgram,纹理,ranSignVeloX,circle2.x);
        Log.d(CIRCLE2,Float.toString(circle2.x));
        //将数据传递到我们的着色器(u_matrix),并启用/绑定纹理
        //textureProgram.setUniforms2(projectionMatrix,纹理,纹理2);
        //绑定我们的[顶点数组]数据给我们的着色器(属性数据)
        //画出来
        / *
        //绘制槌。
        colorProgram.useProgram();
        colorProgram.setUniforms(projectionMatrix);
        mallet.bindData(colorProgram);
        mallet.draw(); * /
    }    公众持股量[] 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(生成,Float.toString(ranX));
        返回新的浮动[] {ranX,ranY};
    }}


解决方案

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

对我来说,似乎所有的圈子正在绘制的,但他们对彼此顶部绘制的,因为没有应用translateM。

您是从onSurfaceChanged调用translateCircle。

但随后OnDrawFrame你是通过调用setIdentityM恢复模型矩阵。

  setIdentityM(modelMatrix,0);
translateM(modelMatrix,0,0F,0.01F,0F);
最终浮动[] TEMP =新的浮动[16];
multiplyMM(温度,0,projectionMatrix,0,modelMatrix,0);
...

删除translateCircle并修改

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

  translateM(modelMatrix,0,X,0.01F,0F);

应该工作。

First, let me say I'm sorry for asking so many questions today. So, I have a class for a circle. And I have an arraylist with 3 circle instance, each with a different x coordinate to draw. For whatever reason, OpenGL ES 2.0 is only drawing one of them, even though I call all of them to be drawn. I looked over my code for hours and tried many different things, but to no avail. So, my question is: Is there anything special I have to do to get OpenGL ES 2.0 to draw more than one object? Here is my code(I know its a mess. I will fix that later :) ): Here is my GLCircle class:

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

}

}

So in my renderer class, this is what I do in the onSurfaceCreated() to instantiate these objects(I'm aware I call the generateRanFloats twice and waste memory by doing this):

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

So I create my three objects. Now, I translate each of these circles into their x position in the onSurfaceChanged method:

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

And then I update them in the onDrawFrame() method:

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

Now, the issue is I only see one of my circles being translated up the screen, when I should have three. As far as I know, I should be able to draw more than one object on the screen. So why is only one being drawn? I also tried to add a separate GLCircle object named circle2 and did the same with this one as well, but it didn't show up either. Is the something I have to do to draw more than one object on the screen? Any help is appreciated, and if you need to see more code, let me know. :)

Edit: Entire renderer class

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

}

解决方案

Probably a bit late, but ...

To me it seems that all the circles are being drawn, but they are drawn on top of each other because translateM is not being applied.

You are calling translateCircle from onSurfaceChanged.

But then in OnDrawFrame you are reverting your model matrix by calling setIdentityM.

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

Removing translateCircle and modify

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

to

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

should work.

这篇关于OpenGL ES 2.0的只能绘制对象一次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆