按钮、OpenGL 和渲染器 - Android
我希望有一个 OpenGL 视图 (GLSurfaceView),它在relativelayout中使用渲染器和一些按钮,以便每个按钮都可以与渲染的视图交互。
假设在此相对布局中,我有一个 GLSurfaceView 和其下方的一个按钮,按下该按钮会将 GLSurfaceView 更改为随机纯色。我了解如何在 OpenGL 中绘制,但我不了解如何从渲染器外部与渲染器进行交互,以便可以通过与视图本身上的触摸事件无关的用户输入来更改表面。
根据我的研究,我猜测我需要某种线程,并且我可能需要使用方法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"
/>
活动(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);
}
}
I'm looking to have an OpenGL view (GLSurfaceView) that uses a Renderer alongside some buttons in a RelativeLayout so that each of these buttons can interact with the rendered view.
Let's say in this RelativeLayout I have one GLSurfaceView and one button underneath it that when pressed will change the GLSurfaceView to a random solid color. I understand how to draw in OpenGL, what I don't understand is how to interact with a renderer from outside the renderer so that the surface can be altered by user input not associated with a touch event on the view itself.
From my research, I'm guessing that I'll need a thread of some sort, and I may need to use the method, queueEvent(Runnable). Not sure where to go from here though.
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"
/>
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));
}
}
Renderer(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);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我知道这是一个老问题,但它得到了一些选票,所以要回答它
我用来跨线程与渲染器进行通信的技巧是将渲染器对象保留为活动中的变量,然后在渲染器中对其进行排队绘制下一帧时要做的事情(下一次调用 onDraw):
在上面的示例中,您可能希望将命令更改为数组并循环遍历它。我实际上使用这种方法来告诉我的渲染器要绘制哪些模型,或者告诉我的渲染器提前开始加载大型模型或纹理,这样当游戏需要它时,它已经在内存中并且没有在绘制之前延迟加载它
I know this is an old question, but it got some votes, so going to answer it
The trick I use to communicate across threads to my renderer is to keep the renderer object as a variable in activity and then queue stuff in the renderer for it to do when it comes to draw the next frame (next call of onDraw):
In the above example, you might want to change command to an array and loop through it. I actually use this approach for telling my renderer which models to draw, or telling my renderer to start loading a large model or texture ahead of time, so that when the game gets round to needing it, it is already in memory and there is no delay in loading it before it is drawn