i'm learning opengl es 2 directed study , there things i'm not understanding. don't quite understand stride is passed glvertexattribpointer. able draw solid color tetrahedron, i'm trying expand make every face different color. not going well. i'm doing wrong in terms of shaders , why draws colors funky/doesn't rotate right. using http://www.learnopengles.com/android-lesson-two-ambient-and-diffuse-lighting/ base understanding how drawing works. understanding how shaders work , stride , forth , i'm doing wrong appreciated.
package com.example.lab5task1; //middle of screen 0,0. left/right -/+ x, up/down +/- y import java.nio.bytebuffer; import java.nio.byteorder; import java.nio.floatbuffer; import java.nio.shortbuffer; import java.util.random; import javax.microedition.khronos.egl.eglconfig; import javax.microedition.khronos.opengles.gl10; import android.annotation.suppresslint; import android.content.context; import android.graphics.point; import android.opengl.gles20; import android.opengl.glsurfaceview; import android.opengl.matrix; import android.os.systemclock; import android.util.log; import android.view.display; import android.view.windowmanager; public class myglrenderer implements glsurfaceview.renderer { private static final string tag = "myglrenderer"; private tetrahedron mtet; private float height, width; public float xtouch, ytouch; random rand = new random(); private final float[] mmvpmatrix = new float[16]; //model view , projection matrix private final float[] mprojmatrix = new float[16]; //projection matrix private final float[] mvmatrix = new float[16]; //view matrix private final float[] mrotationmatrix = new float[16]; //rotation matrix private float[] drawcolor = { rand.nextfloat(), rand.nextfloat(), rand.nextfloat(), 1f }; private float[] mmodelmatrix = new float[16]; @suppresslint("newapi") myglrenderer(context context) { windowmanager wm = (windowmanager) context.getsystemservice(context.window_service); display display = wm.getdefaultdisplay(); point size = new point(); display.getsize(size); //used correct drawing , touch this.height = size.y; this.width = size.x; this.xtouch = this.ytouch = 0; } @override public void onsurfacecreated(gl10 unused, eglconfig config) { gles20.glclearcolor(0.0f, 0.0f, 0.0f, 1.0f); // use culling remove faces. gles20.glenable(gles20.gl_cull_face); // enable depth testing gles20.glenable(gles20.gl_depth_test); //eye positions final float eyex = 0.0f; final float eyey = 0.0f; final float eyez = -3f; // looking toward distance final float lookx = 0.0f; final float looky = 0.0f; final float lookz = -1.0f; // set our vector. our head pointing holding camera. final float upx = 0.0f; final float upy = 1.0f; final float upz = 0.0f; // set view matrix. matrix can said represent camera position. matrix.setlookatm(mvmatrix, 0, eyex, eyey, eyez, lookx, looky, lookz, upx, upy, upz); } @override public void ondrawframe(gl10 unused) { // draw background color gles20.glclear(gles20.gl_color_buffer_bit | gles20.gl_depth_buffer_bit); matrix.setlookatm(mvmatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f); // calculate projection , view transformation matrix.multiplymm(mmvpmatrix, 0, mprojmatrix, 0, mvmatrix, 0); long time = systemclock.uptimemillis() % 10000l; float angleindegrees = (360.0f / 10000.0f) * ((int) time); mtet = new tetrahedron(); // draw triangle facing straight on. matrix.setidentitym(mrotationmatrix, 0); matrix.rotatem(mrotationmatrix, 0, angleindegrees, .5f, .5f, 0.0f); matrix.multiplymm(mmvpmatrix, 0, mrotationmatrix, 0, mmvpmatrix, 0); mtet.draw(mmvpmatrix); } @override public void onsurfacechanged(gl10 unused, int width, int height) { // adjust viewport based on geometry changes, // such screen rotation gles20.glviewport(0, 0, width, height); final float ratio = (float) width / height; final float left = -ratio; final float right = ratio; final float bottom = -1.0f; final float top = 1.0f; final float near = 1.0f; final float far = 10.0f; matrix.frustumm(mprojmatrix, 0, left, right, bottom, top, near, far); } public static int loadshader(int type, string shadercode) { // create vertex shader type (gles20.gl_vertex_shader) // or fragment shader type (gles20.gl_fragment_shader) int shader = gles20.glcreateshader(type); // add source code shader , compile 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 + ": glerror " + error); throw new runtimeexception(gloperation + ": glerror " + error); } } } class tetrahedron { enum style { old, new }; private style codetype = style.new; private final floatbuffer vertexbuffer; private final floatbuffer mcolors; private final shortbuffer drawlistbuffer; private final int mprogram; private int mpositionhandle; private int mcolorhandle; private int mmvpmatrixhandle; private int mmvmatrixhandle; private final string vertexshadercode = "uniform mat4 umvpmatrix;" + " attribute vec4 vposition;" + "void main() {" + " gl_position = vposition * umvpmatrix;" + "}"; private final string fragmentshadercode = "precision mediump float;" + "uniform vec4 vcolor;" + "void main() {" + " gl_fragcolor = vcolor;" + "}"; // number of coordinates per vertex in array // 72d angles @ center, 108 angle @ vertex static final int coords_per_vertex = 3; static final int color_data_size = 4; static float tetcoords[] = { 0.0f, 0.622008459f, 0.0f,// -0.5f, -0.311004243f, 0.0f,// 0.5f, -0.311004243f, 0.0f,// 0.0f, 0.0f, .622008459f }; static float colors[] = { //face 1 1.0f, 0.0f, 0.0f, 1.0f,// 1.0f, 0.0f, 0.0f, 1.0f,// 1.0f, 0.0f, 0.0f, 1.0f,// //face 2 0.0f, 1.0f, 0.0f, 1.0f,// 0.0f, 1.0f, 0.0f, 1.0f,// 0.0f, 1.0f, 0.0f, 1.0f,// //face 3 0.0f, 0.0f, 1.0f, 1.0f,// 0.0f, 0.0f, 1.0f, 1.0f,// 0.0f, 0.0f, 1.0f, 1.0f,// //face 4 1.0f, 1.0f, 0.0f, 1.0f,// 1.0f, 1.0f, 0.0f, 1.0f,// 1.0f, 1.0f, 0.0f, 1.0f,// }; string[] attributes = { "a_position", "a_color" }; private short draworder[] = { 0, 1, 2, 3, 0, 1 }; private final int vertexstride = coords_per_vertex * 4; // 4 bytes per vertex private final int colorstride = color_data_size * 4; float color[] = { .5f, .5f, .5f, 1f }; public tetrahedron() { // initialize vertex byte buffer shape coordinates //this.color = color; bytebuffer bb = bytebuffer.allocatedirect( // (# of coordinate values * 4 bytes per float) tetcoords.length * 4); bb.order(byteorder.nativeorder()); vertexbuffer = bb.asfloatbuffer(); vertexbuffer.put(tetcoords); vertexbuffer.position(0); // initialize byte buffer draw list // (# of coordinate values * 2 bytes per short) bytebuffer dlb = bytebuffer.allocatedirect(draworder.length * 2); dlb.order(byteorder.nativeorder()); drawlistbuffer = dlb.asshortbuffer(); drawlistbuffer.put(draworder); drawlistbuffer.position(0); mcolors = bytebuffer.allocatedirect(colors.length * 4).order(byteorder.nativeorder()) .asfloatbuffer(); mcolors.put(colors); mcolors.position(0); if (codetype == style.new) { final string vertexshader = getvertexshader(); final string fragmentshader = getfragmentshader(); int vertexshaderhandle = myglrenderer.loadshader(gles20.gl_vertex_shader, vertexshader); int fragmentshaderhandle = myglrenderer.loadshader(gles20.gl_fragment_shader, fragmentshader); mprogram = gles20.glcreateprogram(); gles20.glattachshader(mprogram, vertexshaderhandle); gles20.glattachshader(mprogram, fragmentshaderhandle); (int = 0; < attributes.length; i++) { gles20.glbindattriblocation(mprogram, i, attributes[i]); } gles20.gllinkprogram(mprogram); } else { int vertexshaderhandle = myglrenderer.loadshader(gles20.gl_vertex_shader, vertexshadercode); int fragmentshaderhandle = myglrenderer.loadshader(gles20.gl_fragment_shader, fragmentshadercode); mprogram = gles20.glcreateprogram(); gles20.glattachshader(mprogram, vertexshaderhandle); gles20.glattachshader(mprogram, fragmentshaderhandle); (int = 0; < attributes.length; i++) { gles20.glbindattriblocation(mprogram, i, attributes[i]); } gles20.gllinkprogram(mprogram); } } protected string getvertexshader() { // todo: explain why normalize vectors, explain of vector math behind all. explain eye space. final string vertexshader = "uniform mat4 u_mvpmatrix; \n" // constant representing combined model/view/projection matrix. + "uniform mat4 u_mvmatrix; \n" // constant representing combined model/view matrix. + "attribute vec4 a_position; \n" // per-vertex position information pass in. + "attribute vec4 a_color; \n" // per-vertex color information pass in. + "varying vec4 v_color; \n" // passed fragment shader. + "void main() \n" // entry point our vertex shader. + "{ \n" // transform vertex eye space. + " vec3 modelviewvertex = vec3(u_mvmatrix * a_position); \n" // multiply color illumination level. interpolated across triangle. + " v_color = a_color; \n" // gl_position special variable used store final position. // multiply vertex matrix final point in normalized screen coordinates. + " gl_position = u_mvpmatrix * a_position; \n" + "} \n"; return vertexshader; } protected string getfragmentshader() { final string fragmentshader = "precision mediump float; \n" // set default precision medium. don't need high of // precision in fragment shader. + "varying vec4 v_color; \n" // color vertex shader interpolated across // triangle per fragment. + "void main() \n" // entry point our fragment shader. + "{ \n" + " gl_fragcolor = v_color; \n" // pass color directly through pipeline. + "} \n"; return fragmentshader; } public void draw(float[] mvpmatrix) { // add program opengl environment gles20.gluseprogram(mprogram); if (codetype == style.new) { mmvpmatrixhandle = gles20.glgetuniformlocation(mprogram, "u_mvpmatrix"); mmvmatrixhandle = gles20.glgetuniformlocation(mprogram, "u_mvmatrix"); mpositionhandle = gles20.glgetattriblocation(mprogram, "a_position"); mcolorhandle = gles20.glgetattriblocation(mprogram, "a_color"); // prepare triangle coordinate data gles20.glvertexattribpointer(mpositionhandle, coords_per_vertex, gles20.gl_float, false, vertexstride, vertexbuffer); // enable handle triangle vertices gles20.glenablevertexattribarray(mpositionhandle); // pass in color information gles20.glvertexattribpointer(mcolorhandle, color_data_size, gles20.gl_float, false, colorstride, mcolors); gles20.glenablevertexattribarray(mcolorhandle); // apply projection , view transformation gles20.gluniformmatrix4fv(mmvpmatrixhandle, 1, false, mvpmatrix, 0); myglrenderer.checkglerror("gluniformmatrix4fv"); } else { // handle vertex shader's vposition member mpositionhandle = gles20.glgetattriblocation(mprogram, "vposition"); // enable handle triangle vertices gles20.glenablevertexattribarray(mpositionhandle); // prepare triangle coordinate data gles20.glvertexattribpointer(mpositionhandle, coords_per_vertex, gles20.gl_float, false, vertexstride, vertexbuffer); // handle fragment shader's vcolor member mcolorhandle = gles20.glgetuniformlocation(mprogram, "vcolor"); // set color drawing triangle gles20.gluniform4fv(mcolorhandle, 1, color, 0); // handle shape's transformation matrix mmvpmatrixhandle = gles20.glgetuniformlocation(mprogram, "umvpmatrix"); myglrenderer.checkglerror("glgetuniformlocation"); // apply projection , view transformation gles20.gluniformmatrix4fv(mmvpmatrixhandle, 1, false, mvpmatrix, 0); myglrenderer.checkglerror("gluniformmatrix4fv"); } // draw square gles20.gldrawelements(gles20.gl_triangle_strip, draworder.length, gles20.gl_unsigned_short, drawlistbuffer); // disable vertex array gles20.gldisablevertexattribarray(mpositionhandle); } }
the stride distance between attributes in bytes, , used if packing more 1 attribute same array. seems you're using 1 array per attribute here, pass in 0 stride tell opengl attributes tightly packed.
your position , color arrays should same length in terms of components. i.e. 1 position 1 color. why colors not coming out expect.
if want each face different, solid, color, setup vertices each triangle distinct, , draw gl_triangles. example:
{ 0f, 1f, 0f, // left -1, 0f, 1f, -1, 0f, -1f, 0f, 1f, 0f, // right 1f, 0f, 1f, 1f, 0f, 1f, 0f, 1f, 0f, // near -1f, 0f, 1f, 1f, 0f, 1f, 0f, 1f, 0f, // far -1f, 0f, -1f, 1f, 0f, -1f }
and draw gl_triangles. let know if leads improvement!
Comments
Post a Comment