- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 Android 5 的 OpenGL ES 2.0 中使用 glDrawArrays 在点处绘制纹理时,如果绘制调用次数过多,程序会崩溃。重现问题的应用程序的所有源代码都包含在下面。该代码不会在 Android 4 中崩溃,但会在几款配备 Android 5 和 Adreno GPU 的手机上崩溃,例如Android 5.1 的 Nexus 4。
测试程序创建一个包含 1000 个点的列表,并为每个点调用 glDrawArrays。它在调用 glDrawArrays 数百次后崩溃。在真实的应用程序中,glDrawArrays 当然会被调用一次,并将所有点作为输入,但这个程序是专门为重现这个错误而设计的,这个错误最初是在一个更大的应用程序中观察到的,它混合了许多不同的绘制调用。这个大型应用程序也仅在点绘制纹理时崩溃。
如果有任何关于如何解决此问题的建议,我将不胜感激。
这是崩溃后的 logcat 输出:
05-25 02:31:42.576 24891-24913/? A/libc﹕ Fatal signal 7 (SIGBUS), code 2, fault addr 0xa324c000 in tid 24913 (GLThread 6307)
05-25 02:31:42.633 23118-23838/? I/Icing﹕ Indexing 368CB9F40AF00CE01211CBABA69162BEFBB25180 from com.google.android.googlequicksearchbox
05-25 02:31:42.678 10820-10820/? I/DEBUG﹕ *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
05-25 02:31:42.678 10820-10820/? I/DEBUG﹕ Build fingerprint: 'google/occam/mako:5.1/LMY47O/1783956:user/release-keys'
05-25 02:31:42.678 10820-10820/? I/DEBUG﹕ Revision: '11'
05-25 02:31:42.678 10820-10820/? I/DEBUG﹕ ABI: 'arm'
05-25 02:31:42.678 10820-10820/? I/DEBUG﹕ pid: 24891, tid: 24913, name: GLThread 6307 >>> com.example.glpointtexture <<<
05-25 02:31:42.678 10820-10820/? I/DEBUG﹕ signal 7 (SIGBUS), code 2 (BUS_ADRERR), fault addr 0xa324c000
05-25 02:31:42.692 23118-23838/? I/Icing﹕ Indexing done 368CB9F40AF00CE01211CBABA69162BEFBB25180
05-25 02:31:42.695 10820-10820/? I/DEBUG﹕ r0 c0004600 r1 a324c004 r2 00004a81 r3 a324bfec
05-25 02:31:42.695 10820-10820/? I/DEBUG﹕ r4 b73f1748 r5 00000000 r6 00000000 r7 c0022200
05-25 02:31:42.695 10820-10820/? I/DEBUG﹕ r8 b74091e8 r9 04000000 sl 00008000 fp 00000000
05-25 02:31:42.695 10820-10820/? I/DEBUG﹕ ip fc000000 sp a47098b0 lr abbdbc91 pc abbcb908 cpsr 600e0030
05-25 02:31:42.695 10820-10820/? I/DEBUG﹕ backtrace:
05-25 02:31:42.696 10820-10820/? I/DEBUG﹕ #00 pc 000ab908 /system/vendor/lib/egl/libGLESv2_adreno.so (oxili_write_event_write+75)
05-25 02:31:42.696 10820-10820/? I/DEBUG﹕ #01 pc 000bbc8d /system/vendor/lib/egl/libGLESv2_adreno.so (oxili_wa_predraw+234)
05-25 02:31:42.696 10820-10820/? I/DEBUG﹕ #02 pc 000bbef1 /system/vendor/lib/egl/libGLESv2_adreno.so (oxili_wa_point_sprite_dummy_draw+204)
05-25 02:31:42.696 10820-10820/? I/DEBUG﹕ #03 pc 000ba47b /system/vendor/lib/egl/libGLESv2_adreno.so (oxili_primitive_drawarrays+318)
05-25 02:31:42.696 10820-10820/? I/DEBUG﹕ #04 pc 000825cf /system/vendor/lib/egl/libGLESv2_adreno.so (rb_primitive_drawarrays+298)
05-25 02:31:42.696 10820-10820/? I/DEBUG﹕ #05 pc 0005a51f /system/vendor/lib/egl/libGLESv2_adreno.so (core_glDrawArraysInstancedXXX+334)
05-25 02:31:42.696 10820-10820/? I/DEBUG﹕ #06 pc 0005a877 /system/vendor/lib/egl/libGLESv2_adreno.so (core_glDrawArrays+6)
05-25 02:31:42.696 10820-10820/? I/DEBUG﹕ #07 pc 00049acb /system/vendor/lib/egl/libGLESv2_adreno.so (glDrawArrays+24)
05-25 02:31:42.696 10820-10820/? I/DEBUG﹕ #08 pc 00bfb9cb /data/dalvik-cache/arm/system@framework@boot.oat
主 Activity .java
package com.example.glpointtexture;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ConfigurationInfo;
import android.opengl.GLSurfaceView;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity {
private GLSurfaceView glSurfaceView;
private boolean rendererSet = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
glSurfaceView = new GLSurfaceView(this);
final ActivityManager activityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
final boolean supportsEs2 = configurationInfo.reqGlEsVersion >= 0x20000;
if (supportsEs2) {
glSurfaceView.setEGLContextClientVersion(2);
glSurfaceView.setRenderer(new PointTextureRenderer(this));
rendererSet = true;
} else {
Toast.makeText(this, "This device does not support OpenGL ES 2.0", Toast.LENGTH_LONG).show();
return;
}
setContentView(glSurfaceView);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
点列表.java
package com.example.glpointtexture;
import android.opengl.GLES20;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.Random;
public class PointList {
private final int BYTES_PER_POINT = 8;
private final FloatBuffer pointData;
private final int bufferHandle;
public PointList(int numPoints) {
Random rnd = new Random();
// Create and populate buffer.
pointData = ByteBuffer.allocateDirect(numPoints * BYTES_PER_POINT)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
pointData.position(0);
for (int i=0; i<numPoints; i++) {
pointData.put(rnd.nextFloat() - 0.5f);
pointData.put(rnd.nextFloat() - 0.5f);
}
// Send buffer to GPU.
final int buffers[] = new int[1];
GLES20.glGenBuffers(1, buffers, 0);
bufferHandle = buffers[0];
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, bufferHandle);
pointData.position(0);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, numPoints * BYTES_PER_POINT, pointData, GLES20.GL_STATIC_DRAW);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
}
public int getHandle() {
return bufferHandle;
}
public int getSize() {
return pointData.capacity() / 2;
}
}
点着色器.java
package com.example.glpointtexture;
import android.opengl.GLES20;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class PointShader {
private final int programHandle;
private final int uSizeLocation;
private final int uColorLocation;
private final int aPositionLocation;
private final int textureId;
private String vertexShader =
"uniform float u_Size;" +
"attribute vec4 a_Position;" +
"void main() {" +
" gl_PointSize = u_Size;" +
" gl_Position = a_Position;" +
"}";
private String fragmentShader =
"precision mediump float;" +
"uniform sampler2D u_Texture;" +
"uniform vec4 u_Color;" +
"void main() {" +
" float alpha = texture2D(u_Texture, gl_PointCoord).a;" +
" vec4 rgba = u_Color;" +
" rgba.a = alpha;" +
" gl_FragColor = rgba;" +
"}";
public PointShader() {
final int vertexShaderHandle = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
GLES20.glShaderSource(vertexShaderHandle, vertexShader);
GLES20.glCompileShader(vertexShaderHandle);
final int fragmentShaderHandle = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
GLES20.glShaderSource(fragmentShaderHandle, fragmentShader);
GLES20.glCompileShader(fragmentShaderHandle);
programHandle = GLES20.glCreateProgram();
GLES20.glAttachShader(programHandle, vertexShaderHandle);
GLES20.glAttachShader(programHandle, fragmentShaderHandle);
GLES20.glLinkProgram(programHandle);
aPositionLocation = GLES20.glGetAttribLocation(programHandle, "a_Position");
uSizeLocation = GLES20.glGetUniformLocation(programHandle,"u_Size");
uColorLocation = GLES20.glGetUniformLocation(programHandle, "u_Color");
textureId = createTexture(128);
}
public boolean enable() {
if (programHandle == 0)
return false;
GLES20.glUseProgram(programHandle);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
return true;
}
public int getPositionHandle() {
return aPositionLocation;
}
public void setSize(float size) {
GLES20.glUniform1f(uSizeLocation, size);
}
public void setColor(float red, float green, float blue, float alpha) {
GLES20.glUniform4f(uColorLocation, red, green, blue, alpha);
}
private static int createTexture(int size) {
ByteBuffer alphaMask = ByteBuffer.allocateDirect(size * size);
alphaMask.order(ByteOrder.BIG_ENDIAN);
for (int y = size - 1; y >= 0; y--) {
for (int x = 0; x < size; x++) {
int offset = y * size + x;
int alpha = (x <= y) ? 255 : 0;
alphaMask.put(offset, (byte)(alpha));
}
}
return getAlphaMaskTexture(size, size, alphaMask);
}
private static int getAlphaMaskTexture(int width, int height, ByteBuffer alphaMask) {
alphaMask.position(0);
int[] texIds = new int[1];
GLES20.glGenTextures(1, texIds, 0);
int textureId = texIds[0];
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MAG_FILTER,GLES20.GL_LINEAR);
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_ALPHA, width, height, 0, GLES20.GL_ALPHA, GLES20.GL_UNSIGNED_BYTE, alphaMask);
return textureId;
}
}
PointTextureRenderer.java
package com.example.glpointtexture;
import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.util.Log;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class PointTextureRenderer implements GLSurfaceView.Renderer {
private final Context context;
private PointList pointList;
private PointShader pointShader;
public PointTextureRenderer(Context context) {
this.context = context;
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
GLES20.glClearColor(0.0f, 0.0f, 0.5f, 0.0f);
pointList = new PointList(1000);
pointShader = new PointShader();
pointShader.enable();
pointShader.setColor(1.0f, 0.0f, 0.0f, 1.0f);
pointShader.setSize(80);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES20.glViewport(0, 0, width, height);
}
@Override
public void onDrawFrame(GL10 gl) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
drawPoints();
}
private void drawPoints() {
final int coordinatesPerPoint = 2;
final int numPoints = pointList.getSize();
pointShader.enable();
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, pointList.getHandle());
GLES20.glVertexAttribPointer(pointShader.getPositionHandle(), coordinatesPerPoint, GLES20.GL_FLOAT, false, 0, 0);
GLES20.glEnableVertexAttribArray(pointShader.getPositionHandle());
// The points would normally be drawn with this call:
//GLES20.glDrawArrays(GLES20.GL_POINTS, 0, numPoints);
// Instead, we draw one point at a time in order to reproduce a bug.
for (int i=0; i<numPoints; i++) {
GLES20.glDrawArrays(GLES20.GL_POINTS, i, 1);
}
GLES20.glDisableVertexAttribArray(pointShader.getPositionHandle());
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
}
}
最佳答案
Open GL ES 是异步 API。在某些 GL 实现中,每次调用 glDraw* 时,驱动程序不会立即执行渲染,而是创建“任务”并将其放入每个上下文软件命令队列。稍后,调度程序从队列中弹出任务,进行一些优化(任务合并、状态变化减少等)并执行。软件队列的大小是有限的,如果你推送任务的速度快于调度程序弹出它们的速度,你的线程可能会被卡住(并等待调度程序)或者你可能会在某些驱动程序(mali,一些旧的 MESA 版本)上崩溃,如你所见.我在 Samsung Galaxy S3 和 Galaxy Note 上看到了确切的行为。可以使用绘制 100000 个相同三角形的简单示例重现该问题。解决方案是将小型绘制调用合并为大型绘制调用。
关于android - 在点绘制纹理时,glDrawArrays 在 Android 5 中崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30430068/
我正在处理一个个人 Java OpenGL (JOGL) 项目,我正在使用一些具有独立绘制函数和顶点的自定义对象。 public class Cube extends PhysicalObject {
我正在尝试渲染巨大的点云 (~150M),但 OpenGL 只渲染其中的一部分 (~52M)。渲染较小的数据集(glMapBufferRange,这可能会解决 4GB 的限制。 要考虑的另一件事是使用
我正在尝试渲染一个可以扩展到其他对象的四面体。 使用静态数组可以很好地绘制四面体。 但是当我将 OFF 文件读入动态数组时,什么也没有出现。编译时没有出现错误。 GLfloat *tetra_vert
我尝试使用 glDrawArray 和 GL_TRIANGLE_STRIP 渲染纹理网格,但绘制时存在伪影,但在屏幕上分布不均匀。 Screenshot of the problem. 这是我使用的代
伪代码: void draw() { Vertex* vertices = scene.GetVertexArray(); glEnableClientState(...);
我有一个未声明顶点属性的顶点着色器。它根据 UBO、gl_VertexId 和 gl_InstanceID 计算所有需要的值。 我know必须绑定(bind)非零 VAO 才能渲染。 那么,在当前 V
我正在关注一些初学者 OpenGL 教程,并且对这段代码有点困惑: glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject); //Bind GL_ARRAY
我正在尝试在 glDrawArray 上修改程序。如果我只使用glVertex3f一切都很好,如果我使用glDrawArrays`作为相同的顶点值,除了图形之外,我还会得到一些随机线。 与glDraw
我在 python3 中有这段代码,它不能在 Windows 机器上运行,但可以在 Linux 机器上运行。我绘制了一个绿色屏幕和一个红色三角形,但红色三角形仅在我退出时出现。 import pyga
我正在尝试遵循 [this][1] 简单教程,但在到达“glDrawArrays”时出现以下错误: openGLTest.exe 中 0x03D7598E (nvoglv32.dll) 处的未处理异常
我正在使用以下代码在某些指定坐标处绘制一条绿线 GLfloat colors[] = {0,1,0,1, 0,1,0,0.5}; CGPoint v[] = {{p1.x, p1.y},
我使用 vector 来存储顶点和法线数据 vector vertex; vector normal; 例如: normal.push_back(-1); normal.push_back(0); n
我正在尝试做一个简单的 Pong 游戏,但我遇到了一些问题。本质上,我有一个由四个点组成的数组,x 和 y 值表示一个硬编码的球,我需要让那个球正确显示。当我尝试使用 glDrawArray 时,我一
我最近发现 glDrawArrays 在每一帧上分配和释放大量内存。我怀疑它与 openGL 探查器报告的“Shaders compiled outside initialization”问题有关。这
当我尝试使用 glDrawArrays 绘制圆时,它显示四分之一 circle 由代码生成的 VBO 是正确的。顺便说一句,没有 0,0,0 这样的坐标。它似乎只绘制正顶点,但如果我将顶点乘以 -1
我在 openGL 的固定流水线上花了很多时间,最近开始学习可编程流水线。我认识我的画家,着色器类不是问题,因为它们使用固定功能管道的东西。我似乎无法让 glDrawArrays 为我的生活工作。 我
在循环遍历我想在 3D 引擎中渲染的所有对象时,尝试调用时出现错误 glDrawArrays(mesh->primitiveType, 0, mesh->vertexCount); 因为它试图从位置
好的,所以我仍在努力让它发挥作用。我的代码的重要部分是: def __init__(self, vertices, normals, triangles): self.bufferVertic
在通过 lwjgl 学习如何使用 OpenGL 3.2 时,我遵循了 here 上的教程.我一直在方法调用 glDrawArrays 上收到无效操作错误。如果我从教程中复制源代码,甚至会发生此错误。
我有一堆要绘制的多边形数据。我提取了那个绘图代码,现在它看起来像这样 for (int Index = 0; Index < Count; Index++) { glDrawArrays(GL
我是一名优秀的程序员,十分优秀!