Столкнулся со следующей проблемой: при попытке нарисовать что-либо на OpenGL после его первой прорисовке ничего не рисуется. Пробовал и glSurfaceView.requestRender() и glSurfaceView.invalidate() - без толку. С чем может связана быть данная проблема? Привожу пример класса:
package danielbernar.opengl.test.OpenGLTools;
import android.content.Context;
import android.opengl.GLSurfaceView.Renderer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT;
import static android.opengl.GLES20.GL_FLOAT;
import static android.opengl.GLES20.GL_FRAGMENT_SHADER;
import static android.opengl.GLES20.GL_TRIANGLES;
import static android.opengl.GLES20.GL_POINTS;
import static android.opengl.GLES20.GL_VERTEX_SHADER;
import static android.opengl.GLES20.GL_DEPTH_TEST;
import static android.opengl.GLES20.GL_DEPTH_BUFFER_BIT;
import static android.opengl.GLES20.glClear;
import static android.opengl.GLES20.glClearColor;
import static android.opengl.GLES20.glDrawArrays;
import static android.opengl.GLES20.glEnableVertexAttribArray;
import static android.opengl.GLES20.glGetAttribLocation;
import static android.opengl.GLES20.glGetUniformLocation;
import static android.opengl.GLES20.glUniform4f;
import static android.opengl.GLES20.glUseProgram;
import static android.opengl.GLES20.glVertexAttribPointer;
import static android.opengl.GLES20.glViewport;
import static android.opengl.GLES20.glUniformMatrix4fv;
import static android.opengl.GLES20.glEnable;
import android.*;
import android.opengl.*;
import java.util.*;
public class OpenGLRenderer implements Renderer {
private Context context;
private int programId;
private FloatBuffer vertexData;
private int uColorLocation;
private int uMatrixLocation;
private int aPositionLocation;
//String vertex_shader = "attribute vec4 a_Position; void main() { gl_Position = a_Position; gl_PointSize = 5.0; }"; // 2D
String vertex_shader = "attribute vec4 a_Position; uniform mat4 u_Matrix; void main() { gl_Position = u_Matrix * a_Position; gl_PointSize = 1.0; }"; // 3D
String fragment_shader = "precision mediump float; uniform vec4 u_Color; void main() { gl_FragColor = u_Color; }";
static final int GL_COORDINATES_COUNT = 3; // XYZ
private float[] mProjectionMatrix = new float[16];
private float[] vertices = new float[0];
int trngCount = 0;
public OpenGLRenderer(Context context) {
this.context = context;
prepareData();
}
@Override
public void onSurfaceCreated(GL10 arg0, EGLConfig arg1) {
glClearColor(1f, 1f, 1f, 1f);
glEnable(GL_DEPTH_TEST);
int vertexShaderId = ShaderUtils.createShader(GL_VERTEX_SHADER, vertex_shader);
int fragmentShaderId = ShaderUtils.createShader(GL_FRAGMENT_SHADER, fragment_shader);
programId = ShaderUtils.createProgram(vertexShaderId, fragmentShaderId);
glUseProgram(programId);
bindData();
}
@Override
public void onSurfaceChanged(GL10 arg0, int width, int height) {
glViewport(0, 0, width, height);
bindMatrix(width, height);
System.out.println(System.currentTimeMillis() + ": OpenGL onSurfaceChanged(GL10 arg0, int width, int height)");
}
public void addTrng(float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3) {
float[] tmpVert = new float[vertices.length + 3*3]; // 3 вершины и 3 координаты
System.arraycopy(vertices, 0, tmpVert, 0, vertices.length);
int verl = vertices.length;
tmpVert[verl] = x1;
tmpVert[verl+1] = y1;
tmpVert[verl+2] = z1;
tmpVert[verl+3] = x2;
tmpVert[verl+4] = y2;
tmpVert[verl+5] = z2;
tmpVert[verl+6] = x3;
tmpVert[verl+7] = y3;
tmpVert[verl+8] = z3;
vertices = tmpVert;
trngCount++;
}
public void addRect(float x1, float y1, float z1, float x2, float y2, float z2) {
addTrng(x1, y1, z1, x1, y2, z1, x2, y2, z2);
addTrng(x1, y1, z1, x2, y1, z2, x2, y2, z2);
}
public void draw() {
prepareData();
}
private void prepareData() {
vertexData = ByteBuffer.allocateDirect(vertices.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
vertexData.put(vertices);
}
private void bindData() {
uColorLocation = glGetUniformLocation(programId, "u_Color");
aPositionLocation = glGetAttribLocation(programId, "a_Position");
vertexData.position(0);
glVertexAttribPointer(aPositionLocation, GL_COORDINATES_COUNT, GL_FLOAT, false, 0, vertexData);
glEnableVertexAttribArray(aPositionLocation);
// матрица
uMatrixLocation = glGetUniformLocation(programId, "u_Matrix");
}
private void bindMatrix(int width, int height) {
float left = 0;
float right = width;
float bottom = height;
float top = 0;
float near = 1.0f;
float far = 8.0f;
Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
glUniformMatrix4fv(uMatrixLocation, 1, false, mProjectionMatrix, 0);
}
@Override
public void onDrawFrame(GL10 arg0) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 2: очищаем буффер глубины
glUniform4f(uColorLocation, 0.0f, 0.0f, 0.0f, 1.0f);
for (int i = 0; i<trngCount; i++) {
glDrawArrays(GL_TRIANGLES, i*3, 3);
}
}
}
И MainActivity:
final OpenGLRenderer oglr = new OpenGLRenderer(this);
oglr.addTrng(0, 0, -1, 50, 50, -1, 0, 50, -1);
oglr.addRect(100, 100, -1, 400, 400, -1);
for (int i = 0; i<1000; i++) {
int x = new Random().nextInt(1920);
int y = new Random().nextInt(1080);
oglr.addRect(x, y, -1, x+100, y+100, -1); // все отлично рисует
}
oglr.draw();
final GLSurfaceView glSurfaceView = new GLSurfaceView(this);
glSurfaceView.setEGLContextClientVersion(2);
glSurfaceView.setRenderer(oglr);
setContentView(glSurfaceView);
glSurfaceView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View p1) {
int x = new Random().nextInt(1920);
int y = new Random().nextInt(1080);
oglr.addRect(x, y, -1, x+100, y+100, -1); // ни в какую
oglr.draw();
glSurfaceView.requestRender();
glSurfaceView.invalidate();
}
});
Буду очень благодарен за помощь!
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
ЗдравствуйтеИмеется TextView, которая будет зажата с двух сторон другими элементами