OpenGL ES 2.0漫射照明:模型显示黑色

时间:2015-08-16 16:24:22

标签: android opengl-es light

这个问题困扰了我一个星期...... 我试图加载stl文件并在屏幕上显示它。文件已正确读取。不添加光线渲染非常好。添加灯光和着色器代码后,模型仍然存在,但结果是黑色。

我按照本文下面的链接下载的示例: http://www.learnopengles.com/android-lesson-two-ambient-and-diffuse-lighting/

着色器代码与示例完全相同。该计划链接很好。着色器编译也很好。我无法找出问题所在。 PLZ帮助我。

我的渲染器:

public class FrameA extends javax.swing.JFrame {
    FrameB b;          //creates a new JFrame called b
    FrameA a = this;    //this JFrame is assigned to a variable a
    String x;
    public FrameA() {
        initComponents();
    }
    private void btnClickMe (java.awt.event.ActionEvent evt) {
        x = jTextField1.getText();
        b = new FrameB();       //creates a new instance of FrameB
        b.setVisible (true);    //opens the new JFrame
        a.setVisible(false);    //hides or closes the current JFrame
    }
    public String getMe () {
        return x;                //attempts to get the value of x
    }
}

public class FrameB extends javax.swing.JFrame {
    FrameA a = this.FrameA();       //calls the existing JFrame FrameA
    String clickie = a.getMe(); //attempts to get the x variable from FrameA
           //assigns it to a variable then display on the textarea
    jTextArea1.setText(clickie);
    public FrameB() {
        initComponents();
    }
}

我的代码用于绘制灯光的位置:

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 the 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;
 }}

我的型号代码:

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 for the 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);
}}

任何答案都将不胜感激!

2 个答案:

答案 0 :(得分:1)

我解决了这个问题。

首先。颜色给定的循环是错误的。修正如下:

for(int i = 0; i < color.length ; i = i+4)

只有少数表面被着色;但这不是导致模型变黑的主要原因;

重点是漫反射光公式中的distance是大的;它导致diffuse变成一个非常小的值,导致RGB颜色非常接近零;

" diffuse = diffuse * (1.0 / (1.0 + (0.00000025 * distance * distance)));"

它需要一个更好的公式,但简单地减少距离值应该显示颜色和光线的影响。

答案 1 :(得分:0)

在您的代码中,COORDS_PER_VERTEX为3.但在着色器代码"attribute vec4 a_Position; \n"中,a_Position为vec4。

因此GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, 0, vertexBuffer);的矢量大小不兼容。