我希望有一个 OpenGL View (GLSurfaceView),它使用 RelativeLayout 中的一些按钮旁边的渲染器,以便这些按钮中的每一个都可以与渲染的 View 交互。
假设在这个 RelativeLayout 中我有一个 GLSurfaceView 和它下面的一个按钮,按下时会将 GLSurfaceView 更改为随机纯色。我了解如何在 OpenGL 中绘制,但我不了解的是如何从渲染器外部与渲染器交互,以便可以通过与 View 本身的触摸事件无关的用户输入来更改表面。
根据我的研究,我猜测我需要某种线程,并且我可能需要使用方法 queueEvent(Runnable)。虽然不确定从这里去哪里。
XML(主.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"
/>
Activity (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);
}
}
最佳答案
我知道这是一个老问题,但它有一些选票,所以要回答它
我用来跨线程与我的渲染器通信的技巧是将渲染器对象保持为 Activity 中的变量,然后在渲染器中排队等待绘制下一帧(下一次调用 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;
}
}
在上面的示例中,您可能希望将命令更改为数组并循环遍历它。我实际上使用这种方法告诉我的渲染器要绘制哪些模型,或者告诉我的渲染器开始提前加载大型模型或纹理,这样当游戏轮到需要它时,它已经在内存中并且没有在绘制之前延迟加载它
关于android - 按钮、OpenGL 和渲染器 - Android,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7019811/