android - OpenGL ES 2.0 diffuse lighting: model shows up black -
this problem bothers me week... tried load stl files , show on screen. file read properly. rendering without adding light pretty good. after add lighting , shader codes, model still there turns out black.
i followed example downloaded link below article: http://www.learnopengles.com/android-lesson-two-ambient-and-diffuse-lighting/
the shader code same example. program links fine. shaders compile fine, too. can't find out problem is. plz me.
my renderer:
public class myglrenderer implements glsurfaceview.renderer { private test test; private light1 light1; private float range = 145; private final float[] mmvmmatrix = new float[16]; private final float[] mmvpmatrix = new float[16]; private final float[] mmodelmatrix = new float[16]; private final float[] mprojectionmatrix = new float[16]; private final float[] mviewmatrix = new float[16]; protected final static float[] mlightposineyespace = new float[4]; private final float[] mlightmodelmatrix = new float[16]; private final float[] mlightposinmodelspace = new float[] {0.0f, 0.0f, 0.0f, 1.0f}; private final float[] mlightposinworldspace = new float[4]; private final float[] mtempmatrix = new float[16]; public static final float[] maccumulatedmatrix = new float[16]; private final float[] mcurrmatrix = new float[16]; public void onsurfacecreated(gl10 unused, eglconfig config) { // set background frame color gles20.glclearcolor(0.0f, 0.0f, 0.0f, 0.0f); gles20.glenable(gles20.gl_depth_test); gles20.gldepthfunc(gles20.gl_lequal); matrix.setidentitym(mtempmatrix, 0); matrix.setidentitym(maccumulatedmatrix, 0); light1 = new light1(); test = new test(); } public void ondrawframe(gl10 unused) { gles20.glclear(gles20.gl_color_buffer_bit | gles20.gl_depth_buffer_bit); matrix.setidentitym(mviewmatrix, 0); matrix.setidentitym(mmodelmatrix, 0); matrix.setidentitym(mcurrmatrix, 0); matrix.setidentitym(mlightmodelmatrix, 0); matrix.multiplymv(mlightposinworldspace, 0, mlightmodelmatrix, 0, mlightposinmodelspace, 0); matrix.multiplymv(mlightposineyespace, 0, mviewmatrix, 0, mlightposinworldspace, 0); matrix.rotatem(mcurrmatrix, 0, mangley, 0.0f, 1.0f, 0.0f); matrix.rotatem(mcurrmatrix, 0, manglex, 1.0f, 0, 0.0f); manglex = 0.0f; mangley = 0.0f; matrix.multiplymm(mtempmatrix, 0, mcurrmatrix, 0, maccumulatedmatrix, 0); system.arraycopy(mtempmatrix, 0, maccumulatedmatrix, 0, 16); matrix.multiplymm(mtempmatrix, 0, mmodelmatrix, 0, maccumulatedmatrix, 0); system.arraycopy(mtempmatrix, 0, mmodelmatrix, 0, 16); matrix.translatem(mmodelmatrix, 0, -test.meanx, -test.meany, -test.meanz); matrix.multiplymm(mmvmmatrix, 0, mviewmatrix, 0, mmodelmatrix, 0); matrix.multiplymm(mmvpmatrix, 0, mprojectionmatrix, 0, mmvmmatrix, 0); light1.draw(mmvpmatrix); test.draw(mmvpmatrix, mmvmmatrix); } public void onsurfacechanged(gl10 gl, int width, int height) { gles20.glviewport(0, 0, width, height); float ratio = (float) width / height; matrix.orthom(mprojectionmatrix, 0, -range*ratio, range*ratio, -range, range, -range, range); } public final static int loadshader(int type, string shadercode){ int shader = gles20.glcreateshader(type); gles20.glshadersource(shader, shadercode); gles20.glcompileshader(shader); return shader; } public static volatile float manglex; public static volatile float mangley; public static void setanglex(float angle) {manglex = angle;} public float getanglex() { return manglex; } public static void setangley(float angle) { mangley = angle; } public float getangley() { return mangley; }}
my code draw light is:
public class light1 { private final string vertexshadercode = "uniform mat4 u_mvpmatrix; \n" + "attribute vec4 a_position; \n" + "void main() \n" + "{ \n" + " gl_position = u_mvpmatrix \n" + " * a_position; \n" + " gl_pointsize = 5.0; \n" + "} \n"; private final string fragmentshadercode = "precision mediump float; \n" + "void main() \n" + "{ \n" + " gl_fragcolor = vec4(1.0, \n" + " 1.0, 1.0, 1.0); \n" + "} \n"; //light******************* public static float[] lightlocation = new float[] {150, 150, 0};//*********ok private final int mprogram; //light******************* public light1() { // initialize byte buffer draw list int vertexshader = myglrenderer.loadshader( gles20.gl_vertex_shader, vertexshadercode); int fragmentshader = myglrenderer.loadshader( gles20.gl_fragment_shader, fragmentshadercode); mprogram = gles20.glcreateprogram(); gles20.glattachshader(mprogram, vertexshader); gles20.glattachshader(mprogram, fragmentshader); gles20.gllinkprogram(mprogram); } public void draw(float[] mvpmatrix) { gles20.gluseprogram(mprogram); final int pointmvpmatrixhandle = gles20.glgetuniformlocation(mprogram, "u_mvpmatrix"); final int pointpositionhandle = gles20.glgetattriblocation(mprogram, "a_position"); gles20.glvertexattrib3f(pointpositionhandle, lightlocation[0], lightlocation[1], lightlocation[2]); gles20.gluniformmatrix4fv(pointmvpmatrixhandle, 1, false, mvpmatrix, 0); gles20.gldrawarrays(gles20.gl_points, 0, 1); gles20.gldisablevertexattribarray(pointpositionhandle); }}
my model code:
public class test { final string vertexshadercode = "uniform mat4 u_mvpmatrix; \n" // constant representing combined model/view/projection matrix. + "uniform mat4 u_mvmatrix; \n" // constant representing combined model/view matrix. + "uniform vec3 u_lightpos; \n" // position of light in eye space. + "attribute vec4 a_position; \n" // per-vertex position information pass in. + "attribute vec4 a_color; \n" // per-vertex color information pass in. + "attribute vec3 a_normal; \n" // per-vertex normal 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" // transform normal's orientation eye space. + " vec3 modelviewnormal = vec3(u_mvmatrix * vec4(a_normal, 0.0)); \n" // used attenuation. + " float distance = length(u_lightpos - modelviewvertex); \n" // lighting direction vector light vertex. + " vec3 lightvector = normalize(u_lightpos - modelviewvertex); \n" // calculate dot product of light vector , vertex normal. if normal , light vector // pointing in same direction max illumination. + " float diffuse = max(dot(modelviewnormal, lightvector), 0.1); \n" // attenuate light based on distance. + " diffuse = diffuse * (1.0 / (1.0 + (0.25 * distance * distance))); \n" // multiply color illumination level. interpolated across triangle. + " v_color = a_color * diffuse; \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"; private final string fragmentshadercode = "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"; private floatbuffer vertexbuffer; private floatbuffer colorbuffer; private floatbuffer normalbuffer; private final int mprogram; private int mpositionhandle; private int mnormalhandle; private int mlightlocationhandle; private int mcolorhandle; private int mmvpmatrixhandle; private int mmvmatrixhandle; final int coords_per_vertex = 3; float[] squarecoords; float[] coordsnormals; float color[]; public test() { squarecoords = glassui10.readstlbinary("test.stl"); coordsnormals = vectorcalculate.getnormbyptarray(squarecoords); color = new float[squarecoords.length/3*4]; for(int = 0; < color.length/4 ; = i+4) { color[i+0] =0.3f; color[i+1] =0.7f; color[i+2] =0.6f; color[i+3] =1.3f; } system.gc(); log.v("testloaded: ", "loaded"); // initialize vertex byte buffer shape coordinates bytebuffer bb = bytebuffer.allocatedirect(squarecoords.length * 4); bb.order(byteorder.nativeorder()); vertexbuffer = bb.asfloatbuffer(); vertexbuffer.put(squarecoords); vertexbuffer.position(0); colorbuffer = bytebuffer.allocatedirect(color.length * 4) .order(byteorder.nativeorder()).asfloatbuffer(); colorbuffer.put(color).position(0); bytebuffer nb = bytebuffer.allocatedirect(coordsnormals.length * 4); nb.order(byteorder.nativeorder()); normalbuffer = nb.asfloatbuffer(); normalbuffer.put(coordsnormals); normalbuffer.position(0); // initialize byte buffer draw list int vertexshader = myglrenderer.loadshader( gles20.gl_vertex_shader, vertexshadercode);//*********ok int fragmentshader = myglrenderer.loadshader( gles20.gl_fragment_shader, fragmentshadercode);//*********ok mprogram = gles20.glcreateprogram(); gles20.glattachshader(mprogram, vertexshader); gles20.glattachshader(mprogram, fragmentshader); gles20.glbindattriblocation(mprogram, 0, "a_position"); gles20.glbindattriblocation(mprogram, 1, "a_color"); gles20.glbindattriblocation(mprogram, 2, "a_normal"); gles20.gllinkprogram(mprogram); } public void draw(float[] mvpmatrix, float[] mvmatrix) { gles20.gluseprogram(mprogram); mmvpmatrixhandle = gles20.glgetuniformlocation(mprogram, "u_mvpmatrix"); mmvmatrixhandle = gles20.glgetuniformlocation(mprogram, "u_mvmatrix"); mlightlocationhandle = gles20.glgetuniformlocation(mprogram, "u_lightpos"); mpositionhandle = gles20.glgetattriblocation(mprogram, "a_position"); mcolorhandle = gles20.glgetuniformlocation(mprogram, "a_color"); mnormalhandle = gles20.glgetattriblocation(mprogram, "a_normal"); vertexbuffer.position(0); gles20.glvertexattribpointer(mpositionhandle, coords_per_vertex, gles20.gl_float, false, 0, vertexbuffer); gles20.glenablevertexattribarray(mpositionhandle); colorbuffer.position(0); gles20.glvertexattribpointer(mcolorhandle, 4, gles20.gl_float, false, 0, colorbuffer); gles20.glenablevertexattribarray(mcolorhandle); normalbuffer.position(0); gles20.glvertexattribpointer(mnormalhandle, coords_per_vertex, gles20.gl_float, false, 0, normalbuffer); gles20.glenablevertexattribarray(mnormalhandle); gles20.gluniformmatrix4fv(mmvmatrixhandle, 1, false, mvmatrix, 0); gles20.gluniformmatrix4fv(mmvpmatrixhandle, 1, false, mvpmatrix, 0); gles20.gluniform3f(mlightlocationhandle, myglrenderer.mlightposineyespace[0], myglrenderer.mlightposineyespace[1], myglrenderer.mlightposineyespace[2]); gles20.gldrawarrays(gles20.gl_triangles, 0, squarecoords.length/coords_per_vertex); gles20.gldrawarrays(gles20.gl_triangles, 0, vertexcount); gles20.gldisablevertexattribarray(mpositionhandle); }}
any answer appreciated!
in code, coords_per_vertex
3. in shader code "attribute vec4 a_position; \n"
, a_position vec4.
so gles20.glvertexattribpointer(mpositionhandle, coords_per_vertex, gles20.gl_float, false, 0, vertexbuffer);
has incompatible vector size.
Comments
Post a Comment