2011-08-11 89 views
3

我期待有一個OpenGL視圖(GLSurfaceView),它在RelativeLayout中使用渲染器以及一些按鈕,這樣每個按鈕都可以與渲染視圖進行交互。按鈕,OpenGL和渲染器 - Android

讓我們來說說在這個RelativeLayout中,我有一個GLSurfaceView和一個下面的按鈕,當按下它時,會將GLSurfaceView更改爲隨機的純色。我瞭解如何在OpenGL中繪製,但我不明白如何從渲染器外部與渲染器進行交互,以便可以通過用戶輸入來更改曲面,而不會與視圖本身的觸摸事件相關聯。

從我的研究中,我猜我需要某種線程,我可能需要使用queueEvent(Runnable)方法。不知道該從哪裏出發。

XML(main.xml中)

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/RL1" 
android:orientation="vertical" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
> 

<android.opengl.GLSurfaceView 
    android:id="@+id/GLView" 
    android:layout_width="200dip" 
    android:layout_height="200dip" 
    android:layout_centerHorizontal="true" 

    /> 


<Button 
    android:id="@+id/Button1" 
    android:layout_width="150dip" 
    android:layout_height="100dip" 
    android:text="Click." 
    android:layout_below="@id/GLView" 
    android:layout_centerHorizontal="true" 
    /> 

活動(Basic.java)

import android.app.Activity; 
import android.opengl.*; 
import android.os.Bundle; 


public class Basic extends Activity { 
/** Called when the activity is first created. */ 


@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    GLSurfaceView glView = (GLSurfaceView)findViewById(R.id.GLView); 
    glView.setRenderer(new BasicRenderer(this)); 


} 
} 

渲染器(OpenGLRenderer.java)

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

import android.content.Context; 
import android.opengl.GLU; 
import android.opengl.GLSurfaceView.Renderer; 

public class BasicRenderer implements Renderer { 

private Context mContext; 
private float mWidth, mHeight; 
public BasicRenderer(Context context){ 
    mContext=context; 
} 

@Override 
public void onDrawFrame(GL10 gl) { 
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | 
      GL10.GL_DEPTH_BUFFER_BIT); 



} 

@Override 
public void onSurfaceChanged(GL10 gl, int width, int height) { 
    mWidth = (float)width; 
    mHeight = (float)height; 

    gl.glViewport(0, 0, width, height); 

    gl.glMatrixMode(GL10.GL_PROJECTION); 

    gl.glLoadIdentity(); 

    GLU.gluPerspective(gl, 45.0f, 
           (float) width/(float) height, 
           0.1f, 100.0f); 

    gl.glMatrixMode(GL10.GL_MODELVIEW); 

    gl.glLoadIdentity(); 

} 

@Override 
public void onSurfaceCreated(GL10 gl, EGLConfig config) { 

    // Set the background color to white 
    gl.glClearColor(1f, 1f, 1f, 0.5f); 

    gl.glShadeModel(GL10.GL_SMOOTH); 

    gl.glClearDepthf(1.0f); 

    gl.glEnable(GL10.GL_DEPTH_TEST); 

    gl.glDepthFunc(GL10.GL_LEQUAL); 

    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, 
         GL10.GL_NICEST); 

} 

} 

回答

3

我知道這是一個老問題,但它有一些投票es,所以要回答它

我用來跨線程與我的渲染器進行通信的技巧是將渲染器對象保留爲活動中的變量,然後將渲染器中的東西排列在渲染器中,以便在繪製下一幀(的onDraw的下一個呼叫):

public class Basic extends Activity { 
/** Called when the activity is first created. */ 

BasicRenderer myRenderer; 


@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    myRenderer = new BasicRenderer(this); 

    GLSurfaceView glView = (GLSurfaceView)findViewById(R.id.GLView); 
    glView.setRenderer(myRenderer); 


    myRenderer.queueDoSomethingNextTick(BasicRenderer.DO_THIS); 

    findViewById(R.id.Button1).setOnTocuhListener(new OnTouchListener(){ 

     public void onTouch(MotionEvent event){ 
      myRenderer.queueDoSomethingNextTick(BasicRenderer.DO_THAT); 
      // Compiler might complain about myRenderer not being final 
     } 


    }); 


} 
} 


public class BasicRenderer implements Renderer { 

    private Context mContext; 
    private float mWidth, mHeight; 


    private int command; 
    public static final DO_THIS = 1; 
    public static final DO_THAT = 2; 

public BasicRenderer(Context context){ 
    mContext=context; 
} 

@Override 
public void onDrawFrame(GL10 gl) { 

    if(command==DO_THIS){ 
     //doThis(); 
    } else if(command==DO_THAT){ 
     //doThat(); 
    } 

    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | 
     GL10.GL_DEPTH_BUFFER_BIT); 

    gl.glDrawAwesomeness(); 


} 

public void queueDoSomethingNextTick(int command){ 

    this.command = command; 

} 

} 

在上述示例中,你可能想改變命令,通過它的陣列和循環。實際上,我使用這種方法告訴渲染器要繪製哪些模型,或者告訴渲染器提前開始加載大型模型或紋理,以便當遊戲需要時,它已經在內存中,並且沒有在繪製之前延遲加載它

+0

你應該把什麼放入onsurfaceCreated()? – NovusMobile