Last active
April 12, 2016 21:54
-
-
Save framundo/c5a8f3c7c49810df41ce0281ccfc9150 to your computer and use it in GitHub Desktop.
Android OpenGL 2.0
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
... | |
<uses-feature android:glEsVersion="0x00020000" android:required="true" /> | |
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class BasicGLRenderer implements GLSurfaceView.Renderer { | |
private final GLCameraOptions mGLCameraOptions; | |
private int mBackgroundColor; | |
private float[] mViewMatrix = new float[16]; | |
private float[] mMVPMatrix = new float[16]; | |
private float[] mProjectionMatrix = new float[16]; | |
public BasicGLRenderer(GLCameraOptions glCameraOptions) { | |
mGLCameraOptions = glCameraOptions; | |
mBackgroundColor = Color.BLACK; | |
} | |
@Override | |
public void onSurfaceCreated(GL10 gl, EGLConfig config) { | |
// Set the background frame color | |
GLES20.glClearColor(GLColor.r(mBackgroundColor), | |
GLColor.g(mBackgroundColor), | |
GLColor.b(mBackgroundColor), | |
GLColor.a(mBackgroundColor)); | |
// Enable depth testing | |
GLES20.glEnable(GLES20.GL_DEPTH_TEST); | |
} | |
@Override | |
public void onSurfaceChanged(GL10 gl, int width, int height) { | |
GLES20.glViewport(0, 0, width, height); | |
float ratio = (float) width / height; | |
// this projection matrix is applied to object coordinates | |
// in the onDrawFrame() method | |
Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, mGLCameraOptions.near, mGLCameraOptions.far); | |
} | |
@Override | |
public void onDrawFrame(GL10 gl) { | |
// Redraw background color | |
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); | |
// Set the camera position (View matrix) | |
Matrix.setLookAtM(mViewMatrix, 0, | |
mGLCameraOptions.eyeX, | |
mGLCameraOptions.eyeY, | |
mGLCameraOptions.eyeZ, | |
mGLCameraOptions.centerX, | |
mGLCameraOptions.centerY, | |
mGLCameraOptions.centerZ, | |
mGLCameraOptions.upX, | |
mGLCameraOptions.upY, | |
mGLCameraOptions.upZ); | |
// Calculate the projection and view transformation | |
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0); | |
} | |
public void setBackgroundColor(int color) { | |
mBackgroundColor = color; | |
} | |
public void addModel(Model3D model3D) { | |
mModels.add(model3D); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class BasicGLRenderer implements GLSurfaceView.Renderer { | |
... | |
private List<Model3D> mModels = new LinkedList<>(); | |
@Override | |
public void onDrawFrame(GL10 gl) { | |
... | |
for(Model3D model : mModels) { | |
model.draw(mMVPMatrix); | |
} | |
} | |
public void addModel(Model3D model3D) { | |
mModels.add(model3D); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class EasyGLView extends GLSurfaceView { | |
public EasyGLView(Context context) { | |
super(context); | |
init(); | |
} | |
public EasyGLView(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
init(); | |
} | |
private void init() { | |
setEGLConfigChooser(8, 8, 8, 8, 16, 0); | |
setEGLContextClientVersion(2); | |
GLHelper.setContext(getContext().getApplicationContext()); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ExampleFragment extends Fragment { | |
private EasyGLView mEasyGLView; | |
private BasicGLRenderer mBasicRenderer; | |
@Nullable | |
@Override | |
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { | |
ViewGroup viewGroup = (ViewGroup) inflater.inflate(R.layout.fragment_example, container, false); | |
mEasyGLView = (EasyGLView) viewGroup.findViewById(R.id.easygl); | |
setupWorld(); | |
return viewGroup; | |
} | |
private void setupWorld() { | |
GLCameraOptions glCameraOptions = new GLCameraOptions() | |
.setEye(0, 0, -3.0f) | |
.setUp(0, 1.0f, 0) | |
.setDepthRange(0.5f, 100.0f); | |
mBasicRenderer = new BasicGLRenderer(glCameraOptions); | |
mBasicRenderer.setBackgroundColor(Color.BLUE); | |
mEasyGLView.setRenderer(mBasicRenderer); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
android:layout_width="match_parent" android:layout_height="match_parent"> | |
<ar.com.wolox.easygl.view.EasyGLView | |
android:id="@+id/easygl" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" /> | |
</FrameLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class GLCameraOptions { | |
public float eyeX; | |
public float eyeY; | |
public float eyeZ; | |
public float centerX; | |
public float centerY; | |
public float centerZ; | |
public float upX; | |
public float upY; | |
public float upZ; | |
public float near; | |
public float far; | |
public GLCameraOptions setEye(float x, float y, float z) { | |
eyeX = x; | |
eyeY = y; | |
eyeZ = z; | |
return this; | |
} | |
public GLCameraOptions setCenter(float x, float y, float z) { | |
centerX = x; | |
centerY = y; | |
centerZ = z; | |
return this; | |
} | |
public GLCameraOptions setUp(float x, float y, float z) { | |
upX = x; | |
upY = y; | |
upZ = z; | |
return this; | |
} | |
public GLCameraOptions setDepthRange(float near, float far) { | |
this.near = near; | |
this.far = far; | |
return this; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class GLHelper { | |
private static final String TAG = "GLHelper"; | |
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); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public abstract class Model3D { | |
private Integer mProgram; | |
private int mColorHandle; | |
private float[] mColor; | |
private String mVertexShader; | |
private String mFragmentShader; | |
private void setupShaders() { | |
mProgram = GLES20.glCreateProgram(); | |
GLES20.glAttachShader(mProgram, | |
GLHelper.loadShader(GLES20.GL_VERTEX_SHADER, mVertexShader)); | |
GLES20.glAttachShader(mProgram, | |
GLHelper.loadShader(GLES20.GL_FRAGMENT_SHADER, mFragmentShader)); | |
GLES20.glLinkProgram(mProgram); | |
} | |
public void draw(float[] mvpMatrix) { | |
if(mProgram == null) { | |
if(mVertexShader == null || mFragmentShader == null) { | |
return; | |
}; | |
setupShaders(); | |
} | |
GLES20.glUseProgram(mProgram); | |
GLHelper.checkGlError("glUseProgram"); | |
int positionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition"); | |
GLHelper.checkGlError("glGetAttribLocation"); | |
GLES20.glEnableVertexAttribArray(positionHandle); | |
GLHelper.checkGlError("glEnableVertexAttribArray"); | |
GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 0, getVertexBuffer()); | |
GLHelper.checkGlError("glVertexAttribPointer"); | |
if(mColor != null) { | |
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor"); | |
GLHelper.checkGlError("glGetUniformLocation"); | |
GLES20.glUniform4fv(mColorHandle, 1, mColor, 0); | |
GLHelper.checkGlError("glUniform4fv"); | |
} | |
int matrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); | |
GLHelper.checkGlError("glGetUniformLocation"); | |
GLES20.glUniformMatrix4fv(matrixHandle, 1, false, mvpMatrix, 0); | |
GLHelper.checkGlError("glUniformMatrix4fv"); | |
GLES20.glDrawElements(GLES20.GL_TRIANGLES, getIndexBuffer().capacity(), GLES20.GL_UNSIGNED_SHORT, getIndexBuffer()); | |
GLHelper.checkGlError("glDrawElements"); | |
GLES20.glDisableVertexAttribArray(positionHandle); | |
GLHelper.checkGlError("glDisableVertexAttribArray"); | |
} | |
protected abstract FloatBuffer getVertexBuffer(); | |
protected abstract ShortBuffer getIndexBuffer(); | |
public void setColor(int color) { | |
mColor = new float[] {GLColor.r(color), GLColor.g(color), GLColor.b(color), GLColor.a(color)}; | |
if(mVertexShader == null || mFragmentShader == null) { | |
setShaders(Shaders.COLOR_VERTEX_SHADER, Shaders.COLOR_FRAGMENT_SHADER); | |
} | |
} | |
private void setShaders(String vertexShader, String fragmentShader) { | |
mVertexShader = vertexShader; | |
mFragmentShader = fragmentShader; | |
mProgram = null; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Shaders { | |
public static final String COLOR_VERTEX_SHADER = | |
"uniform mat4 uMVPMatrix;\n" + | |
"attribute vec4 vPosition;\n" + | |
"void main() {\n" + | |
" gl_Position = uMVPMatrix * vPosition;\n" + | |
" gl_PointSize = 10.0;\n" + | |
"}"; | |
public static final String COLOR_FRAGMENT_SHADER = | |
"precision mediump float;\n" + | |
"uniform vec4 vColor;\n" + | |
"void main() {\n" + | |
" gl_FragColor = vColor;\n" + | |
"}"; | |
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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Triangle extends Model3D { | |
private FloatBuffer vertexBuffer; | |
static final int COORDS_PER_VERTEX = 3; | |
static float triangleCoords[] = { // in counterclockwise order: | |
0.0f, 1.0f, 0.0f, // top | |
-0.5f, -0.5f, 0.0f, // bottom left | |
0.5f, -0.5f, 0.0f // bottom right | |
}; | |
static final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX; | |
private ShortBuffer indexBuffer; | |
public Triangle() { | |
super(); | |
init(); | |
} | |
private void init() { | |
// initialize vertex byte buffer for shape coordinates | |
ByteBuffer bb = ByteBuffer.allocateDirect( | |
// (number of coordinate values * 4 bytes per float) | |
triangleCoords.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(triangleCoords); | |
// set the buffer to read the first coordinate | |
vertexBuffer.position(0); | |
indexBuffer = ShortBuffer.allocate(vertexCount); | |
indexBuffer.put((short)0); | |
indexBuffer.put((short)1); | |
indexBuffer.put((short)2); | |
indexBuffer.rewind(); | |
} | |
@Override | |
protected FloatBuffer getVertexBuffer() { | |
return vertexBuffer; | |
} | |
@Override | |
protected ShortBuffer getIndexBuffer() { | |
return indexBuffer; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment