passing instructions from UI thread to Rendering thread (GLSurfaceView)
Asked Answered
D

2

3

The Setup : A RelativeLayout with a GLSurfaceView and a Button as shown in the image..

enter image description here

The Problem: Lets say I have other triangle models (The one in the picture being the initial model)... I wish to change the models cyclically on click of the button. Since button is on the UI thread and glSurfaceView runs on a separate thread, I don't exactly know how to pass the info/instruction to it. I know there is this thing called Handler in Android which might be useful in this case... But I need some help here..

Edit: If Handler is the right way, I need to know how to add Looper to that Handler... The documentation says add looper.prepare() at the start of run() method.. But the glSurfaceView creates thread implicitly, resulting in no run() method directly available..

Darlinedarling answered 25/1, 2013 at 13:26 Comment(0)
M
4

I don't think it is necessary to use handlers to solve this issue but you may need to adjust the way you organise your classes.

Here is an example of an organisational structure that might solve your issue:

Activity Class

public class MainActivity extends Activity {

    private int modelNumber = 0;
    private ArrayList<Model> models = new ArrayList<Model>();
    private YourRendererClass renderer;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        ...

        // Setup GLSurfaceView
        GLSurfaceView surface = new GLSurfaceView(this);
        setContentView(surface);

        renderer = new YourRendererClass();
        surface.setRenderer(renderer);

        // Set up models
        models.add(new Model(x, y, size etc..));
        models.add(new Model(x, y, size etc..));
        models.add(new Model(x, y, size etc..));
        etc.

        // Display first model
        renderer.setCurrentModel(models.get(modelNumber));

        ...
    }

    // Called by the button press:
    // Use android:onClick="onClick"
    // in your layout xml file within button
    public void onClick(View view){
        // Make it loop round
        modelNumber++;
        if(modelNumber>=models.size()){
            modelNumber=0;
        }

        // Display current model
        renderer.setCurrentModel(models.get(modelNumber));

    }
}

Renderer Class

public class YourRendererClass implements Renderer {

    private Model currentModel;

    @Override
    public void onDrawFrame(GL10 gl) {

        // ** Your existing set-up code **//

        // Draw model
        if (currentModel!=null){
            currentModel.draw(gl);
        }

    }

    public void setCurrentModel(Model model){
        currentModel = model;
    }

}

Model class

public class Model {
    // Holds model information
    private int size;
    private int x;
    private int y;
    // etc...

    public model(int x, int y, int size etc...){
        this.x=x;
        this.y=y;
        this.size=size;
        // etc....
    }

    public void draw(GL10 gl) {
        // ** Draw model based on model information fields above **
    }
}

The above code is untested as I don't have access to your drawing code but the structure should work if implemented correctly. I've tried to make it clear where you'll have to insert your own code to make it work. In particular I wasn't sure what defines each of your different models so you'll need to include sufficient local variables within the Model class to define them.

I hope my answer helps, let me know if you have any questions.

Tim

Morales answered 12/3, 2013 at 10:20 Comment(0)
F
3

You should look at queueEvent! It's a very convenient way to pass informations from UI Thread to renderer Thread:

queueEvent(new Runnable(){
    @Override
    public void run() {
        mRenderer.method();
}});
Forkey answered 9/6, 2016 at 9:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.