Why is my list of objects all the same? - android
I've been making lists of objects for a while now to make multiple objects in the games I program. I haven't had an issue until now. I use a for loop to create 3 objects, give each object its own values, and then add them to the array list. Unfortunately, when I tried this each object had the same values, which I figured out through logs were the values of the last item in the list. I'm not sure what I'm doing wrong. Here is the code I'm using(I apologize. It's very sloppy, I'm just trying to program the core of this project currently. There is a lot of useless code/poorly programmed code/incorrectly programmed code, I know)
GLCircle.java(the object I want to make multiple of):
package com.background.gl.objects;
import static android.opengl.GLES20.GL_TRIANGLE_FAN;
import static android.opengl.GLES20.glDrawArrays;
import static android.opengl.Matrix.multiplyMM;
import static android.opengl.Matrix.setIdentityM;
import static android.opengl.Matrix.translateM;
import static com.background.gl.glcirclebackgroundanimation.Constants.BYTES_PER_FLOAT;
import java.util.Random;
import android.opengl.Matrix;
import com.background.gl.data.VertexArray;
import com.background.gl.glcirclebackgroundanimation.CircleHandler;
import com.background.gl.helper.TextureShaderProgram;
public class GLCircle {
private static final int POSITION_COMPONENT_COUNT = 2;
private static final int TEXTURE_COORDINATES_COMPONENT_COUNT = 2;
private static final int STRIDE = (POSITION_COMPONENT_COUNT
+ TEXTURE_COORDINATES_COMPONENT_COUNT) * BYTES_PER_FLOAT;
public static float x;
public static float y;
protected static float[] wallBounds;
protected static boolean positiveX, positiveY;
public static boolean nullify;
protected static float xCounter = 0f;
protected static float yCounter = 0f;
public static float[] bounds;
protected Random ran;
private static final float[] VERTEX_DATA = {
// Order of coordinates: X, Y, S, T
// Triangle Fan
0f, 0f, 0.5f, 0.5f,
-0.25f, -0.25f, 0f, 0.9f,
0.25f, -0.25f, 1f, 0.9f,
0.25f, 0.25f, 1f, 0.1f,
-0.25f, 0.25f, 0f, 0.1f,
-0.25f, -0.25f, 0f, 0.9f };
private final VertexArray vertexArray;
public GLCircle(float x, float y) {
vertexArray = new VertexArray(VERTEX_DATA);
ran = new Random();
wallBounds = new float[4];
nullify = false;
this.x = x;
this.y = y;
}
public void bindData(TextureShaderProgram textureProgram) {
//Bind the position data to the shader attribute
vertexArray.setVertexAttribPointer(
0,
textureProgram.getPositionAttributeLocation(),
POSITION_COMPONENT_COUNT,
STRIDE);
//Bind the texture coordinate data to the shader attribute
vertexArray.setVertexAttribPointer(
POSITION_COMPONENT_COUNT,
textureProgram.getTextureCoordinatesAttributeLocation(),
TEXTURE_COORDINATES_COMPONENT_COUNT,
STRIDE);
}
public void drawCircle() {
glDrawArrays(GL_TRIANGLE_FAN, 0, 6);
}
public float getX() {
return this.x;
}
public float getY() {
return this.y;
}
public static boolean isPositiveX() {
return positiveX;
}
public static boolean isPositiveY() {
return positiveY;
}
public float[] getBounds(float ranX, float ranY) {
if(!positiveX) {
/*if(ranX >= 0f) {
wallBounds[0] = 1.05f + ranX;
} else {*/
this.wallBounds[0] = 1.05f + ranX;
//}
} else {
/*
if(ranX >= 0f) {
wallBounds[0] = 1.05f - ranX;
} else {*/
this.wallBounds[1] = 1.05f - ranX;
//}
}
if(!positiveY) {
this.wallBounds[2] = 1.75f + ranY;
} else {
this.wallBounds[3] = 1.75f - ranY;
}
return this.wallBounds;
}
public void setPos(float[] modelMatrix,
float[] projectionMatrix, TextureShaderProgram textureProgram,
int texture, float x, float y) {
setIdentityM(modelMatrix, 0);
if(!nullify)
translateM(modelMatrix, 0, 0f, 0.01f, 0f);
else
translateM(modelMatrix, 0, 0f, 0f, 0f);
final float[] temp = new float[16];
multiplyMM(temp, 0, projectionMatrix, 0, modelMatrix, 0);
System.arraycopy(temp, 0, projectionMatrix, 0, temp.length);
textureProgram.useProgram();
textureProgram.setUniforms(projectionMatrix, texture);
bindData(textureProgram);
drawCircle();
}
public void draw(float velocity, float[] modelMatrix,
float[] projectionMatrix, TextureShaderProgram textureProgram,
int texture) {
xCounter+=0.001f;
setIdentityM(modelMatrix, 0);
if(-x < -1.75f) {
translateM(modelMatrix, 0, 0f, 0.001f, 0f);
} else {
translateM(modelMatrix, 0, 0f, -0.001f, 0f);
}
final float[] temp = new float[16];
multiplyMM(temp, 0, projectionMatrix, 0, modelMatrix, 0);
System.arraycopy(temp, 0, projectionMatrix, 0, temp.length);
textureProgram.useProgram();
textureProgram.setUniforms(projectionMatrix, texture);
bindData(textureProgram);
drawCircle();
}
public void scaleCircle(float[] modelMatrix, float x, float y, float z) {
Matrix.scaleM(modelMatrix, 0, x, y, z);
}
public void storeResults(float[] results) {
this.x = results[0];
this.y = results[1];
}
}
This is how I create the multiple objects:
for(int i = 0; i < 3; i++) {
GLCircle circle = new GLCircle(generateRanFloats()[0], generateRanFloats()[1]);
circles.add(circle);
/*circle[i].x = circle[i].getX();
circle[i].y = circle[i].getY();
circle[i].bounds = circle[i].getBounds();*/
}
And this is the generateranFloats() method:
public float[] generateRanFloats() {
ranSignX = ran.nextFloat();
ranSignY = ran.nextFloat();
ranSignX = ranSignX > 0.5f? -1:1;
ranSignY = ranSignY > 0.5f? -1:1;
ranSignVeloX = ran.nextFloat();
ranSignVeloY = ran.nextFloat();
ranX = ran.nextFloat() * 1.05f;
ranY = ran.nextFloat() * 1.75f;
ranX = ranSignX > 0.5? -ranX:ranX;
ranY = ranSignY > 0.5? -ranY:ranY;
Log.d("Generated", Float.toString(ranX));
return new float[] {ranX, ranY};
}
Why do all of the objects contain the same values(such as x and y)?
The answer is simple
Your x, y variables are declared as static, meaning all instances of your object share the same variables.
By the way, this line
GLCircle circle = new GLCircle(generateRanFloats()[0], generateRanFloats()[1]);
is doing double work, you're calling generateRanFloats twice, and you use half of the generated information every time.
Related
Cast remote display android Nullpointer
When we click on change color button nullpointer exception in CubeRender class. java.lang.NullPointerException: Attempt to invoke virtual method 'void CubeRenderer.changeColor()' on a null object reference java class public class CubeRenderer implements GLSurfaceView.Renderer { private static final String TAG = "CubeRenderer"; private static final float ANGLE_INCREMENT = 1.2f; private static final boolean CALCULATE_FPS = false; private Cube mCube; private float mAngle; private boolean mChangeColor; private long mLastTime; private long mFpsCounter; protected final float[] mMMatrix = new float[16]; protected final float[] mMVMatrix = new float[16]; protected final float[] mMVPMatrix = new float[16]; protected final float[] mProjectionMatrix = new float[16]; protected final float[] mViewMatrix = new float[16]; protected final float[] mRotationMatrix = new float[16]; public void onDrawFrame(GL10 unused) { if (CALCULATE_FPS) { long currentTime = SystemClock.uptimeMillis(); if (mLastTime == 0) { mLastTime = currentTime; } else { mFpsCounter++; long diffTime = currentTime - mLastTime; if (diffTime >= 1000) { Log.d(TAG, "fps=" + mFpsCounter); mFpsCounter = 0; mLastTime = currentTime; } } } GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); // Set the camera position Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -10, 0f, 0f, 0f, 0f, 1.0f, 0.0f); // Configure matrices for first cube Matrix.setIdentityM(mMMatrix, 0); Matrix.translateM(mMMatrix, 0, 0.0f, -0.5f, -1.5f); Matrix.setRotateM(mRotationMatrix, 0, 2 * mAngle, 0.0f, 1.0f, 1.0f); Matrix.multiplyMM(mMMatrix, 0, mRotationMatrix, 0, mMMatrix, 0); Matrix.multiplyMM(mMVMatrix, 0, mViewMatrix, 0, mMMatrix, 0); Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVMatrix, 0); mCube.draw(mMVPMatrix, mChangeColor); // Configure matrices for second cube Matrix.setIdentityM(mMMatrix, 0); Matrix.translateM(mMMatrix, 0, 0.0f, 2.0f, 0.0f); Matrix.setRotateM(mRotationMatrix, 0, -mAngle, 0.0f, 1.0f, 1.0f); Matrix.multiplyMM(mMMatrix, 0, mRotationMatrix, 0, mMMatrix, 0); Matrix.multiplyMM(mMVMatrix, 0, mViewMatrix, 0, mMMatrix, 0); Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVMatrix, 0); mCube.draw(mMVPMatrix, mChangeColor); mAngle += ANGLE_INCREMENT; } public void onSurfaceChanged(GL10 unused, int width, int height) { float ratio = (float) width / height; GLES20.glViewport(0, 0, width, height); // Configure perspective with field of view float fov = 30.0f; float near = 1.0f; float far = 100.0f; float top = (float) Math.tan(fov * Math.PI / 360.0f) * near; float bottom = -top; float left = ratio * bottom; float right = ratio * top; Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far); } public void onSurfaceCreated(GL10 unused, EGLConfig config) { // Set background color GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Depth handling GLES20.glEnable(GLES20.GL_DEPTH_TEST); GLES20.glDepthFunc(GLES20.GL_LEQUAL); // Set anti-aliasing GLES20.glEnable(GLES20.GL_BLEND); GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); // Important to initialize the graphics on the GL thread mCube = new Cube(); } /** * Utility method to allow the user to change the cube color. */ public void changeColor() { mChangeColor = !mChangeColor; } } Accessing CubeRenderer class method mCubeRenderer.changeColor() exact place where null pointer exception need to handle public class PresentationService extends CastRemoteDisplayLocalService { private static final String TAG = "PresentationService"; // First screen private CastPresentation mPresentation; private MediaPlayer mMediaPlayer; private CubeRenderer mCubeRenderer; #Override public void onCreate() { super.onCreate(); // Audio mMediaPlayer = MediaPlayer.create(this, R.raw.sound); mMediaPlayer.setVolume((float) 0.1, (float) 0.1); mMediaPlayer.setLooping(true); } #Override public void onCreatePresentation(Display display) { createPresentation(display); } #Override public void onDismissPresentation() { dismissPresentation(); } private void dismissPresentation() { if (mPresentation != null) { mMediaPlayer.stop(); mPresentation.dismiss(); mPresentation = null; } } private void createPresentation(Display display) { dismissPresentation(); mPresentation = new TVPresentation(this, display); try { mPresentation.show(); mMediaPlayer.start(); } catch (WindowManager.InvalidDisplayException ex) { Log.e(TAG, "Unable to show presentation, display was removed.", ex); dismissPresentation(); } } /** * Utility method to allow the user to change the cube color. */ public void changeColor() { mCubeRenderer.changeColor(); } }
Problem solved mCubeRenderer= new CubeRenderer(); need to add this line in PresentationService class
android opengl es 2 display after several rotate error
I am trying to draw lines connected to each other. Let's say they are creating a rectangle. At each corner also I have points. When I have tested code in my Samsung Galaxy Note 4 after several rotations, using touch, all rectangle ended up with a single point at the center. I could not figure out why this was happening. Code works fine in emulator. Also I am storing line and point data as array list in my code. These array lists are used to create line and point object classes to render. public class GLRender implements GLSurfaceView.Renderer { private final float[] mMVPMatrix = new float[16]; private final float[] mProjectionMatrix = new float[16]; private final float[] mViewMatrix = new float[16]; private float[] mRotationMatrix = new float[16]; private float[] mVRMatrix = new float[16]; private static ArrayList<Line> DrLine = new ArrayList<Line>(); private static ArrayList<Point> DrPoint = new ArrayList<Point>(); private float ratio; private float Joint1; private float Joint2; private float x1, y1, z1, x2, y2, z2; private float px, py, pz, ps; private float[] nearN = new float[4]; private static ArrayList<ArrayList<String>> LineArray = new ArrayList<ArrayList<String>>(); private ArrayList<String> L = new ArrayList<String>(); private ArrayList<String> P = new ArrayList<String>(); private static ArrayList<ArrayList<String>> PointArray = new ArrayList<ArrayList<String>>(); private static ArrayList<String> EmptyLine = new ArrayList<String>(); private static ArrayList<String> EmptyPoint = new ArrayList<String>(); private static ArrayList<ArrayList<ArrayList<String>>> UndoL = new ArrayList<ArrayList<ArrayList<String>>>(); private static ArrayList<ArrayList<ArrayList<String>>> UndoP = new ArrayList<ArrayList<ArrayList<String>>>(); public GLRender(Activity activity) { } public void onSurfaceCreated(GL10 unused, EGLConfig config) { // Set the background frame color //GLES20.glClearColor(0.53f, 0.53f, 0.53f, 1.0f); GLES20.glClearColor(0.474f, 0.537f, 0.078f, 1.0f); } public void onDrawFrame(GL10 unused) { GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); Drawer(); Line XLine = new Line(); XLine.SetVerts(0.0f, 0.0f, 0.0f, 1.0f / 10, 0.0f, 0.0f); XLine.SetColor(1.0f, 0.0f, 0.0f, 1.0f); Line YLine = new Line(); YLine.SetVerts(0.0f, 0.0f, 0.0f, 0.0f, 1.0f / 10, 0.0f); YLine.SetColor(0.0f, 1.0f, 0.0f, 1.0f); Line ZLine = new Line(); ZLine.SetVerts(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f / 10); ZLine.SetColor(0.0f, 0.0f, 1.0f, 1.0f); Matrix.setIdentityM(mViewMatrix, 0); Matrix.setLookAtM(mViewMatrix, 0, 0, 0, 1.0f , 0f, 0f, 0f, 0f, 1.0f, 0.0f); Matrix.setIdentityM(mRotationMatrix, 0); Matrix.rotateM(mRotationMatrix, 0, mXAngle, 0, 1f, 0); Matrix.rotateM(mRotationMatrix, 0, mYAngle, 1f, 0, 0); Matrix.setIdentityM(mVRMatrix, 0); Matrix.multiplyMM(mVRMatrix, 0, mViewMatrix, 0, mRotationMatrix, 0); Matrix.setIdentityM(mMVPMatrix, 0); Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mVRMatrix, 0); Matrix.scaleM(mMVPMatrix,0,mScale,mScale,mScale); if (DrLine.size() > 0) { for (Line LineX : DrLine) { LineX.draw(mMVPMatrix); } } if (DrPoint.size() > 0) { for (Point PointX : DrPoint) { PointX.draw(mMVPMatrix); } } XLine.draw(mMVPMatrix); YLine.draw(mMVPMatrix); ZLine.draw(mMVPMatrix); } public void onSurfaceChanged(GL10 unused, int width, int height) { GLES20.glViewport(0, 0, width, height); ratio = (float) width / height; //Matrix.frustumM(mProjectionMatrix, 0, -ratio*10, ratio*10, -10, 10, 1, 9); Matrix.orthoM(mProjectionMatrix, 0, -ratio, ratio, -1.0f, 1.0f, -5.0f, 5.0f); } 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; } private Float TempMaxPointHolder = 0.0f; private Float MaxPointHolder = 0.0f; public Float Scaler(){ Float TempScaler = 1.0f; Iterator<ArrayList<String>> MaxPointFinder = PointArray.iterator(); while (MaxPointFinder.hasNext()){ ArrayList<String> MaxPoint = MaxPointFinder.next(); TempMaxPointHolder = Math.abs(Math.max(Math.max(Float.parseFloat(MaxPoint.get(1)),Float.parseFloat(MaxPoint.get(2))),Float.parseFloat(MaxPoint.get(3)))); if (TempMaxPointHolder > MaxPointHolder){ MaxPointHolder = TempMaxPointHolder; } } TempScaler = 0.9f / MaxPointHolder; return TempScaler; } public void Drawer(){ Float Scaler = Scaler(); Integer Lindex = 0; ArrayList<Point> TempDrPoint = new ArrayList<Point>(); ArrayList<Line> TempDrLine = new ArrayList<Line>(); Iterator<ArrayList<String>> Litr = LineArray.iterator(); while (Litr.hasNext()) { L = Litr.next(); Joint1 = Float.parseFloat(L.get(1)); Joint2 = Float.parseFloat(L.get(2)); Iterator<ArrayList<String>> PitrL = PointArray.iterator(); while (PitrL.hasNext()){ P = PitrL.next(); if (Float.parseFloat(P.get(0)) == Joint1) { x1 = Float.parseFloat(P.get(1)) * Scaler; y1 = Float.parseFloat(P.get(2)) * Scaler; z1 = Float.parseFloat(P.get(3)) * Scaler; } if (Float.parseFloat(P.get(0)) == Joint2) { x2 = Float.parseFloat(P.get(1)) * Scaler; y2 = Float.parseFloat(P.get(2)) * Scaler; z2 = Float.parseFloat(P.get(3)) * Scaler; } } Line TempLine = new Line(); TempLine.SetVerts(x1, y1, z1, x2, y2, z2); if (L.get(3) == "0") { TempLine.SetColor(0.0f, 0.0f, 0.0f, 1.0f); } else if (L.get(3) == "1"){ TempLine.SetColor(0.66f, 0.73f, 0.21f, 1.0f); } TempDrLine.add(TempLine); Lindex = Lindex + 1; } setDrLine(TempDrLine); Integer Pindex = 0; Iterator<ArrayList<String>> Pitr = PointArray.iterator(); while (Pitr.hasNext()){ P = Pitr.next(); px = Float.parseFloat(P.get(1)) * Scaler; py = Float.parseFloat(P.get(2)) * Scaler; pz = Float.parseFloat(P.get(3)) * Scaler; ps = Float.parseFloat(P.get(4)); Point TempPoint = new Point(); TempPoint.SetPointVerts(px, py, pz); if (ps == 0.0f) { TempPoint.SetPointColor(0.65f, 0.37f, 0.11f, 1.0f); } else if (ps == 1.0f) { TempPoint.SetPointColor(0.68f, 0.07f, 0.32f, 1.0f); } TempDrPoint.add(TempPoint); Pindex = Pindex + 1; } setDrPoint(TempDrPoint); } public volatile float mXAngle; public volatile float mYAngle; public ArrayList<Line> getDrLine() { return DrLine; } public ArrayList<Point> getDrPoint(){ return DrPoint; } public void setDrLine(ArrayList<Line> XDrLine) { DrLine = XDrLine; } public void setDrPoint(ArrayList<Point> XDrPoint) { DrPoint = XDrPoint; } public float getXAngle() { return mXAngle; } public float getYAngle(){ return mYAngle; } public void setAngleX(float Xangle) { mXAngle = Xangle; } public void setAngleY(float Yangle) { mYAngle = Yangle; } public volatile float mScale = 1; public volatile float mXFocus; public volatile float mYFocus; public void setZoom(float scale){ mScale = scale; } public void setFocus(float XFocus, float YFocus){ mXFocus = XFocus; mYFocus = YFocus; } public float getmScale(){ return mScale; } public float getmXFocus(){ return mXFocus; } public float getmYFocus(){ return mYFocus; } public void setLineArray(ArrayList<ArrayList<String>> XLine){ LineArray = XLine; } public ArrayList<ArrayList<String>> getLineArray(){ return LineArray; } public void setUndoL(ArrayList<ArrayList<String>> UndoLine){ this.UndoL.add(new ArrayList<ArrayList<String>>(UndoLine)); } public ArrayList<ArrayList<ArrayList<String>>> getUndoL() { return UndoL; } public void setUndoP(ArrayList<ArrayList<String>> UndoPoint){ this.UndoP.add(new ArrayList<ArrayList<String>>(UndoPoint)); } public ArrayList<ArrayList<ArrayList<String>>> getUndoP() { return UndoP; } public void setPointArray(ArrayList<ArrayList<String>> XPoint){ PointArray = XPoint; } public ArrayList<ArrayList<String>> getPointArray(){ return PointArray; } gives error contents_sample_state: [ agr({[3 ,38]=11, [3 ,7 ,38]=28}) ] public class Line { private FloatBuffer VertexBuffer; 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 " gl_Position = uMVPMatrix * vPosition;" + "}"; private final String FragmentShaderCode = "precision mediump float;" + "uniform vec4 vColor;" + "void main() {" + " gl_FragColor = vColor;" + "}"; protected int GlProgram; protected int PositionHandle; protected int ColorHandle; protected int MVPMatrixHandle; // number of coordinates per vertex in this array static final int COORDS_PER_VERTEX = 3; static float LineCoords[] = { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }; private final int VertexCount = LineCoords.length / COORDS_PER_VERTEX; private final int VertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex // Set color with red, green, blue and alpha (opacity) values float color[] = { 0.0f, 0.0f, 0.0f, 1.0f }; public Line() { // initialize vertex byte buffer for shape coordinates ByteBuffer bb = ByteBuffer.allocateDirect( // (number of coordinate values * 4 bytes per float) LineCoords.length * 4); // use the device hardware's native byte order bb.order(ByteOrder.nativeOrder()); // create a floating point buffer from the ByteBuffer VertexBuffer = bb.asFloatBuffer(); // add the coordinates to the FloatBuffer VertexBuffer.put(LineCoords); // set the buffer to read the first coordinate VertexBuffer.position(0); int vertexShader = GLRender.loadShader(GLES20.GL_VERTEX_SHADER, VertexShaderCode); int fragmentShader = GLRender.loadShader(GLES20.GL_FRAGMENT_SHADER, FragmentShaderCode); GlProgram = GLES20.glCreateProgram(); // create empty OpenGL ES Program GLES20.glAttachShader(GlProgram, vertexShader); // add the vertex shader to program GLES20.glAttachShader(GlProgram, fragmentShader); // add the fragment shader to program GLES20.glLinkProgram(GlProgram); // creates OpenGL ES program executables } public void SetVerts(float v0, float v1, float v2, float v3, float v4, float v5) { LineCoords[0] = v0; LineCoords[1] = v1; LineCoords[2] = v2; LineCoords[3] = v3; LineCoords[4] = v4; LineCoords[5] = v5; VertexBuffer.put(LineCoords); // set the buffer to read the first coordinate VertexBuffer.position(0); } public void SetColor(float red, float green, float blue, float alpha) { color[0] = red; color[1] = green; color[2] = blue; color[3] = alpha; } public void draw(float[] mvpMatrix) { // Add program to OpenGL ES environment GLES20.glUseProgram(GlProgram); // get handle to vertex shader's vPosition member PositionHandle = GLES20.glGetAttribLocation(GlProgram, "vPosition"); // Enable a handle to the triangle vertices GLES20.glEnableVertexAttribArray(PositionHandle); // Prepare the triangle coordinate data GLES20.glVertexAttribPointer(PositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, VertexStride, VertexBuffer); // get handle to fragment shader's vColor member ColorHandle = GLES20.glGetUniformLocation(GlProgram, "vColor"); // Set color for drawing the triangle GLES20.glUniform4fv(ColorHandle, 1, color, 0); // get handle to shape's transformation matrix MVPMatrixHandle = GLES20.glGetUniformLocation(GlProgram, "uMVPMatrix"); //GLRender.checkGlError("glGetUniformLocation"); // Apply the projection and view transformation GLES20.glUniformMatrix4fv(MVPMatrixHandle, 1, false, mvpMatrix, 0); //GLRender.checkGlError("glUniformMatrix4fv"); GLES20.glLineWidth(5); // Draw the triangle GLES20.glDrawArrays(GLES20.GL_LINES, 0, VertexCount); // Disable vertex array GLES20.glDisableVertexAttribArray(PositionHandle); } } public class GLSurface extends GLSurfaceView { //public static GLRender xRender; ScaleGestureDetector ScaleDetect; MainActivity mMain; OpenGL XOPL = mMain.xOpenGL; public GLSurface(Context context, AttributeSet attrs){ super(context, attrs); // Render the view only when there is a change in the drawing data //setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); ScaleDetect = new ScaleGestureDetector(context, new ScaleDetectorListener()); } private float mPreviousX; private float mPreviousY; float density = this.getResources().getDisplayMetrics().density; private static final int MAX_CLICK_DURATION = 300; private long pressStartTime; #Override public boolean onTouchEvent(MotionEvent e) { ScaleDetect.onTouchEvent(e); float x = e.getX(); float y = e.getY(); switch (e.getAction()) { case MotionEvent.ACTION_MOVE: if(!ScaleDetect.isInProgress()) { float xMoveRange = x - mPreviousX; float yMoveRange = y - mPreviousY; float dx = 0.0f; float dy = 0.0f; float w = this.getWidth(); float h = this.getHeight(); if (Math.abs(xMoveRange) > w / 100 && Math.abs(yMoveRange) < h / 100){ dx = xMoveRange / density / 2.0f; XOPL.xRender.setAngleX(XOPL.xRender.getXAngle() + dx); } if (Math.abs(xMoveRange) < w / 100 && Math.abs(yMoveRange) > h / 100){ dy = yMoveRange / density / 2.0f; XOPL.xRender.setAngleY(XOPL.xRender.getYAngle() + dy); } XOPL.myGLView.requestRender(); } break; case MotionEvent.ACTION_DOWN: pressStartTime = System.currentTimeMillis(); break; case MotionEvent.ACTION_UP: long pressDuration = System.currentTimeMillis() - pressStartTime; if (pressDuration < MAX_CLICK_DURATION) { float Nx = (x - Float.parseFloat(Double.toString(this.getWidth())) * 0.5f) / (Float.parseFloat(Double.toString(this.getWidth())) * 0.5f); float Ny = (y - Float.parseFloat(Double.toString(this.getHeight())) * 0.5f) / (Float.parseFloat(Double.toString(this.getHeight())) * 0.5f); float Nz = 1.0f; XOPL.xRender.setNCoordinate(Nx, Ny, Nz); XOPL.xRender.Selection(); XOPL.myGLView.requestRender(); } break; } mPreviousX = x; mPreviousY = y; return true; } private float sizeCoef = 1; public class ScaleDetectorListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { float scaleFocusX = 0; float scaleFocusY = 0; public boolean onScale(ScaleGestureDetector arg0) { float scale = arg0.getScaleFactor() * sizeCoef; sizeCoef = scale; XOPL.xRender.setZoom(sizeCoef); XOPL.myGLView.requestRender(); return true; } public boolean onScaleBegin(ScaleGestureDetector arg0) { invalidate(); scaleFocusX = arg0.getFocusX(); scaleFocusY = arg0.getFocusY(); XOPL.xRender.setFocus(scaleFocusX,scaleFocusY); return true; } public void onScaleEnd(ScaleGestureDetector arg0) { scaleFocusX = 0; scaleFocusY = 0; XOPL.xRender.setFocus(scaleFocusX,scaleFocusY); } } }
Not sure if this is the problem, but watch out for things like: XOPL.xRender.setAngleX(XOPL.xRender.getXAngle() + dx) ... especially when using mediump precision in shaders. Generally I'd recommend changing setAngle functions to exploit rotational symmetry and wrap the value around so you get an absolute range used at the API-level of of +-Pi. In your current code if the user keeps swiping in one direction, eventually you'll run our of bits and everything will either stop rotating (at best), or fail with infinities or NaN results (at worst). Note using "-Pi to +Pi" is preferred to using "0 to +2Pi", because the sign-bit is free in most floating point representations so preserves more dynamic precision. Example code: public float wrapRadians(float angle) { // If angle is negative ensure value is higher than minus pi if (angle < 0) { while (angle < -math.PI) { angle += 2 * math.PI; } // Else angle is positive so ensure value is less than pi } else { while (angle > math.PI) { angle -= 2 * math.PI; } } return angle; } public float setXAngle(float XAngle) { mXAngle = wrapRadians(XAngle); } public float setYAngle(float YAngle) { mYAngle = wrapRadians(YAngle); }
How to zoom properly in OpenGL ES 2
I've a 3d-model in OpenGL ES in Android. I've already implemented swipe-gestures for translating, rotating and zooming into the model. Everything but the zooming works fine. I'm not sure what I'm missing or what I have to change but I'm not able to zoom into my model. The model is a building. What I'd like to do is to zoom into the different floors of the building. But no matter how I change my implementation, I'm not able to do this. Either the building disappears when I zoom in or the zoom has a limitation so that I can't zoom into it further.... First of all I decreased the field of view by modifying the Matrix: frustumM(matrix, 0, -ratio/zoom, ratio/zoom, -1/zoom, 1/zoom, nearPlane, farPlane). Someone told me, that this is not the correct approach and I should modify the eyeZ value like: eyeZ = -1.0/zoom The first approach is working, but I'd like to know what my mistake with the second approach is, because it has the issues I mentioned in the beginning. My renderer-class is the following: public class MyGLRenderer implements GLSurfaceView.Renderer { private float[] mModelMatrix = new float[16]; private final float[] mMVMatrix = new float[16]; private final float[] mProjectionMatrix = new float[16]; private final float[] mViewMatrix = new float[16]; private float nearPlaneDistance = 1f; private float farPlaneDistance = 200f; private float modelRatio = 1.0f; private int offset = 0; private float eyeX = 0; private float eyeY = 0; private float eyeZ = -1; private float centerX = 0f; private float centerY = 0f; private float centerZ = 0f; private float upX = 0f; private float upY = 1.0f; private float upZ = 0.0f; private float mZoomLevel = 1f; private float defaultRotationX = 100.0f; //building otherwise on the wrong side private float defaultRotationZ = 180.0f; //building otherwise on the wrong side private float rotationX = defaultRotationX; private float rotationY = 0.0f; private float rotationZ = defaultRotationZ; private float translateX = 0.0f; private float translateY = 0.0f; private float translateZ = 0.0f; private float scaleFactor = 20.0f; //no matter what scale factor -> it's not possible to zoom into the building... private float ratio; private float width; private float height; private List<IDrawableObject> drawableObjects; public Model3D model3d; public MyGLRenderer(Model3D model3d) { this.model3d = model3d; getModelScale(); } private void getModelScale() { float highestValue = (model3d.width > model3d.height) ? model3d.width : model3d.height; modelRatio = 2f / highestValue; } #Override public void onSurfaceCreated(GL10 unused, EGLConfig config) { // Set the background frame color GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); GLES20.glDisable(GLES20.GL_CULL_FACE); GLES20.glEnable(GLES20.GL_DEPTH_TEST); drawableObjects = ... ; //to much detail, basically getting triangles } #Override public void onDrawFrame(GL10 unused) { float[] mMVPMatrix = new float[16]; // Draw background color Matrix.setIdentityM(mModelMatrix, 0); GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); // model is in origin-solution too big Matrix.scaleM(mModelMatrix, 0, modelRatio * scaleFactor, modelRatio * scaleFactor, modelRatio * scaleFactor); Matrix.translateM(mModelMatrix, 0, translateX, translateY, translateZ); rotateModel(mModelMatrix, rotationX, rotationY, rotationZ, true); // Set the camera position (View matrix) Matrix.setLookAtM(mViewMatrix, offset, eyeX, eyeY, eyeZ / mZoomLevel, centerX, centerY, centerZ, upX, upY, upZ); // combine the model with the view matrix Matrix.multiplyMM(mMVMatrix, 0, mViewMatrix, 0, mModelMatrix, 0); // this projection matrix is applied to object coordinates // in the onDrawFrame() method Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, 1, -1, nearPlaneDistance, farPlaneDistance); // Calculate the projection and view transformation Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVMatrix, 0); for (IDrawableObject d : drawableObjects) { d.draw(mMVPMatrix); } } private void rotateModel(float[] mModelMatrix, Float x, Float y, Float z, boolean rotateAroundCenter) { // translation for rotating the model around its center if (rotateAroundCenter) { Matrix.translateM(mModelMatrix, 0, (model3d.width / 2f), 0, (model3d.height / 2f)); } if (x != null) { Matrix.rotateM(mModelMatrix, 0, x, 1.0f, 0.0f, 0.0f); } if (y != null) { Matrix.rotateM(mModelMatrix, 0, y, 0.0f, 1.0f, 0.0f); } if (z != null) { Matrix.rotateM(mModelMatrix, 0, z, 0.0f, 0.0f, 1.0f); } // translation back to the origin if (rotateAroundCenter) { Matrix.translateM(mModelMatrix, 0, -(model3d.width / 2f), 0, -(model3d.height / 2f)); } } #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); this.width = width; this.height = height; ratio = (float) width / height; } 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 int getFPS() { return lastMFPS; } public static void checkGlError(String glOperation) { int error; while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) { Log.e(TAG, glOperation + ": glError " + error); throw new RuntimeException(glOperation + ": glError " + error); } } public void setZoom(float zoom) { this.mZoomLevel = zoom; } public void setDistance(float distance) { eyeZ = distance; } public float getDistance() { return eyeZ; } public float getRotationX() { return rotationX; } public void setRotationX(float rotationX) { this.rotationX = defaultRotationX + rotationX; } public float getRotationY() { return rotationY; } public void setRotationY(float rotationY) { this.rotationY = rotationY; } public float getRotationZ() { return rotationZ; } public void setRotationZ(float rotationZ) { this.rotationZ = defaultRotationZ + rotationZ; } public float getFarPlane() { return farPlaneDistance; } public float getNearPlane() { return nearPlaneDistance; } public void addTranslation(float mPosX, float mPosY) { this.translateX = mPosX; this.translateY = mPosY; } public void downPressed() { translateX -= 10; } public void upPressed() { translateX += 10; } public void actionMoved(float mPosX, float mPosY) { float translationX = (mPosX / width); float translationY = -(mPosY / height); addTranslation(translationX, translationY); } public float getmZoomLevel() { return mZoomLevel; } public void setmZoomLevel(float mZoomLevel) { this.mZoomLevel = mZoomLevel; } public float getWidth() { return width; } public float getHeight() { return height; } public void setTranslation(Float x, Float y, Float z) { if (x != null) { this.translateX = -x; } if (y != null) { this.translateY = y; } if (z != null) { this.translateZ = -z; } } public void setRotation(Float x, Float y, Float z) { if (x != null) { this.rotationX = defaultRotationX + x; } if (y != null) { this.rotationY = y; } if (z != null) { this.rotationZ = defaultRotationZ + z; } } public void setScale(float scale) { this.mZoomLevel = scale; } public float getDefaultRotationX() { return defaultRotationX; } } Do you see any mistake I'm currently doing? You can also have a look into the github repository: https://github.com/Dalanie/OpenGL-ES/tree/master/buildingGL
First you must define what you mean by "zoom". In the scenario of a perspective projection, there are a few possibilities: You change the field of view. This is analogous to the zoom of cameras, where zooming results in changing the focal width. You just scale the model before the projection. You change the distance of the model (nearer to the camera to zoom in, farer away to zoom out) The variant 1 is what you did by changing the frustum. In my opinion, that is the most intuitive effect. At least to someone who is used to cameras. ALso note that this has the same effect as upscaling some sub-rectangle of the 2d projected image to fill the whole screen. Changing eyeZ is approach 3. But now you must be carefol to not move the object out of the viewing volume (which seems to be the issue you are describing). Ideally you would modify the frustum here, too. But to keep the field of view, while moving the near/far planes so that the object always stays inbetween. Note that this requires changing all 6 values of the frustum, what stays the same should be the ratios left/near, right/near, top/near and bottom/near to keep the FOV/aspect you had before.
open GL ES1.0 Trails
I am new to open GL, I just want to move a circle randomly in the screen , when the user touches the circle , I need to know the hit and miss. this is what I'm able to achieve through the online classes. render class: public class HelloOpenGLES10Renderer implements Renderer { private int points = 250; private float vertices[] = { 0.0f, 0.0f, 0.0f }; private FloatBuffer vertBuff; public float x = 0.0f, y = 0.0f; public boolean color = false; boolean first = true; #Override public void onDrawFrame(GL10 gl) { gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); gl.glTranslatef(x, y, 0); gl.glColor4f(1.0f, 1.0f, 1.0f, 0f); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertBuff); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, points); } #Override public void onSurfaceChanged(GL10 gl, int width, int height) { Log.i("TAG", "change" + width + ":" + height); gl.glViewport(0, 0, width, height); float ratio = (float) width / height; gl.glMatrixMode(GL10.GL_PROJECTION); gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7); GLU.gluLookAt(gl, 0f, 0f, -5f, 0.0f, 0.0f, 0f, 0.0f, 1.0f, 0.0f); } #Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { Log.i("TAG", "CREATE"); gl.glClearColor(0.1f, 0.1f, 0.0f, 1.0f); initShapes(); } private void initShapes() { vertices = new float[(points + 1) * 3]; for (int i = 3; i < (points + 1) * 3; i += 3) { double rad = (i * 360 / points * 3) * (3.14 / 180); vertices[i] = (float) Math.cos(rad) * 0.10f; vertices[i + 1] = (float) Math.sin(rad) * 0.10f; vertices[i + 2] = 0; } ByteBuffer bBuff = ByteBuffer.allocateDirect(vertices.length * 4); bBuff.order(ByteOrder.nativeOrder()); vertBuff = bBuff.asFloatBuffer(); vertBuff.put(vertices); vertBuff.position(0); } } Activity: package com.example.opengltrail; import java.util.Random; import android.app.Activity; import android.opengl.GLSurfaceView; import android.os.Bundle; import android.util.FloatMath; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; public class MainActivity extends Activity implements OnTouchListener { private GLSurfaceView mGLView; float oldx = 0, oldy = 0; private HelloOpenGLES10Renderer m; ProgressDialogThread p; ProgressDialogThread123 t; boolean stop = true; #Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mGLView = new GLSurfaceView(this); m = new HelloOpenGLES10Renderer(); mGLView.setRenderer(m); mGLView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); setContentView(mGLView); mGLView.setOnTouchListener(this); p = new ProgressDialogThread(); } #Override protected void onPause() { super.onPause(); mGLView.onPause(); p.stop(); stop = false; } #Override protected void onResume() { super.onResume(); mGLView.onResume(); t = new ProgressDialogThread123(); t.start(); p.start(); } /** * gets u the random number btw 0.0 to 1.0 */ public float getmearandom() { Random rng = new Random(); float next = rng.nextFloat(); Integer i = rng.nextInt(); if (i % 2 == 0) next = next * (-1); return next; } class ProgressDialogThread123 extends Thread { #Override public void run() { // TODO Auto-generated method stub super.run(); for (; stop;) { p.run(); } } } class ProgressDialogThread extends Thread { #Override public void run() { super.run(); if (stop) { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } m.x = getmearandom(); m.y = getmearandom(); Log.i("m.x=" + m.x + ":", "m.y=" + m.y); mGLView.requestRender(); } } } #Override public boolean onTouch(View v, MotionEvent event) { float x = event.getX(); float y = event.getY(); float x1 = ((x * 2) / 480); float y1 = ((y * 2) / 724); x1 = -1 + x1; y1 = -1 + y1; if (y < 362) { if (y1 > 0) y1 = -y1; } else if (y > 362) { if (y1 < 0) y1 = -y1; } else { y1 = 0; } if (x > 240) { if (x1 < 0) x1 = -x1; } else if (x < 240) { if (x1 > 0) x1 = -x1; } else { x1 = 0; } Log.i("x1=" + x1, "y1=" + y1); float d = (((m.x - x1) * (m.x - x1)) + ((m.y - y1) * (m.y - y1))); float dd = FloatMath.sqrt(d); if (dd <= 0.10f) { m.color = true; // mGLView.requestRender(); Log.i("Tag", "Circle"); } // m.x += 0.10f; return true; } } Please anyone help me !! thanks in advance
If you are only drawing in 2d I suggest you loose "frustum" and "lookAt" and replace them with "ortho" with coordinates: ortho(viewOrigin.x, viewOrigin.x + viewSize.width, viewOrigin.y + viewSize.height, viewOrigin.y, -1.0f, 1.0f). This will make your GL coordinate system same as your view coordinates. As for circle vertices rather create them with radius of 1.0f. Now to draw the circle, before the draw call you just have to "push" matrix, translate to screen coordinates (X, Y, .0f), scale to radius R in pixels (R, R, 1.0f) and "pop" the matrix after the call.. Now to check on touch if the circle was hit: `bool didHit = ((touch.x-cicrcleCenter.x)*(touch.x-cicrcleCenter.x) + (touch.y-cicrcleCenter.y)*(touch.y-cicrcleCenter.y)) < R*R`; Note that "viewOrigin" in "ortho" depends on where you are catching touches: If you are catching them in the same view it will probably be at (0,0) no matter where the view is. Those coordinates should correspond to coordinates you receive in your touch event when pressing at upper left and bottom right corners of your view. If you really need to draw in 3d and you will have to use frustum, you will need to get inverse of your projection matrix to create 3d rays from your touches and then check for hits the same way you would for bullets if you like.
opengl problem works on droid but not droid eris and others
This GlRenderer works fine on the moto droid, but does not work well at all on droid eris or other android phones does anyone know why? package com.ntu.way2fungames.spacehockeybase; import java.io.DataInputStream; import java.io.IOException; import java.nio.Buffer; import java.nio.FloatBuffer; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import com.ntu.way2fungames.LoadFloatArray; import com.ntu.way2fungames.OGLTriReader; import android.content.res.AssetManager; import android.content.res.Resources; import android.opengl.GLU; import android.opengl.GLSurfaceView.Renderer; import android.os.Handler; import android.os.Message; public class GlRenderer extends Thread implements Renderer { private float drawArray[]; private float yoff; private float yoff2; private long lastRenderTime; private float[] yoffs= new float[10]; int Width; int Height; private float[] pixelVerts = new float[] { +.0f,+.0f,2, +.5f,+.5f,0, +.5f,-.5f,0, +.0f,+.0f,2, +.5f,-.5f,0, -.5f,-.5f,0, +.0f,+.0f,2, -.5f,-.5f,0, -.5f,+.5f,0, +.0f,+.0f,2, -.5f,+.5f,0, +.5f,+.5f,0, }; #Override public void run() { } private float[] arenaWalls = new float[] { 8.00f,2.00f,1f,2f,2f,1f,2.00f,8.00f,1f,8.00f,2.00f,1f,2.00f,8.00f,1f,8.00f,8.00f,1f, 2.00f,8.00f,1f,2f,2f,1f,0.00f,0.00f,0f,2.00f,8.00f,1f,0.00f,0.00f,0f,0.00f,10.00f,0f, 8.00f,8.00f,1f,2.00f,8.00f,1f,0.00f,10.00f,0f,8.00f,8.00f,1f,0.00f,10.00f,0f,10.00f,10.00f,0f, 2f,2f,1f,8.00f,2.00f,1f,10.00f,0.00f,0f,2f,2f,1f,10.00f,0.00f,0f,0.00f,0.00f,0f, 8.00f,2.00f,1f,8.00f,8.00f,1f,10.00f,10.00f,0f,8.00f,2.00f,1f,10.00f,10.00f,0f,10.00f,0.00f,0f, 10.00f,10.00f,0f,0.00f,10.00f,0f,0.00f,0.00f,0f,10.00f,10.00f,0f,0.00f,0.00f,0f,10.00f,0.00f,0f, 8.00f,6.00f,1f,8.00f,4.00f,1f,122f,4.00f,1f,8.00f,6.00f,1f,122f,4.00f,1f,122f,6.00f,1f, 8.00f,6.00f,1f,122f,6.00f,1f,120f,7.00f,0f,8.00f,6.00f,1f,120f,7.00f,0f,10.00f,7.00f,0f, 122f,4.00f,1f,8.00f,4.00f,1f,10.00f,3.00f,0f,122f,4.00f,1f,10.00f,3.00f,0f,120f,3.00f,0f, 480f,10.00f,0f,470f,10.00f,0f,470f,0.00f,0f,480f,10.00f,0f,470f,0.00f,0f,480f,0.00f,0f, 478f,2.00f,1f,478f,8.00f,1f,480f,10.00f,0f,478f,2.00f,1f,480f,10.00f,0f,480f,0.00f,0f, 472f,2f,1f,478f,2.00f,1f,480f,0.00f,0f,472f,2f,1f,480f,0.00f,0f,470f,0.00f,0f, 478f,8.00f,1f,472f,8.00f,1f,470f,10.00f,0f,478f,8.00f,1f,470f,10.00f,0f,480f,10.00f,0f, 472f,8.00f,1f,472f,2f,1f,470f,0.00f,0f,472f,8.00f,1f,470f,0.00f,0f,470f,10.00f,0f, 478f,2.00f,1f,472f,2f,1f,472f,8.00f,1f,478f,2.00f,1f,472f,8.00f,1f,478f,8.00f,1f, 478f,846f,1f,472f,846f,1f,472f,852f,1f,478f,846f,1f,472f,852f,1f,478f,852f,1f, 472f,852f,1f,472f,846f,1f,470f,844f,0f,472f,852f,1f,470f,844f,0f,470f,854f,0f, 478f,852f,1f,472f,852f,1f,470f,854f,0f,478f,852f,1f,470f,854f,0f,480f,854f,0f, 472f,846f,1f,478f,846f,1f,480f,844f,0f,472f,846f,1f,480f,844f,0f,470f,844f,0f, 478f,846f,1f,478f,852f,1f,480f,854f,0f,478f,846f,1f,480f,854f,0f,480f,844f,0f, 480f,854f,0f,470f,854f,0f,470f,844f,0f,480f,854f,0f,470f,844f,0f,480f,844f,0f, 10.00f,854f,0f,0.00f,854f,0f,0.00f,844f,0f,10.00f,854f,0f,0.00f,844f,0f,10.00f,844f,0f, 8.00f,846f,1f,8.00f,852f,1f,10.00f,854f,0f,8.00f,846f,1f,10.00f,854f,0f,10.00f,844f,0f, 2f,846f,1f,8.00f,846f,1f,10.00f,844f,0f,2f,846f,1f,10.00f,844f,0f,0.00f,844f,0f, 8.00f,852f,1f,2.00f,852f,1f,0.00f,854f,0f,8.00f,852f,1f,0.00f,854f,0f,10.00f,854f,0f, 2.00f,852f,1f,2f,846f,1f,0.00f,844f,0f,2.00f,852f,1f,0.00f,844f,0f,0.00f,854f,0f, 8.00f,846f,1f,2f,846f,1f,2.00f,852f,1f,8.00f,846f,1f,2.00f,852f,1f,8.00f,852f,1f, 6f,846f,1f,4f,846f,1f,4f,8f,1f,6f,846f,1f,4f,8f,1f,6f,8f,1f, 6f,846f,1f,6f,8f,1f,7f,10f,0f,6f,846f,1f,7f,10f,0f,7f,844f,0f, 4f,8f,1f,4f,846f,1f,3f,844f,0f,4f,8f,1f,3f,844f,0f,3f,10f,0f, 474f,8f,1f,474f,846f,1f,473f,844f,0f,474f,8f,1f,473f,844f,0f,473f,10f,0f, 476f,846f,1f,476f,8f,1f,477f,10f,0f,476f,846f,1f,477f,10f,0f,477f,844f,0f, 476f,846f,1f,474f,846f,1f,474f,8f,1f,476f,846f,1f,474f,8f,1f,476f,8f,1f, 130f,10.00f,0f,120f,10.00f,0f,120f,0.00f,0f,130f,10.00f,0f,120f,0.00f,0f,130f,0.00f,0f, 128f,2.00f,1f,128f,8.00f,1f,130f,10.00f,0f,128f,2.00f,1f,130f,10.00f,0f,130f,0.00f,0f, 122f,2f,1f,128f,2.00f,1f,130f,0.00f,0f,122f,2f,1f,130f,0.00f,0f,120f,0.00f,0f, 128f,8.00f,1f,122f,8.00f,1f,120f,10.00f,0f,128f,8.00f,1f,120f,10.00f,0f,130f,10.00f,0f, 122f,8.00f,1f,122f,2f,1f,120f,0.00f,0f,122f,8.00f,1f,120f,0.00f,0f,120f,10.00f,0f, 128f,2.00f,1f,122f,2f,1f,122f,8.00f,1f,128f,2.00f,1f,122f,8.00f,1f,128f,8.00f,1f, 352f,8.00f,1f,358f,8.00f,1f,358f,2.00f,1f,352f,8.00f,1f,358f,2.00f,1f,352f,2.00f,1f, 358f,2.00f,1f,358f,8.00f,1f,360f,10.00f,0f,358f,2.00f,1f,360f,10.00f,0f,360f,0.00f,0f, 352f,2.00f,1f,358f,2.00f,1f,360f,0.00f,0f,352f,2.00f,1f,360f,0.00f,0f,350f,0.00f,0f, 358f,8.00f,1f,352f,8.00f,1f,350f,10.00f,0f,358f,8.00f,1f,350f,10.00f,0f,360f,10.00f,0f, 352f,8.00f,1f,352f,2.00f,1f,350f,0.00f,0f,352f,8.00f,1f,350f,0.00f,0f,350f,10.00f,0f, 350f,0.00f,0f,360f,0.00f,0f,360f,10.00f,0f,350f,0.00f,0f,360f,10.00f,0f,350f,10.00f,0f, 358f,6.00f,1f,472f,6.00f,1f,470f,7.00f,0f,358f,6.00f,1f,470f,7.00f,0f,360f,7.00f,0f, 472f,4.00f,1f,358f,4.00f,1f,360f,3.00f,0f,472f,4.00f,1f,360f,3.00f,0f,470f,3.00f,0f, 472f,4.00f,1f,472f,6.00f,1f,358f,6.00f,1f,472f,4.00f,1f,358f,6.00f,1f,358f,4.00f,1f, 472f,848f,1f,472f,850f,1f,358f,850f,1f,472f,848f,1f,358f,850f,1f,358f,848f,1f, 472f,848f,1f,358f,848f,1f,360f,847f,0f,472f,848f,1f,360f,847f,0f,470f,847f,0f, 358f,850f,1f,472f,850f,1f,470f,851f,0f,358f,850f,1f,470f,851f,0f,360f,851f,0f, 350f,844f,0f,360f,844f,0f,360f,854f,0f,350f,844f,0f,360f,854f,0f,350f,854f,0f, 352f,852f,1f,352f,846f,1f,350f,844f,0f,352f,852f,1f,350f,844f,0f,350f,854f,0f, 358f,852f,1f,352f,852f,1f,350f,854f,0f,358f,852f,1f,350f,854f,0f,360f,854f,0f, 352f,846f,1f,358f,846f,1f,360f,844f,0f,352f,846f,1f,360f,844f,0f,350f,844f,0f, 358f,846f,1f,358f,852f,1f,360f,854f,0f,358f,846f,1f,360f,854f,0f,360f,844f,0f, 352f,852f,1f,358f,852f,1f,358f,846f,1f,352f,852f,1f,358f,846f,1f,352f,846f,1f, 128f,846f,1f,122f,846f,1f,122f,852f,1f,128f,846f,1f,122f,852f,1f,128f,852f,1f, 122f,852f,1f,122f,846f,1f,120f,844f,0f,122f,852f,1f,120f,844f,0f,120f,854f,0f, 128f,852f,1f,122f,852f,1f,120f,854f,0f,128f,852f,1f,120f,854f,0f,130f,854f,0f, 122f,846f,1f,128f,846f,1f,130f,844f,0f,122f,846f,1f,130f,844f,0f,120f,844f,0f, 128f,846f,1f,128f,852f,1f,130f,854f,0f,128f,846f,1f,130f,854f,0f,130f,844f,0f, 130f,854f,0f,120f,854f,0f,120f,844f,0f,130f,854f,0f,120f,844f,0f,130f,844f,0f, 122f,848f,1f,8f,848f,1f,10f,847f,0f,122f,848f,1f,10f,847f,0f,120f,847f,0f, 8f,850f,1f,122f,850f,1f,120f,851f,0f,8f,850f,1f,120f,851f,0f,10f,851f,0f, 8f,850f,1f,8f,848f,1f,122f,848f,1f,8f,850f,1f,122f,848f,1f,122f,850f,1f, 10f,847f,0f,120f,847f,0f,124.96f,829.63f,-0.50f,10f,847f,0f,124.96f,829.63f,-0.50f,19.51f,829.63f,-0.50f, 130f,844f,0f,130f,854f,0f,134.55f,836.34f,-0.50f,130f,844f,0f,134.55f,836.34f,-0.50f,134.55f,826.76f,-0.50f, 350f,844f,0f,350f,854f,0f,345.45f,836.34f,-0.50f,350f,844f,0f,345.45f,836.34f,-0.50f,345.45f,826.76f,-0.50f, 360f,847f,0f,470f,847f,0f,460.49f,829.63f,-0.50f,360f,847f,0f,460.49f,829.63f,-0.50f,355.04f,829.63f,-0.50f, 470f,7.00f,0f,360f,7.00f,0f,355.04f,24.37f,-0.50f,470f,7.00f,0f,355.04f,24.37f,-0.50f,460.49f,24.37f,-0.50f, 350f,10.00f,0f,350f,0.00f,0f,345.45f,17.66f,-0.50f,350f,10.00f,0f,345.45f,17.66f,-0.50f,345.45f,27.24f,-0.50f, 130f,10.00f,0f,130f,0.00f,0f,134.55f,17.66f,-0.50f,130f,10.00f,0f,134.55f,17.66f,-0.50f,134.55f,27.24f,-0.50f, 473f,844f,0f,473f,10f,0f,463.36f,27.24f,-0.50f,473f,844f,0f,463.36f,27.24f,-0.50f,463.36f,826.76f,-0.50f, 7f,10f,0f,7f,844f,0f,16.64f,826.76f,-0.50f,7f,10f,0f,16.64f,826.76f,-0.50f,16.64f,27.24f,-0.50f, 120f,7.00f,0f,10.00f,7.00f,0f,19.51f,24.37f,-0.50f,120f,7.00f,0f,19.51f,24.37f,-0.50f,124.96f,24.37f,-0.50f, 120f,7.00f,0f,130f,10.00f,0f,134.55f,27.24f,-0.50f,120f,7.00f,0f,134.55f,27.24f,-0.50f,124.96f,24.37f,-0.50f, 10.00f,7.00f,0f,7f,10f,0f,16.64f,27.24f,-0.50f,10.00f,7.00f,0f,16.64f,27.24f,-0.50f,19.51f,24.37f,-0.50f, 350f,10.00f,0f,360f,7.00f,0f,355.04f,24.37f,-0.50f,350f,10.00f,0f,355.04f,24.37f,-0.50f,345.45f,27.24f,-0.50f, 473f,10f,0f,470f,7.00f,0f,460.49f,24.37f,-0.50f,473f,10f,0f,460.49f,24.37f,-0.50f,463.36f,27.24f,-0.50f, 473f,844f,0f,470f,847f,0f,460.49f,829.63f,-0.50f,473f,844f,0f,460.49f,829.63f,-0.50f,463.36f,826.76f,-0.50f, 360f,847f,0f,350f,844f,0f,345.45f,826.76f,-0.50f,360f,847f,0f,345.45f,826.76f,-0.50f,355.04f,829.63f,-0.50f, 130f,844f,0f,120f,847f,0f,124.96f,829.63f,-0.50f,130f,844f,0f,124.96f,829.63f,-0.50f,134.55f,826.76f,-0.50f, 7f,844f,0f,10f,847f,0f,19.51f,829.63f,-0.50f,7f,844f,0f,19.51f,829.63f,-0.50f,16.64f,826.76f,-0.50f, 19.51f,829.63f,-0.50f,124.96f,829.63f,-0.50f,136.47f,789.37f,-2f,19.51f,829.63f,-0.50f,136.47f,789.37f,-2f,41.56f,789.37f,-2f, 134.55f,826.76f,-0.50f,134.55f,836.34f,-0.50f,145.09f,795.41f,-2f,134.55f,826.76f,-0.50f,145.09f,795.41f,-2f,145.09f,786.78f,-2f, 345.45f,826.76f,-0.50f,345.45f,836.34f,-0.50f,334.91f,795.41f,-2f,345.45f,826.76f,-0.50f,334.91f,795.41f,-2f,334.91f,786.78f,-2f, 355.04f,829.63f,-0.50f,460.49f,829.63f,-0.50f,438.44f,789.37f,-2f,355.04f,829.63f,-0.50f,438.44f,789.37f,-2f,343.53f,789.37f,-2f, 460.49f,24.37f,-0.50f,355.04f,24.37f,-0.50f,343.53f,64.63f,-2f,460.49f,24.37f,-0.50f,343.53f,64.63f,-2f,438.44f,64.63f,-2f, 345.45f,27.24f,-0.50f,345.45f,17.66f,-0.50f,334.91f,58.59f,-2f,345.45f,27.24f,-0.50f,334.91f,58.59f,-2f,334.91f,67.22f,-2f, 134.55f,27.24f,-0.50f,134.55f,17.66f,-0.50f,145.09f,58.59f,-2f,134.55f,27.24f,-0.50f,145.09f,58.59f,-2f,145.09f,67.22f,-2f, 463.36f,826.76f,-0.50f,463.36f,27.24f,-0.50f,441.03f,67.22f,-2f,463.36f,826.76f,-0.50f,441.03f,67.22f,-2f,441.03f,786.78f,-2f, 16.64f,27.24f,-0.50f,16.64f,826.76f,-0.50f,38.97f,786.78f,-2f,16.64f,27.24f,-0.50f,38.97f,786.78f,-2f,38.97f,67.22f,-2f, 124.96f,24.37f,-0.50f,19.51f,24.37f,-0.50f,41.56f,64.63f,-2f,124.96f,24.37f,-0.50f,41.56f,64.63f,-2f,136.47f,64.63f,-2f, 124.96f,24.37f,-0.50f,134.55f,27.24f,-0.50f,145.09f,67.22f,-2f,124.96f,24.37f,-0.50f,145.09f,67.22f,-2f,136.47f,64.63f,-2f, 19.51f,24.37f,-0.50f,16.64f,27.24f,-0.50f,38.97f,67.22f,-2f,19.51f,24.37f,-0.50f,38.97f,67.22f,-2f,41.56f,64.63f,-2f, 345.45f,27.24f,-0.50f,355.04f,24.37f,-0.50f,343.53f,64.63f,-2f,345.45f,27.24f,-0.50f,343.53f,64.63f,-2f,334.91f,67.22f,-2f, 463.36f,27.24f,-0.50f,460.49f,24.37f,-0.50f,438.44f,64.63f,-2f,463.36f,27.24f,-0.50f,438.44f,64.63f,-2f,441.03f,67.22f,-2f, 463.36f,826.76f,-0.50f,460.49f,829.63f,-0.50f,438.44f,789.37f,-2f,463.36f,826.76f,-0.50f,438.44f,789.37f,-2f,441.03f,786.78f,-2f, 355.04f,829.63f,-0.50f,345.45f,826.76f,-0.50f,334.91f,786.78f,-2f,355.04f,829.63f,-0.50f,334.91f,786.78f,-2f,343.53f,789.37f,-2f, 134.55f,826.76f,-0.50f,124.96f,829.63f,-0.50f,136.47f,789.37f,-2f,134.55f,826.76f,-0.50f,136.47f,789.37f,-2f,145.09f,786.78f,-2f, 16.64f,826.76f,-0.50f,19.51f,829.63f,-0.50f,41.56f,789.37f,-2f,16.64f,826.76f,-0.50f,41.56f,789.37f,-2f,38.97f,786.78f,-2f, }; private float[] backgroundData = new float[] { // # ,Scale, Speed, 300 , 1.05f, .001f, 150 , 1.07f, .002f, 075 , 1.10f, .003f, 040 , 1.12f, .006f, 20 , 1.15f, .012f, 10 , 1.25f, .025f, 05 , 1.50f, .050f, 3 , 2.00f, .100f, 2 , 3.00f, .200f, }; private float[] triangleCoords = new float[] { 0, -25, 0, -.75f, -1, 0, +.75f, -1, 0, 0, +2, 0, -.99f, -1, 0, .99f, -1, 0, }; private float[] triangleColors = new float[] { 1.0f, 1.0f, 1.0f, 0.05f, 1.0f, 1.0f, 1.0f, 0.5f, 1.0f, 1.0f, 1.0f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, 1.0f, 1.0f, 1.0f, 0.5f, }; private float[] drawArray2; private FloatBuffer drawBuffer2; private float[] colorArray2; private static FloatBuffer colorBuffer; private static FloatBuffer triangleBuffer; private static FloatBuffer quadBuffer; private static FloatBuffer drawBuffer; private float[] backgroundVerts; private FloatBuffer backgroundVertsWrapped; private float[] backgroundColors; private Buffer backgroundColorsWraped; private FloatBuffer backgroundColorsWrapped; private FloatBuffer arenaWallsWrapped; private FloatBuffer arenaColorsWrapped; private FloatBuffer arena2VertsWrapped; private FloatBuffer arena2ColorsWrapped; private long wallHitStartTime; private int wallHitDrawTime; private FloatBuffer pixelVertsWrapped; private float[] wallHit; private FloatBuffer pixelColorsWrapped; //private float[] pitVerts; private Resources lResources; private FloatBuffer pitVertsWrapped; private FloatBuffer pitColorsWrapped; private boolean arena2; private long lastStartTime; private long startTime; private int state=1; private long introEndTime; protected long introTotalTime =8000; protected long introStartTime; private boolean initDone= false; private static int stateIntro = 0; private static int stateGame = 1; public GlRenderer(spacehockey nspacehockey) { lResources = nspacehockey.getResources(); nspacehockey.SetHandlerToGLRenderer(new Handler() { #Override public void handleMessage(Message m) { if (m.what ==0){ wallHit = m.getData().getFloatArray("wall hit"); wallHitStartTime =System.currentTimeMillis(); wallHitDrawTime = 1000; }else if (m.what ==1){ //state = stateIntro; introEndTime= System.currentTimeMillis()+introTotalTime ; introStartTime = System.currentTimeMillis(); } }}); } public void onSurfaceCreated(GL10 gl, EGLConfig config) { gl.glShadeModel(GL10.GL_SMOOTH); gl.glClearColor(.01f, .01f, .01f, .1f); gl.glClearDepthf(1.0f); gl.glEnable(GL10.GL_DEPTH_TEST); gl.glDepthFunc(GL10.GL_LEQUAL); gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); } private float SumOfStrideI(float[] data, int offset, int stride) { int sum= 0; for (int i=offset;i<data.length-1;i=i+stride){ sum = (int) (data[i]+sum); } return sum; } public void onDrawFrame(GL10 gl) { if (state== stateIntro){DrawIntro(gl);} if (state== stateGame){DrawGame(gl);} } private void DrawIntro(GL10 gl) { startTime = System.currentTimeMillis(); if (startTime< introEndTime){ float ptd = (float)(startTime- introStartTime)/(float)introTotalTime; float ptl = 1-ptd; gl.glClear(GL10.GL_COLOR_BUFFER_BIT);//dont move gl.glMatrixMode(GL10.GL_MODELVIEW); int setVertOff = 0; gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_COLOR_ARRAY); gl.glColorPointer(4, GL10.GL_FLOAT, 0, backgroundColorsWrapped); for (int i = 0; i < backgroundData.length / 3; i = i + 1) { int setoff = i * 3; int setVertLen = (int) backgroundData[setoff]; yoffs[i] = (backgroundData[setoff + 2]*(90+(ptl*250))) + yoffs[i]; if (yoffs[i] > Height) {yoffs[i] = 0;} gl.glPushMatrix(); //gl.glTranslatef(0, -(Height/2), 0); //gl.glScalef(1f, 1f+(ptl*2), 1f); //gl.glTranslatef(0, +(Height/2), 0); gl.glTranslatef(0, yoffs[i], i+60); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, backgroundVertsWrapped); gl.glDrawArrays(GL10.GL_TRIANGLES, (setVertOff * 2 * 3) - 0, (setVertLen * 2 * 3) - 1); gl.glTranslatef(0, -Height, 0); gl.glDrawArrays(GL10.GL_TRIANGLES, (setVertOff * 2 * 3) - 0, (setVertLen * 2 * 3) - 1); setVertOff = (int) (setVertOff + setVertLen); gl.glPopMatrix(); } gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); gl.glDisableClientState(GL10.GL_COLOR_ARRAY); }else{state = stateGame;} } private void DrawGame(GL10 gl) { lastStartTime = startTime; startTime = System.currentTimeMillis(); long moveTime = startTime-lastStartTime; gl.glClear(GL10.GL_COLOR_BUFFER_BIT);//dont move gl.glMatrixMode(GL10.GL_MODELVIEW); int setVertOff = 0; gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_COLOR_ARRAY); gl.glColorPointer(4, GL10.GL_FLOAT, 0, backgroundColorsWrapped); for (int i = 0; i < backgroundData.length / 3; i = i + 1) { int setoff = i * 3; int setVertLen = (int) backgroundData[setoff]; yoffs[i] = (backgroundData[setoff + 2]*moveTime) + yoffs[i]; if (yoffs[i] > Height) {yoffs[i] = 0;} gl.glPushMatrix(); gl.glTranslatef(0, yoffs[i], i+60); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, backgroundVertsWrapped); gl.glDrawArrays(GL10.GL_TRIANGLES, (setVertOff * 6) - 0, (setVertLen *6) - 1); gl.glTranslatef(0, -Height, 0); gl.glDrawArrays(GL10.GL_TRIANGLES, (setVertOff * 6) - 0, (setVertLen *6) - 1); setVertOff = (int) (setVertOff + setVertLen); gl.glPopMatrix(); } //arena frame gl.glPushMatrix(); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, arenaWallsWrapped); gl.glColorPointer(4, GL10.GL_FLOAT, 0, arenaColorsWrapped); gl.glColor4f(.1f, .5f, 1f, 1f); gl.glTranslatef(0, 0, 50); gl.glDrawArrays(GL10.GL_TRIANGLES, 0, (int)(arenaWalls.length / 3)); gl.glPopMatrix(); //arena2 frame if (arena2 == true){ gl.glLoadIdentity(); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, pitVertsWrapped); gl.glColorPointer(4, GL10.GL_FLOAT, 0, pitColorsWrapped); gl.glTranslatef(0, -Height, 40); gl.glDrawArrays(GL10.GL_TRIANGLES, 0, (int)(pitVertsWrapped.capacity() / 3)); } if (wallHitStartTime != 0) { float timeRemaining = (wallHitStartTime + wallHitDrawTime)-System.currentTimeMillis(); if (timeRemaining>0) { gl.glPushMatrix(); float percentDone = 1-(timeRemaining/wallHitDrawTime); gl.glLoadIdentity(); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, pixelVertsWrapped); gl.glColorPointer(4, GL10.GL_FLOAT, 0, pixelColorsWrapped); gl.glTranslatef(wallHit[0], wallHit[1], 0); gl.glScalef(8, Height*percentDone, 0); gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 12); gl.glPopMatrix(); } else { wallHitStartTime = 0; } } gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); gl.glDisableClientState(GL10.GL_COLOR_ARRAY); } public void init(GL10 gl) { if (arena2 == true) { AssetManager assetManager = lResources.getAssets(); try { // byte[] ba = {111,111}; DataInputStream Dis = new DataInputStream(assetManager .open("arena2.ogl")); pitVertsWrapped = LoadFloatArray.FromDataInputStream(Dis); pitColorsWrapped = MakeFakeLighting(pitVertsWrapped.array(), .25f, .50f, 1f, 200, .5f); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if ((Height != 854) || (Width != 480)) { arenaWalls = ScaleFloats(arenaWalls, Width / 480f, Height / 854f); } arenaWallsWrapped = FloatBuffer.wrap(arenaWalls); arenaColorsWrapped = MakeFakeLighting(arenaWalls, .03f, .16f, .33f, .33f, 3); pixelVertsWrapped = FloatBuffer.wrap(pixelVerts); pixelColorsWrapped = MakeFakeLighting(pixelVerts, .03f, .16f, .33f, .10f, 20); initDone=true; } public void onSurfaceChanged(GL10 gl, int nwidth, int nheight) { Width= nwidth; Height = nheight; // avoid division by zero if (Height == 0) Height = 1; // draw on the entire screen gl.glViewport(0, 0, Width, Height); // setup projection matrix gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); gl.glOrthof(0, Width, Height, 0, 100, -100); // gl.glOrthof(-nwidth*2, nwidth*2, nheight*2,-nheight*2, 100, -100); // GLU.gluPerspective(gl, 180.0f, (float)nwidth / (float)nheight, // 1000.0f, -1000.0f); gl.glEnable(GL10.GL_BLEND); gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); System.gc(); if (initDone == false){ SetupStars(); init(gl); } } public void SetupStars(){ backgroundVerts = new float[(int) SumOfStrideI(backgroundData,0,3)*triangleCoords.length]; backgroundColors = new float[(int) SumOfStrideI(backgroundData,0,3)*triangleColors.length]; int iii=0; int vc=0; float ascale=1; for (int i=0;i<backgroundColors.length-1;i=i+1){ if (iii==0){ascale = (float) Math.random();} if (vc==3){ backgroundColors[i]= (float) (triangleColors[iii]*(ascale)); }else if(vc==2){ backgroundColors[i]= (float) (triangleColors[iii]-(Math.random()*.2)); }else{ backgroundColors[i]= (float) (triangleColors[iii]-(Math.random()*.3)); } iii=iii+1;if (iii> triangleColors.length-1){iii=0;} vc=vc+1; if (vc>3){vc=0;} } int ii=0; int i =0; int set =0; while(ii<backgroundVerts.length-1){ float scale = (float) backgroundData[(set*3)+1]; int length= (int) backgroundData[(set*3)]; for (i=0;i<length;i=i+1){ if (set ==0){ AddVertsToArray(ScaleFloats(triangleCoords, scale,scale*.25f), backgroundVerts, (float)(Math.random()*Width),(float) (Math.random()*Height), ii); }else{ AddVertsToArray(ScaleFloats(triangleCoords, scale), backgroundVerts, (float)(Math.random()*Width),(float) (Math.random()*Height), ii);} ii=ii+triangleCoords.length; } set=set+1; } backgroundVertsWrapped = FloatBuffer.wrap(backgroundVerts); backgroundColorsWrapped = FloatBuffer.wrap(backgroundColors); } public void AddVertsToArray(float[] sva,float[]dva,float ox,float oy,int start){ //x for (int i=0;i<sva.length;i=i+3){ if((start+i)<dva.length){dva[start+i]= sva[i]+ox;} } //y for (int i=1;i<sva.length;i=i+3){ if((start+i)<dva.length){dva[start+i]= sva[i]+oy;} } //z for (int i=2;i<sva.length;i=i+3){ if((start+i)<dva.length){dva[start+i]= sva[i];} } } public FloatBuffer MakeFakeLighting(float[] sa,float r, float g,float b,float a,float multby){ float[] da = new float[((sa.length/3)*4)]; int vertex=0; for (int i=0;i<sa.length;i=i+3){ if (sa[i+2]>=1){ da[(vertex*4)+0]= r*multby*sa[i+2]; da[(vertex*4)+1]= g*multby*sa[i+2]; da[(vertex*4)+2]= b*multby*sa[i+2]; da[(vertex*4)+3]= a*multby*sa[i+2]; }else if (sa[i+2]<=-1){ float divisor = (multby*(-sa[i+2])); da[(vertex*4)+0]= r / divisor; da[(vertex*4)+1]= g / divisor; da[(vertex*4)+2]= b / divisor; da[(vertex*4)+3]= a / divisor; }else{ da[(vertex*4)+0]= r; da[(vertex*4)+1]= g; da[(vertex*4)+2]= b; da[(vertex*4)+3]= a; } vertex = vertex+1; } return FloatBuffer.wrap(da); } public float[] ScaleFloats(float[] va,float s){ float[] reta= new float[va.length]; for (int i=0;i<va.length;i=i+1){ reta[i]=va[i]*s; } return reta; } public float[] ScaleFloats(float[] va,float sx,float sy){ float[] reta= new float[va.length]; int cnt = 0; for (int i=0;i<va.length;i=i+1){ if (cnt==0){reta[i]=va[i]*sx;} else if (cnt==1){reta[i]=va[i]*sy;} else if (cnt==2){reta[i]=va[i];} cnt = cnt +1;if (cnt>2){cnt=0;} } return reta; } }