- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我制作了一个初学者 OpenGL 应用程序,它显示了从 obj 文件加载的旋转金牛座。它运行得很好,我给我的 friend 们看了。昨天我打开应用程序, View 不再更新。如果我按下主页按钮,然后再次点击应用程序,它将更新 View ,以便我知道主循环处于 Activity 状态。
我回家并将其插入 android studio 以确认渲染线程正常触发,并且 view.requestRender();
也被调用。
我不知道为什么它停止工作。
这是我的 Android fragment ,用于加载 View 和渲染器
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
/**
* Inflate the layout for this fragment
*/
View root = inflater.inflate(R.layout.glfragment, container, false);
GLSurfaceView glview = (GLSurfaceView)root.findViewById(R.id.surface_view);
Log.i("Method", "OpenGLFragment::onCreateView()");
Context context = this.getActivity().getApplicationContext();
MyRenderer renderer = new MyRenderer(context);
glview.setEGLContextClientVersion(2);
glview.setRenderer(renderer);
glview.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
loadMeshes(context); // loads obj file into variable tourus
renderer.addToScene(tourus);
update = new GraphicsThread(glview);
update.start();
return root;
}
@Override
public void onDestroyView() {
if(update != null) {
update.quit();
}
super.onDestroyView();
}
这是图形线程:
public class GraphicsThread extends Thread {
private GLSurfaceView.Renderer renderer;
private GLSurfaceView view;
private boolean isRunning;
public GraphicsThread(GLSurfaceView view) {
this.view = view;
this.isRunning = true;
}
@Override
public void run() {
while (this.isRunning) {
view.requestRender(); // I verified this loop is executed just fine
}
}
public void quit() {
this.isRunning = false;
}
}
这是MyRenderer
代码
public class MyRenderer implements GLSurfaceView.Renderer {
private int program; // default shader program
private List<Mesh> drawables;
private Context context;
private long lastFrameTime;
private RenderInfo info; // MVP and Light matrices
private Bitmap bg;
public MyRenderer(Context context) {
this.drawables = new ArrayList<>();
this.context = context;
this.lastFrameTime = 0;
this.info = null;
}
@Override
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
info = new RenderInfo(context);
GLES20.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
GLES20.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
GLES20.glEnable(GLES20.GL_CULL_FACE);
}
public void onDrawFrame(GL10 unused){
// Redraw background color
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
float elapsed = getElapsedTime();
float rot = 10.0f*elapsed;
for(Mesh m : drawables) {
m.rotateX(rot);
m.draw(info, elapsed);
}
}
public void onSurfaceChanged(GL10 unused, int width, int height) {
GLES20.glViewport(0, 0, width, height);
if(width > 0 && height > 0) {
final float ratio = (float) width / height;
final float left = -ratio;
final float right = ratio;
info.resizePerspective(left, right, 1, -1);
}
}
public void addToScene(Mesh mesh) {
drawables.add(mesh);
}
private float getElapsedTime() {
long currentTime = SystemClock.elapsedRealtime();
float elapsed = (float)(currentTime - lastFrameTime) / 1000.0f; //convert ms to seconds
lastFrameTime = currentTime;
return elapsed;
}
}
最后,这是我绘制网格的方法。 RenderInfo
包含相机 MVP 矩阵和灯光及其矩阵等世界信息。与该问题无关。
public void draw(RenderInfo info, float elapsed) {
if(!loaded) {
Log.d("Mesh", "failed to draw");
return;
};
final int program = info.getProgram();
int position = GLES20.glGetAttribLocation(program, "a_Position");
int normal = GLES20.glGetAttribLocation(program, "a_Normal");
int aColor = GLES20.glGetAttribLocation(program, "a_Color");
//int textcoord = GLES20.glGetAttribLocation(program, "a_TexCoordinate");
GLES20.glEnableVertexAttribArray(position);
GLES20.glVertexAttribPointer(position, 3, GLES20.GL_FLOAT, false, 3 * 4, verticesBuffer);
GLES20.glEnableVertexAttribArray(aColor);
GLES20.glVertexAttribPointer(aColor, 4, GLES20.GL_FLOAT, true, 4*4, colorBuffer);
//GLES20.glEnableVertexAttribArray(normal);
//GLES20.glVertexAttribPointer(normal, 3, GLES20.GL_FLOAT, false, 3 * 4, normalBuffer);
float[] modelMatrix = new float[16];
Matrix.setIdentityM(modelMatrix, 0);
Matrix.setRotateM(modelMatrix, 0, rotX , 1.0f, 0.0f, 0.0f);
//Matrix.setRotateM(modelMatrix, 0, rotY , 0.0f, 1.0f, 0.0f);
//Matrix.setRotateM(modelMatrix, 0, rotZ , 0.0f, 0.0f, 1.0f);
float[] mvpMatrix = info.getMVP(modelMatrix);
int MVP = GLES20.glGetUniformLocation(program, "u_MVP");
GLES20.glUniformMatrix4fv(MVP, 1, false, mvpMatrix, 0);
float[] mvMatrix = info.getMV();
int MV = GLES20.glGetUniformLocation(program, "u_MV");
GLES20.glUniformMatrix4fv(MV, 1, false, mvMatrix, 0);
int lightM = GLES20.glGetAttribLocation(program, "u_LightPos");
GLES20.glUniformMatrix4fv(lightM, 1, false, info.getLightMatrix(), 0);
int lightCol = GLES20.glGetAttribLocation(program, "u_LightCol");
GLES20.glUniform4fv(lightCol, 1, info.getLightColor(), 0);
Log.d("boogio", "u_LightCol is: " + Integer.toString(lightCol));
GLES20.glDrawElements(GLES20.GL_TRIANGLES, facesList.size() * 3, GLES20.GL_UNSIGNED_SHORT, facesBuffer);
GLES20.glDisableVertexAttribArray(position);
GLES20.glDisableVertexAttribArray(aColor);
//GLES20.glDisableVertexAttribArray(normal);
}
TL;DR:应用程序渲染良好,并且用于更新良好。突然,应用程序不再在视觉上更新(没有重绘)。仅当应用程序失去并重新获得焦点 1 帧时,它才会重绘。不知道为什么。
最佳答案
您没有发布所有代码,因此无法重现该情况。我所能做的就是向你提出一些建议。
首先,最好告诉 GLView 使用 setPreservceEGLContext 保留设置的 OpenGL 上下文。 。如果这不能解决问题,最好在 OpenGL ES 上下文上启用调试跟踪,使用 setDebugFlas方法。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
/**
* Inflate the layout for this fragment
*/
View root = inflater.inflate(R.layout.glfragment, container, false);
GLSurfaceView glview = (GLSurfaceView)root.findViewById(R.id.surface_view);
Log.i("Method", "OpenGLFragment::onCreateView()");
Context context = this.getActivity().getApplicationContext();
MyRenderer renderer = new MyRenderer(context);
glview.setEGLContextClientVersion(2);
// added code
glview.setDebugFlags(GLSurfaceView.DEBUG_CHECK_GL_ERROR); // enable log
glview.setPreserveEGLContextOnPause(true); // default is false
glview.setRenderer(renderer);
glview.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
loadMeshes(context); // loads obj file into variable tourus
renderer.addToScene(tourus);
update = new GraphicsThread(glview);
update.start();
return root;
}
这将在 logcat
中向您的应用添加更多调试信息(我希望您已经知道它是什么)。我认为您会发现一些错误(带有 OPEN GL 错误的行..某些内容)。
我怀疑您重新打开该 Activity ,OpenGL上下文尝试使用不再有效的资源(因为OpenGL上下文被破坏)。在上下文重新创建期间需要管理的资源的典型示例是纹理和着色器程序。
只需将一些日志调试信息添加到图形线程:
public class GraphicsThread extends Thread {
private GLSurfaceView.Renderer renderer;
private GLSurfaceView view;
private boolean isRunning;
public GraphicsThread(GLSurfaceView view) {
this.view = view;
this.isRunning = true;
Log.i("GraphicsThread", "GraphicsThread::constructor()");
}
@Override
public void run() {
while (this.isRunning) {
Log.i("GraphicsThread", "requestRender");
view.requestRender(); // I verified this loop is executed just fine
}
}
public void quit() {
this.isRunning = false;
Log.i("GraphicsThread", "GraphicsThread::quit()");
}
}
GraphicThread 上的日志信息将帮助您检查线程是否按方面工作。
glview.setPreserveEGLContextOnPause(true);
在销毁上下文(屏幕旋转或后台 Activity )时保留资源:另一种方法是重新创建并重新加载所有资源。我想这样做是因为,一开始,当 GLView 被销毁时,Android 设备没有内存来保存 GLContext。RENDERMODE_CONTINUOUSLY
告诉 GLView 尽可能绘制场景(据我所知,这是最好的方法)。希望我的建议可以帮助到您。
关于android - 为什么我的 OpenGL fragment 在更新时停止重绘?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58645491/
我正在尝试使用谷歌浏览器的 Trace Event Profiling Tool分析我正在运行的 Node.js 应用程序。选择点样本后,我可以在三种 View 之间进行选择: 自上而下(树) 自上而
对于一个可能是菜鸟的问题,我们深表歉意,但尽管在 SO 上研究了大量教程和其他问题,但仍找不到答案。 我想做的很简单:显示一个包含大量数据库存储字符串的 Android ListView。我所说的“很
我已经开始了一个新元素的工作,并决定给 Foundation 5 一个 bash,看看它是什么样的。在创建带有水平字段的表单时,我在文档中注意到的第一件事是它们使用大量 div 来设置样式。所以我在下
我有一个 Windows 窗体用户控件,其中包含一个使用 BeginInvoke 委托(delegate)调用从单独线程更新的第 3 方图像显示控件。 在繁重的 CPU 负载下,UI 会锁定。当我附加
我有一堆严重依赖dom元素的JS代码。我目前使用的测试解决方案依赖于 Selenium ,但 AFAIK 无法正确评估 js 错误(addScript 错误不会导致您的测试失败,而 getEval 会
我正在制作一款基于滚动 2D map /图 block 的游戏。每个图 block (存储为图 block [21][11] - 每个 map 总共 231 个图 block )最多可以包含 21 个
考虑到以下情况,我是前端初学者: 某个 HTML 页面应该包含一个沉重的图像(例如 - 动画 gif),但我不想强制客户缓慢地等待它完全下载才能享受一个漂亮的页面,而是我更愿意给他看一个轻量级图像(例
我正在设计一个小软件,其中包括: 在互联网上获取资源, 一些用户交互(资源的快速编辑), 一些处理。 我想使用许多资源(它们都列在列表中)来这样做。每个都独立于其他。由于编辑部分很累,我想让用户(可能
我想比较两个理论场景。为了问题的目的,我简化了案例。但基本上它是您典型的生产者消费者场景。 (我关注的是消费者)。 我有一个很大的Queue dataQueue我必须将其传输给多个客户端。 那么让我们
我有一个二元分类问题,标签 0 和 1(少数)存在巨大不平衡。由于测试集带有标签 1 的行太少,因此我将训练测试设置为至少 70-30 或 60-40,因此仍然有重要的观察结果。由于我没有过多地衡量准
我是一名优秀的程序员,十分优秀!