java - Drawing a sphere in OpenGL ES 2.0 -
i'm trying draw sphere in opengl es 2.0 on android. looked @ related questions , tried of code still can't work.
based on android developer examples , this code found on gamedev.net came code below. not drawing correctly; when using gldrawarrays() rendering works results not correct, when using gldrawelements() gl_invalid_operation error. listed contents of buffers below.
sphere.java
public class sphere { private int stacks; private int slices; private float radius; //buffers private floatbuffer vertexbuffer; private floatbuffer colorbuffer; private shortbuffer indexbuffer; //buffer sizes in aantal bytes private int vertexbuffersize; private int colorbuffersize; private int indexbuffersize; private int vertexcount; private int program; static final int floats_per_vertex = 3; // het aantal floats in een vertex (x, y, z) static final int floats_per_color = 4; // het aantal floats in een kleur (r, g, b, a) static final int shorts_per_index = 2; static final int bytes_per_float = 4; static final int bytes_per_short = 2; static final int bytes_per_vertex = floats_per_vertex * bytes_per_float; static final int bytes_per_color = floats_per_color * bytes_per_float; static final int bytes_per_index_entry = shorts_per_index * bytes_per_short; // set color red, green, blue , alpha (opacity) values private float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f }; public sphere(float radius, int stacks, int slices) { this.stacks = stacks; this.slices = slices; this.radius = radius; vertexcount = (stacks+1) * (slices+1); vertexbuffersize = vertexcount * bytes_per_vertex; colorbuffersize = vertexcount * bytes_per_color; indexbuffersize = vertexcount * bytes_per_index_entry; program = glhelpers.createprogram(); if (program == 0) { return; } glhelpers.checkglerror("program"); // setup vertex-array buffer. vertices in float. float has 4 bytes. vertexbuffer = bytebuffer.allocatedirect(vertexbuffersize).order(byteorder.nativeorder()).asfloatbuffer(); colorbuffer = bytebuffer.allocatedirect(colorbuffersize).order(byteorder.nativeorder()).asfloatbuffer(); indexbuffer = bytebuffer.allocatedirect(indexbuffersize).order(byteorder.nativeorder()).asshortbuffer(); generatespherecoords(radius, stacks, slices); vertexbuffer.position(0); colorbuffer.position(0); indexbuffer.position(0); } public void draw(float[] modelviewprojectionmatrix) { gles20.gluseprogram(program); glhelpers.checkglerror("useprogram"); int positionhandle = gles20.glgetattriblocation(program, "a_position"); gles20.glenablevertexattribarray(positionhandle); gles20.glvertexattribpointer(positionhandle, 3, gles20.gl_float, false, bytes_per_vertex, vertexbuffer); glhelpers.checkglerror("pos"); //int colorhandle = gles20.glgetattriblocation(program, "a_color"); //gles20.glenablevertexattribarray(colorhandle); //gles20.glvertexattribpointer(colorhandle, 4, gles20.gl_float, false, bytes_per_color, colorbuffer); //glhelpers.checkglerror("color"); int matrixhandle = gles20.glgetuniformlocation(program, "u_matrix"); gles20.gluniformmatrix4fv(matrixhandle, 1, false, modelviewprojectionmatrix, 0); /* * when using gldrawarrays rendering works results not correct, when using gldrawelements gl_invalid_operation error. */ gles20.gldrawelements(gles20.gl_triangle_strip, indexbuffer.capacity(), gles20.gl_short, indexbuffer); //gles20.gldrawarrays(gles20.gl_triangle_strip, 0, vertexcount); glhelpers.checkglerror("draw"); // disable vertex array gles20.gldisablevertexattribarray(positionhandle); //gles20.gldisablevertexattribarray(colorhandle); } private void generatespherecoords(float radius, int stacks, int slices) { (int stacknumber = 0; stacknumber <= stacks; ++stacknumber) { (int slicenumber = 0; slicenumber < slices; ++slicenumber) { float theta = (float) (stacknumber * math.pi / stacks); float phi = (float) (slicenumber * 2 * math.pi / slices); float sintheta = floatmath.sin(theta); float sinphi = floatmath.sin(phi); float costheta = floatmath.cos(theta); float cosphi = floatmath.cos(phi); vertexbuffer.put(new float[]{radius * cosphi * sintheta, radius * sinphi * sintheta, radius * costheta}); } } (int stacknumber = 0; stacknumber < stacks; ++stacknumber) { (int slicenumber = 0; slicenumber <= slices; ++slicenumber) { indexbuffer.put((short) ((stacknumber * slices) + (slicenumber % slices))); indexbuffer.put((short) (((stacknumber + 1) * slices) + (slicenumber % slices))); } } } } glhelpers.java
public class glhelpers { private static final string tag = "glhelpers"; private static final string vertex_shader_code = "uniform mat4 u_matrix;" + "attribute vec4 a_position;" + "attribute vec4 a_color;" + "varying vec4 v_color;" + "void main() {" + " v_color = a_color;" + " gl_position = a_position * u_matrix;" + "}"; private static final string fragment_shader_code = "precision mediump float;" + "varying vec4 v_color;" + "void main() {" + " gl_fragcolor = v_color;" + "}"; private static int loadshader(int shadertype, string source) { int shader = gles20.glcreateshader(shadertype); if (shader != 0) { gles20.glshadersource(shader, source); gles20.glcompileshader(shader); int[] compiled = new int[1]; gles20.glgetshaderiv(shader, gles20.gl_compile_status, compiled, 0); if (compiled[0] == 0) { log.e(tag, "could not compile shader " + shadertype + ":"); log.e(tag, gles20.glgetshaderinfolog(shader)); gles20.gldeleteshader(shader); shader = 0; } } return shader; } public static int createprogram() { int vertexshader = glhelpers.loadshader(gles20.gl_vertex_shader, glhelpers.vertex_shader_code); if (vertexshader == 0) return 0; int pixelshader = glhelpers.loadshader(gles20.gl_fragment_shader, glhelpers.fragment_shader_code); if (pixelshader == 0) return 0; int program = gles20.glcreateprogram(); if (program != 0) { gles20.glattachshader(program, vertexshader); glhelpers.checkglerror("glattachshader"); gles20.glattachshader(program, pixelshader); glhelpers.checkglerror("glattachshader"); gles20.gllinkprogram(program); int[] linkstatus = new int[1]; gles20.glgetprogramiv(program, gles20.gl_link_status, linkstatus, 0); if (linkstatus[0] != gles20.gl_true) { log.e(tag, "could not link program: "); log.e(tag, gles20.glgetprograminfolog(program)); gles20.gldeleteprogram(program); program = 0; } } return program; } 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); } } } the contents of vertexbuffer
x y z 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, -0.0, 0.0, 1.0, -0.0, -0.0, 1.0, 0.0, -0.0, 1.0, 0.58778524, 0.0, 0.809017, 0.18163562, 0.559017, 0.809017, -0.4755283, 0.34549147, 0.809017, -0.4755282, -0.34549156, 0.809017, 0.18163571, -0.55901694, 0.809017, 0.95105654, 0.0, 0.30901697, 0.29389262, 0.90450853, 0.30901697, -0.769421, 0.55901694, 0.30901697, -0.76942086, -0.5590171, 0.30901697, 0.29389274, -0.9045085, 0.30901697, 0.9510565, 0.0, -0.30901703, 0.2938926, 0.9045085, -0.30901703, -0.7694209, 0.5590169, -0.30901703, -0.7694208, -0.55901706, -0.30901703, 0.29389274, -0.9045084, -0.30901703, 0.5877852, 0.0, -0.80901706, 0.1816356, 0.55901694, -0.80901706, -0.47552824, 0.3454914, -0.80901706, -0.47552818, -0.34549153, -0.80901706, 0.1816357, -0.5590169, -0.80901706, -8.742278e-8, -0.0, -1.0, -2.7015123e-8, -8.3144e-8, -1.0, 7.0726514e-8, -5.138581e-8, -1.0, 7.072651e-8, 5.138583e-8, -1.0, -2.7015135e-8, 8.3143995e-8, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 the contents of indexbuffer
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] the result when using gldrawarrays():

you're setting vertexcount lat * lon * bytes per float, looks weird me.
i think have misnamed variable, number of vertices has nothing bytes per float.
you're using same variable in gldrawarrays, seems me not have accurate number of vertices.
Comments
Post a Comment