0
我製作了一個遊戲,可以正確繪製openGL形狀來屏蔽大部分遊戲。但出於某種原因,在遊戲中隨機間隔我得到了1282 glGetUniformLocation錯誤。奇怪的是,它有一段時間的工作,但後來失敗了?OpenGL 2.0 glGetUniformLocation:glError 1282 in draw()
這是堆棧跟蹤
12-12 12:31:54.781: E/AndroidRuntime(2531): FATAL EXCEPTION: GLThread 86993
12-12 12:31:54.781: E/AndroidRuntime(2531): Process: com.laytonlabs.android.levelup, PID: 2531
12-12 12:31:54.781: E/AndroidRuntime(2531): java.lang.RuntimeException: glGetUniformLocation: glError 1282
12-12 12:31:54.781: E/AndroidRuntime(2531): at com.laytonlabs.android.levelup.MyGLRenderer.checkGlError(MyGLRenderer.java:460)
12-12 12:31:54.781: E/AndroidRuntime(2531): at com.laytonlabs.android.levelup.shapes.Shape.draw(Shape.java:240)
12-12 12:31:54.781: E/AndroidRuntime(2531): at com.laytonlabs.android.levelup.MyGLRenderer.drawShapes(MyGLRenderer.java:350)
12-12 12:31:54.781: E/AndroidRuntime(2531): at com.laytonlabs.android.levelup.MyGLRenderer.drawFixedShapes(MyGLRenderer.java:324)
12-12 12:31:54.781: E/AndroidRuntime(2531): at com.laytonlabs.android.levelup.MyGLRenderer.onDrawFrame(MyGLRenderer.java:205)
12-12 12:31:54.781: E/AndroidRuntime(2531): at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1531)
12-12 12:31:54.781: E/AndroidRuntime(2531): at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1248)
這是生成錯誤(我想),內部Shape.java繪製()函數的部分。
Shape.java
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
MyGLRenderer.checkGlError("glGetUniformLocation");
的下面是用於錯誤堆棧所引用的Java類的完整代碼。
MyGLRenderer.java
package com.laytonlabs.android.levelup;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import com.laytonlabs.android.levelup.game.Cell;
import com.laytonlabs.android.levelup.game.CurrentAnswer;
import com.laytonlabs.android.levelup.game.Equation;
import com.laytonlabs.android.levelup.game.Game;
import com.laytonlabs.android.levelup.game.Level;
import com.laytonlabs.android.levelup.game.Score;
import com.laytonlabs.android.levelup.game.Stage;
import com.laytonlabs.android.levelup.game.Time;
import com.laytonlabs.android.levelup.shapes.Color;
import com.laytonlabs.android.levelup.shapes.EquationRectangle;
import com.laytonlabs.android.levelup.shapes.Hexagon;
import com.laytonlabs.android.levelup.shapes.InputSquare;
import com.laytonlabs.android.levelup.shapes.Shape;
import com.laytonlabs.android.levelup.shapes.StatsRectangle;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;
import android.util.Log;
public class MyGLRenderer implements GLSurfaceView.Renderer {
private static final String TAG = "MyGLRenderer";
private static StatsRectangle levelRectangle;
private static StatsRectangle timeRectangle;
private static StatsRectangle scoreRectangle;
private static EquationRectangle equationRectangle;
private static EquationRectangle answerRectangle;
private ArrayList<Shape> gridShapes;
private ArrayList<Shape> bottomRowShapes;
private static ArrayList<Shape> inputShapes;
// mMVPMatrix is an abbreviation for "Model View Projection Matrix"
private final float[] mMVPMatrix = new float[16];
private final float[] mMVPFixed = new float[16];
private final float[] mProjectionMatrix = new float[16];
private final float[] mViewMatrix = new float[16];
private final float[] mGridModelMatrix = new float[16];
private float[] mFixedModelMatrix = new float[16];
private float[] mTempMatrix = new float[16];
private float mMovementY;
private float mBottomRowScale;
private static String mAnswerText = CurrentAnswer.getLabel();
private boolean isCorrectGuess = false;
private boolean renderCorrectGuess = false;
private boolean isWrongGuess = false;
private boolean renderOutput = false;
//To limit the number of renders per second
private long startTime;
private long endTime;
private long timeElapsed;
private int currentFrame = 0; // active frame
private int outputCurrentFrame = 0; // active frame
private final int FPS = 33; // Frames per second
private final int FPS_ANIMATION_10 = 10;
private final int FPS_ANIMATION_20 = 20;
//Reducer values, these are used for animation scenes
private float mFPSMovementY;
private float mFPSBottomRowScale;
private int gridLevel = 0; //The cell layout level in the grid.
private int rowLevel = 1; //The current row in the grid user is selected.
//Constants for grid presentation
private final float CELL_SCALE = 0.3f;
private final float CELL_OFFSET_Y = 0.7f;
@Override
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
// Set the background frame color
GLES20.glClearColor(Color.DARK_GREY[0], Color.DARK_GREY[1], Color.DARK_GREY[2], Color.DARK_GREY[3]);
startTime = System.currentTimeMillis();
//TODO Add code that sets current answer to whatever the current answer is.
//Initialise fixed shapes
equationRectangle = new EquationRectangle(-0.35f);
answerRectangle = new EquationRectangle(-0.5f);
equationRectangle.setShapes(0.2f, Equation.get());
answerRectangle.setShapes(0.3f, mAnswerText);
//TODO - Change the below calculations to be align_left, align_centre, align_right, etc.
levelRectangle = new StatsRectangle(0 - (Screen.DEFAULT_WIDTH/3), Color.TURQUOISE, Color.TURQUOISE);
timeRectangle = new StatsRectangle(0, Color.PURPLE, Color.PURPLE);
scoreRectangle = new StatsRectangle(0 + (Screen.DEFAULT_WIDTH/3), Color.TURQUOISE, Color.TURQUOISE);
levelRectangle.setShapes(-1f, Level.getLabel());
scoreRectangle.setShapes(-1f, Score.getScoreLabel());
timeRectangle.setShapes(-1f, Time.getTimeRemainingLabel());
setGridShapes();
//Complete the bottom row for inputting guesses
bottomRowShapes = new ArrayList<Shape>();
setBottomRowShapes();
buildInputGrid();
setBottomRowScale(1.0f);
setFPSBottomRowScale(getBottomRowScale()/FPS_ANIMATION_20);
setFPSMovementY((CELL_OFFSET_Y*CELL_SCALE)/FPS_ANIMATION_20);
}
private void buildInputGrid() {
inputShapes = new ArrayList<Shape>();
inputShapes.add(new InputSquare(0.16f, -3.0f, 1.15f, "1")); //1
inputShapes.add(new InputSquare(0.16f, -1.8f, 1.15f, "2")); //2
inputShapes.add(new InputSquare(0.16f, -0.6f, 1.15f, "3")); //3
inputShapes.add(new InputSquare(0.16f, 0.6f, 1.15f, "4")); //4
inputShapes.add(new InputSquare(0.16f, 1.8f, 1.15f, "5")); //5
inputShapes.add(new InputSquare(0.16f, 3.0f, 1.15f, "6")); //6
inputShapes.add(new InputSquare(0.16f, -2.4f, 0, "7")); //7
inputShapes.add(new InputSquare(0.16f, -1.2f, 0, "8")); //8
inputShapes.add(new InputSquare(0.16f, 0, 0, "9")); //9
inputShapes.add(new InputSquare(0.16f, 1.2f, 0, "0")); //0
inputShapes.add(new InputSquare(0.16f, 2.4f, 0, "x")); //X - This is to clear input
}
@Override
public void onDrawFrame(GL10 unused) {
//We dont need continuous rendering, only needed for animation and time switching
endTime = System.currentTimeMillis();
timeElapsed = endTime - startTime;
if (timeElapsed < FPS) {
try {
Log.d(TAG, "Sleeping until "+FPS+" millsecs pass");
Thread.sleep(FPS - timeElapsed);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
startTime = endTime;
//Update the timers by deducting timeRemaining
Time.update();
Matrix.setIdentityM(mGridModelMatrix, 0); // initialize to identity matrix
//Setup the equation display before we start moving the grid around
Matrix.setIdentityM(mFixedModelMatrix, 0); // initialize to identity matrix
// Draw background color
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
// Enable transparency options for colors.
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
// Set the camera position (View matrix)
Matrix.setLookAtM(mViewMatrix, 0, 0, 0, 3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
// Calculate the projection and view transformation
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
//Clone this for use with fixed and grid MVPs
mTempMatrix = mMVPMatrix.clone();
// Create a rotation for the triangle
// Use the following code to generate constant rotation.
// Leave this code out when using TouchEvents.
// long time = SystemClock.uptimeMillis() % 4000L;
// float angle = 0.090f * ((int) time);
drawGridShapes();
drawFixedShapes();
}
private void drawGridShapes() {
//Start the grid drawing at bottom of screen.
Matrix.translateM(mGridModelMatrix, 0, 0, -0.1f, 0);
//Move the grid down or up the screen depending on touch events.
Matrix.translateM(mGridModelMatrix, 0, 0, mMovementY, 0);
// Combine the rotation matrix with the projection and camera view
// Note that the mMVPMatrix factor *must be first* in order
// for the matrix multiplication product to be correct.
//Matrix.multiplyMM(scratch, 0, mMVPMatrix, 0, mRotationMatrix, 0);
//Add the movement to the matrix
Matrix.multiplyMM(mMVPMatrix, 0, mTempMatrix, 0, mGridModelMatrix, 0);
if (isCorrectGuess()) {
renderCorrectGuess = true; //This is to change the answer text to green inside drawFixedShapes
currentFrame++; // step to next frame
setMovementY(getMovementY() - getFPSMovementY());
setBottomRowScale(getBottomRowScale() - getFPSBottomRowScale());
if (currentFrame >= FPS_ANIMATION_20) { // if end of sequence
currentFrame = 0; // restart sequence
setBottomRowScale(1.0f); // Reset the scale
removeBottomRow();
setCorrectGuess(false); //Mark as false so animation stops and user can make new guess
}
}
//Draw all grid shapes
if (isCorrectGuess()) {
drawAllShapesAndShrinkBottomRow(mMVPMatrix);
} else {
drawAllShapes(getGridShapes(), mMVPMatrix);
}
}
private void drawAllShapes(ArrayList<Shape> shapes, float[] mMVPMatrix) {
for (Shape shape : shapes) {
Log.d(TAG, "Scale Hexagon ("+shape.toString()+") Aft ("+shape.getCentreX()+", "+shape.getCentreY()+")");
drawShapes(shape, mMVPMatrix);
}
}
private void drawAllShapesAndShrinkBottomRow(float[] mMVPMatrix) {
float[] mMVPScaled = mMVPMatrix.clone();
Matrix.scaleM(mMVPScaled, 0, getBottomRowScale(), getBottomRowScale(), 0);
int lastCellIndex = getBottomRowLastCellIndex();
//Apply scaling to the bottom row and just move the other rows.
for (int i = 0; i < getGridShapes().size(); i++) {
if (i <= lastCellIndex) {
drawShapes(getGridShapes().get(i), mMVPScaled);
} else {
drawShapes(getGridShapes().get(i), mMVPMatrix);
}
}
}
private void drawFixedShapes() {
Matrix.multiplyMM(mMVPFixed, 0, mTempMatrix, 0, mFixedModelMatrix, 0);
if (isRenderOutput()) {
//Show the equation using the values from the selected cell.
equationRectangle.setShapes(0.2f, Equation.get());
answerRectangle.setShapes(0.3f, mAnswerText);
setRenderOutput(false);
}
//Update the time if time has changed
if (!timeRectangle.toString().equals(Time.getTimeRemainingLabel())) {
//If the time remaining is almost up then change text to red.
if (Time.isTimeAlmostUp()) {
timeRectangle.setShapes(-1f, Time.getTimeRemainingLabel(), Color.RED);
} else {
timeRectangle.setShapes(-1f, Time.getTimeRemainingLabel());
}
}
//Animation for changing color of the text
if (isWrongGuess()) {
if (outputCurrentFrame == 0) {
answerRectangle.setShapes(0.3f, mAnswerText, Color.RED);
}
outputCurrentFrame++;
if (outputCurrentFrame >= FPS_ANIMATION_10) {
outputCurrentFrame = 0;
setAnswerText("");
answerRectangle.setShapes(0.3f, mAnswerText);
setWrongGuess(false);
}
} else if (renderCorrectGuess) {
if (outputCurrentFrame == 0) {
answerRectangle.setShapes(0.3f, mAnswerText, Color.GREEN);
levelRectangle.setShapes(-1f, Level.getLabel(), Color.YELLOW);
scoreRectangle.setShapes(-1f, Score.getScoreLabel(), Color.YELLOW);
timeRectangle.setShapes(-1f, Time.getTimeRemainingLabel(), Color.YELLOW);
}
outputCurrentFrame++;
if (outputCurrentFrame >= FPS_ANIMATION_20) {
outputCurrentFrame = 0;
answerRectangle.setShapes(0.3f, mAnswerText);
levelRectangle.setShapes(-1f, Level.getLabel());
scoreRectangle.setShapes(-1f, Score.getScoreLabel());
timeRectangle.setShapes(-1f, Time.getTimeRemainingLabel());
setGridShapes();
renderCorrectGuess = false;
}
}
drawShapes(answerRectangle, mMVPFixed);
drawShapes(equationRectangle, mMVPFixed);
drawShapes(levelRectangle, mMVPFixed);
drawShapes(timeRectangle, mMVPFixed);
drawShapes(scoreRectangle, mMVPFixed);
//Draw all input grid shapess
drawAllShapes(inputShapes, mMVPFixed);
}
public static void printStack() {
Log.e(TAG,"Level: " + Level.getLabel());
Log.e(TAG,"Score: " + Score.getScoreLabel());
Log.e(TAG,"Time: " + Time.getTimeRemainingLabel());
Log.e(TAG,"mAnswerText: " + mAnswerText);
Log.e(TAG,"Equation: " + Equation.get());
for (int i = 0; i < inputShapes.size(); i++) {
Log.e(TAG,"inputShapes[" + i + "]: " + inputShapes.get(i).toString());
}
}
private void drawShapes(Shape parentShape, float[] mMVPMatrix) {
parentShape.draw(mMVPMatrix);
if (parentShape.getShapes() == null) {
return;
}
for (Shape nestedShapes : parentShape.getShapes()) {
nestedShapes.draw(mMVPMatrix);
}
}
private ArrayList<Shape> getGridShapes() {
return gridShapes;
}
private int getBottomRowLastCellIndex() {
int lastCellIndex = 0;
Shape prevShape = null;
for (int i = 0; i < getGridShapes().size(); i++) {
if (prevShape == null || getGridShapes().get(i).getCentreY() == prevShape.getCentreY()) {
lastCellIndex = i;
prevShape = getGridShapes().get(i);
} else {
return lastCellIndex;
}
}
return lastCellIndex;
}
private void removeBottomRow() {
for (int i = getBottomRowLastCellIndex(); i >= 0 ; i--) {
getGridShapes().remove(i);
}
//Reset the bottom row shapes
setBottomRowShapes();
}
public ArrayList<Shape> getBottomRowShapes() {
return bottomRowShapes;
}
private void setBottomRowShapes() {
ArrayList<Shape> tempRowShapes = new ArrayList<Shape>();
//Apply scaling to the bottom row and just move the other rows.
for (int i = 0; i <= getBottomRowLastCellIndex(); i++) {
tempRowShapes.add(getGridShapes().get(i));
}
bottomRowShapes = tempRowShapes;
}
@Override
public void onSurfaceChanged(GL10 unused, int width, int height) {
// Adjust the viewport based on geometry changes,
// such as screen rotation
GLES20.glViewport(0, 0, width, height);
//Log.d("MyGLRenderer", "Width: " + width + " Height: " + height);
float ratio = (float) width/height;
Log.d("Screen","Width: "+ width +" - Height: "+ height +" - Ratio: "+ ratio);
// this projection matrix is applied to object coordinates
// in the onDrawFrame() method
if (ratio > 1) {
ratio = Screen.DEFAULT_LANDSCAPE_RATIO;
} else {
ratio = Screen.DEFAULT_PORTRAIT_RATIO;
}
Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
//TODO Store the current answer, the current answer Text and the current Equation.
}
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 static void checkGlError(String glOperation) {
int error;
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
Log.e(TAG, glOperation + ": 1glError " + error);
printStack();
//TODO - Print out the fixed shapes values to see if something wierd is being displayed after a while.
throw new RuntimeException(glOperation + ": glError " + error);
}
}
public float getMovementY() {
return mMovementY;
}
public void setMovementY(float movementY) {
mMovementY = movementY;
}
public float[] getProjectionMatrix() {
return mProjectionMatrix;
}
public float[] getGridModelMatrix() {
return mGridModelMatrix;
}
public float[] getFixedModelMatrix() {
return mFixedModelMatrix;
}
public String getAnswerText() {
return mAnswerText;
}
public void setAnswerText(String guessInput) {
if (guessInput == "") {
this.mAnswerText = getInputUnderscores();
return;
}
this.mAnswerText = this.mAnswerText.replaceFirst("_", guessInput);
}
public void resetAnswerText() {
this.mAnswerText = CurrentAnswer.getLabel();
}
private String getInputUnderscores() {
if (Equation.getExpectedAnswer() <= 0) {
return "";
}
return Equation.getExpectedAnswerLabel().replaceAll("[0-9]", "_");
}
public ArrayList<Shape> getInputShapes() {
return inputShapes;
}
Shape.java
package com.laytonlabs.android.levelup.shapes;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import java.util.ArrayList;
import android.opengl.GLES20;
import com.laytonlabs.android.levelup.MyGLRenderer;
import com.laytonlabs.android.levelup.Vec2;
import com.laytonlabs.android.levelup.game.Cell;
/**
* A two-dimensional square for use as a drawn object in OpenGL ES 2.0.
*/
public abstract class Shape {
private final String TAG = "Shape";
private final String vertexShaderCode =
// This matrix member variable provides a hook to manipulate
// the coordinates of the objects that use this vertex shader
"uniform mat4 uMVPMatrix;" +
"attribute vec4 vPosition;" +
"void main() {" +
// The matrix must be included as a modifier of gl_Position.
// Note that the uMVPMatrix factor *must be first* in order
// for the matrix multiplication product to be correct.
" gl_Position = uMVPMatrix * vPosition;" +
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
"void main() {" +
" gl_FragColor = vColor;" +
"}";
private final FloatBuffer vertexBuffer;
private final ShortBuffer drawListBuffer;
private final int mProgram;
private int mPositionHandle;
private int mColorHandle;
private int mMVPMatrixHandle;
protected float[] shapeCoords;
private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex
// number of coordinates per vertex in this array
static final int COORDS_PER_VERTEX = 3;
//These will be initiated by the abstract class
private final float[] ORIGINAL_COORDS;
private final short[] DRAW_ORDER; // order to draw vertices
//#RGB: white (255, 255, 255)
private final float[] COLOR;
//Sets the scale of the shape and where the X centre is.
private final float SCALE;
private final float CENTRE_X;
private final float CENTRE_Y;
public abstract float getCentreX();
public abstract float getCentreY();
public float[] getNestedTextColor() {
return null;
}
public void setNestedTextColor(float[] textColor) {}
public Cell getCell() {
return null;
}
public ArrayList<Shape> getShapes() {
return null;
}
public void setShapes(float scale, String nestedText) {}
public void setShapes(float scale, String nestedText, float[] textColor) {}
public boolean intersects(Vec2 touchCoords) {
return false;
}
public float getMinX() {return getMin(getArraySubset(0));}
public float getMaxX() {return getMax(getArraySubset(0));}
public float getMinY() {return getMin(getArraySubset(1));}
public float getMaxY() {return getMax(getArraySubset(1));}
private float getMin(float[] values) {
float minVal = 1000f;
for (float value : values) {
if (value < minVal) {
minVal = value;
}
}
return minVal;
}
private float getMax(float[] values) {
float maxVal = -1000f;
for (float value : values) {
if (value > maxVal) {
maxVal = value;
}
}
return maxVal;
}
private float[] getArraySubset(int offset) {
if (shapeCoords == null || shapeCoords.length == 0) {
return null;
}
float[] subsetArray = new float[shapeCoords.length/COORDS_PER_VERTEX];
int subsetIndex = 0;
for (int i = offset; i < shapeCoords.length; i=(i+COORDS_PER_VERTEX)) {
subsetArray[subsetIndex] = shapeCoords[i];
subsetIndex++;
}
return subsetArray;
}
/**
* Sets up the drawing object data for use in an OpenGL ES context.
*/
public Shape(float[] originalCoords, short[] drawOrder, float[] color,
float scale, float centreX, float centreY) {
this.ORIGINAL_COORDS = originalCoords;
this.DRAW_ORDER = drawOrder;
this.COLOR = color;
this.SCALE = scale;
this.CENTRE_X = centreX;
this.CENTRE_Y = centreY;
this.shapeCoords = ORIGINAL_COORDS.clone();
adjustShape(scale, centreX, centreY);
//Resize based on the scale
//adjustSize(scale);
// initialize vertex byte buffer for shape coordinates
ByteBuffer bb = ByteBuffer.allocateDirect(
// (# of coordinate values * 4 bytes per float)
shapeCoords.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(shapeCoords);
vertexBuffer.position(0);
// initialize byte buffer for the draw list
ByteBuffer dlb = ByteBuffer.allocateDirect(
// (# of coordinate values * 2 bytes per short)
DRAW_ORDER.length * 2);
dlb.order(ByteOrder.nativeOrder());
drawListBuffer = dlb.asShortBuffer();
drawListBuffer.put(DRAW_ORDER);
drawListBuffer.position(0);
// prepare shaders and OpenGL program
int vertexShader = MyGLRenderer.loadShader(
GLES20.GL_VERTEX_SHADER,
vertexShaderCode);
int fragmentShader = MyGLRenderer.loadShader(
GLES20.GL_FRAGMENT_SHADER,
fragmentShaderCode);
mProgram = GLES20.glCreateProgram(); // create empty OpenGL Program
GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program
GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
GLES20.glLinkProgram(mProgram); // create OpenGL program executables
}
//Adjust the original scale of the shape and position
private void adjustShape(float scale, float centreX, float centreY) {
for (int i = 0; i < shapeCoords.length; i++) {
//Apply the scale
shapeCoords[i] = (ORIGINAL_COORDS[i] * scale);
//Apply the x offset
shapeCoords[i] += (i % 3 == 0 ? centreX : 0);
//Apply the y offset
shapeCoords[i] += (i % 3 == 1 ? centreY : 0);
}
}
/**
* Encapsulates the OpenGL ES instructions for drawing this shape.
*
* @param mvpMatrix - The Model View Project matrix in which to draw
* this shape.
*/
public void draw(float[] mvpMatrix) {
// Add program to OpenGL environment
GLES20.glUseProgram(mProgram);
// get handle to vertex shader's vPosition member
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
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
// Set color for drawing the triangle
GLES20.glUniform4fv(mColorHandle, 1, COLOR, 0);
// get handle to shape's transformation matrix
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
MyGLRenderer.checkGlError("glGetUniformLocation");
// Apply the projection and view transformation
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
MyGLRenderer.checkGlError("glUniformMatrix4fv");
// Draw the square
GLES20.glDrawElements(
GLES20.GL_TRIANGLES, DRAW_ORDER.length,
GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
// Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
}
感謝您的答覆。我對opengl很新,所以我很幸運,避免了很多錯誤。我會研究這個鏈接處理程序的Java版本,但是您提供的代碼會在失敗之前嘗試修復問題嗎?從我的代碼中可以看到,如果鏈接失敗,它的應用程序出錯了嗎? –
@MatthewLayton:它從該函數返回。你用這個回報值做什麼取決於你。 –
好的,我添加了你建議的代碼。下面是java版本,但它仍然崩潰?當我看到InfoLog的輸出時,它不顯示任何內容?我看到的只是這個錯誤。那麼這是一個記憶問題? '12-14 09:09:35.889:I/System.out(16537):得到鏈接狀態 12-14 09:09:35.889:E/Shape(16537):程序鏈接錯誤: 12-14 09: 09:35.889:W/Adreno-GSL(16537)::sharedmem_gpumem_alloc:mmap失敗errno 1不允許操作 12-14 09:09:35.889:E/Adreno-GSL(16537)::GSL MEM ERROR:kgsl_sharedmem_alloc ioctl failed.' –