2013-09-15 3 views
2

Я новичок в OpenGL на Android, и я прочитал сильно документированные образцы, и я это понимаю. Но прежде чем пытаться сделать что-нибудь сложное, я хочу нарисовать простой двумерный белый прямоугольник на черном фоне. Ничего больше.OpenGL ES 2.0 Контекст в Android

Я застрял в этой ошибке: call to OpenGL ES API with no current context, которая, кажется, что я вызываю что-то из не-OpenGL Thread. Дело в том, что я не уверен, что вызывается из OpenGL Thread. Так вот мой код

// ============== активность ================== //

public class MainActivity extends Activity { 

public static String TAG = MainActivity.class.getSimpleName(); 

MyGLSurfaceView surface; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    getWindow().setFlags(
      WindowManager.LayoutParams.FLAG_FULLSCREEN, 
      WindowManager.LayoutParams.FLAG_FULLSCREEN 
    ); 

    surface = new MyGLSurfaceView(this); 
    setContentView(surface); 
} 

@Override 
protected void onPause() { 
    super.onPause(); 
    surface.onPause(); 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
    surface.onResume(); 
} 

} 

// ==================== GLSurfaceView =====================================================/

public class MyGLSurfaceView extends GLSurfaceView { 

MyGLSurfaceRenderer renderer; 

public MyGLSurfaceView(Context context) { 
    super(context); 

    setEGLContextClientVersion(2); 

    renderer = new MyGLSurfaceRenderer(this); 
    setRenderer(renderer); 
} 

} 

// ================== Renderer ===================== ===== //

public class MyGLSurfaceRenderer implements GLSurfaceView.Renderer { 

Square square = new Square(); 

public MyGLSurfaceRenderer(MyGLSurfaceView surface) { 

} 

@Override 
public void onDrawFrame(GL10 gl) { 
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); 
    square.draw(); 
} 

@Override 
public void onSurfaceChanged(GL10 gl, int width, int height) { 
    // TODO Auto-generated method stub 

} 

@Override 
public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 

} 

} 

// ==================== Площадь ============= ====== ===== //

public class Square { 

private FloatBuffer vertexBuffer; 
private ShortBuffer drawListBuffer; 

// number of coordinates per vertex in this array 
static final int COORDS_PER_VERTEX = 3; 
static float squareCoords[] = { -0.5f, 0.5f, 0.0f, // top left 
           -0.5f, -0.5f, 0.0f, // bottom left 
           0.5f, -0.5f, 0.0f, // bottom right 
           0.5f, 0.5f, 0.0f }; // top right 

private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices 
float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f }; 


private final String vertexShaderCode = 
     "attribute vec4 vPosition;" + 
     "void main() {" + 
     " gl_Position = vPosition;" + 
     "}"; 

private final String fragmentShaderCode = 
    "precision mediump float;" + 
    "uniform vec4 vColor;" + 
    "void main() {" + 
    " gl_FragColor = vColor;" + 
    "}"; 

int mProgram; 

static final int vertexStride = COORDS_PER_VERTEX * 4; 
static final int vertexCount = 4; 

public Square() { 
    // initialize vertex byte buffer for shape coordinates 
    ByteBuffer bb = ByteBuffer.allocateDirect(squareCoords.length * 4); // (# of coordinate values * 4 bytes per float) 
    bb.order(ByteOrder.nativeOrder()); 
    vertexBuffer = bb.asFloatBuffer(); 
    vertexBuffer.put(squareCoords); 
    vertexBuffer.position(0); 

    // initialize byte buffer for the draw list 
    ByteBuffer dlb = ByteBuffer.allocateDirect(drawOrder.length * 2); // (# of coordinate values * 2 bytes per short) 
    dlb.order(ByteOrder.nativeOrder()); 
    drawListBuffer = dlb.asShortBuffer(); 
    drawListBuffer.put(drawOrder); 
    drawListBuffer.position(0); 


    int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode); 
    int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode); 

    mProgram = GLES20.glCreateProgram();    // create empty OpenGL ES Program 
    GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program 
    GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program 
    GLES20.glLinkProgram(mProgram);     // creates OpenGL ES program executables 
} 

public static int loadShader(int type, String shaderCode){ 

    // create a vertex shader type (GLES20.GL_VERTEX_SHADER) 
    // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER) 
    int shader = GLES20.glCreateShader(type); 

    // add the source code to the shader and compile it 
    GLES20.glShaderSource(shader, shaderCode); 
    GLES20.glCompileShader(shader); 

    return shader; 
} 

public void draw() { 
    // Add program to OpenGL ES environment 
    GLES20.glUseProgram(mProgram); 

    // get handle to vertex shader's vPosition member 
    int mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition"); 

    // Enable a handle to the triangle vertices 
    GLES20.glEnableVertexAttribArray(mPositionHandle); 

    // Prepare the triangle coordinate data 
    GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, 
           GLES20.GL_FLOAT, false, 
           vertexStride, vertexBuffer); 

    // get handle to fragment shader's vColor member 
    int mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor"); 

    // Set color for drawing the triangle 
    GLES20.glUniform4fv(mColorHandle, 1, color, 0); 

    // Draw the triangle 
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount); 

    // Disable vertex array 
    GLES20.glDisableVertexAttribArray(mPositionHandle); 
} 
} 

ответ

7

Проблема может быть эта строка:

Square square = new Square(); 

Поскольку он инициализируется перед вызовом "setRenderer". Конструктор для Square вызывает методы GLES20, которые могут вызвать проблему. Попробуйте создать экземпляр после вызова «setRenderer (render)»; или внутри метода onSurfaceCreated.

+0

Да, это была проблема. благодаря –