0

最近、Windows 用の OpenGL を学びましたが、Android でも試してみたいと思っています。いくつかのチュートリアルを確認したところ、このサンプルのハッキングを開始しました: http://blog.shayanjaved.com/2011/03/13/shaders-android/

このアプリではメッシュを選択できますが、同時に 2 つのメッシュを描画したいと考えています。drawRoad 関数と drawCar 関数を作りました。

private void drawCar(int program){



    /*** DRAWING OBJECT **/
    // Get buffers from mesh
    Object3D ob = this._objects[this.CUBE];
    Mesh mesh = ob.getMesh();
    FloatBuffer _vb = mesh.get_vb();
    ShortBuffer _ib = mesh.get_ib();

    short[] _indices = mesh.get_indices();

    // Vertex buffer

    // the vertex coordinates
    _vb.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
    GLES20.glVertexAttribPointer(GLES20.glGetAttribLocation(program, "aPosition"), 3, GLES20.GL_FLOAT, false,
            TRIANGLE_VERTICES_DATA_STRIDE_BYTES, _vb);
    GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(program, "aPosition"));

    // the normal info
    _vb.position(TRIANGLE_VERTICES_DATA_NOR_OFFSET);
    GLES20.glVertexAttribPointer(GLES20.glGetAttribLocation(program, "aNormal"), 3, GLES20.GL_FLOAT, false,
            TRIANGLE_VERTICES_DATA_STRIDE_BYTES, _vb);
    GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(program, "aNormal"));

    // Texture info

    // bind textures
    if (ob.hasTexture()) {// && enableTexture) {
        // number of textures
        int[] texIDs = ob.get_texID(); 

        for(int i = 0; i < _texIDs.length; i++) {
            GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + i);
            Log.d("TEXTURE BIND: ", i + " " + texIDs[i]);
            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texIDs[i]);
            GLES20.glUniform1i(GLES20.glGetUniformLocation(program, "texture" + (i+1)), i);
        }
    }

    // enable texturing? [fix - sending float is waste]
    GLES20.glUniform1f(GLES20.glGetUniformLocation(program, "hasTexture")/*shader.hasTextureHandle*/, ob.hasTexture() && enableTexture ? 2.0f : 0.0f);

    // texture coordinates
    _vb.position(TRIANGLE_VERTICES_DATA_TEX_OFFSET);
    GLES20.glVertexAttribPointer(GLES20.glGetAttribLocation(program, "textureCoord")/*shader.maTextureHandle*/, 2, GLES20.GL_FLOAT, false,
            TRIANGLE_VERTICES_DATA_STRIDE_BYTES, _vb);
    GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(program, "textureCoord"));//GLES20.glEnableVertexAttribArray(shader.maTextureHandle);

    // Draw with indices
    GLES20.glDrawElements(GLES20.GL_TRIANGLES, _indices.length, GLES20.GL_UNSIGNED_SHORT, _ib);
    checkGlError("glDrawElements");

    /** END DRAWING OBJECT ***/

}



private void drawRoad(int program){


    /*** DRAWING OBJECT **/
    // Get buffers from mesh
    Object3D ob = this._objects[this.ROAD];
    Mesh mesh = ob.getMesh();
    FloatBuffer _vb = mesh.get_vb();
    ShortBuffer _ib = mesh.get_ib();

    short[] _indices = mesh.get_indices();

    // Vertex buffer

    // the vertex coordinates
    _vb.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
    GLES20.glVertexAttribPointer(GLES20.glGetAttribLocation(program, "aPosition"), 3, GLES20.GL_FLOAT, false,
            TRIANGLE_VERTICES_DATA_STRIDE_BYTES, _vb);
    GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(program, "aPosition"));

    // the normal info
    _vb.position(TRIANGLE_VERTICES_DATA_NOR_OFFSET);
    GLES20.glVertexAttribPointer(GLES20.glGetAttribLocation(program, "aNormal"), 3, GLES20.GL_FLOAT, false,
            TRIANGLE_VERTICES_DATA_STRIDE_BYTES, _vb);
    GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(program, "aNormal"));

    // Texture info

    // bind textures
    if (ob.hasTexture()) {// && enableTexture) {
        // number of textures
        int[] texIDs = ob.get_texID(); 

        for(int i = 0; i < _texIDs.length; i++) {
            GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + i);
            //Log.d("TEXTURE BIND: ", i + " " + texIDs[i]);
            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texIDs[i]);
            GLES20.glUniform1i(GLES20.glGetUniformLocation(program, "texture" + (i+1)), i);
        }
    }

    // enable texturing? [fix - sending float is waste]
    GLES20.glUniform1f(GLES20.glGetUniformLocation(program, "hasTexture")/*shader.hasTextureHandle*/, ob.hasTexture() && enableTexture ? 2.0f : 0.0f);

    // texture coordinates
    _vb.position(TRIANGLE_VERTICES_DATA_TEX_OFFSET);
    GLES20.glVertexAttribPointer(GLES20.glGetAttribLocation(program, "textureCoord")/*shader.maTextureHandle*/, 2, GLES20.GL_FLOAT, false,
            TRIANGLE_VERTICES_DATA_STRIDE_BYTES, _vb);
    GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(program, "textureCoord"));//GLES20.glEnableVertexAttribArray(shader.maTextureHandle);

    // Draw with indices
    GLES20.glDrawElements(GLES20.GL_TRIANGLES, _indices.length, GLES20.GL_UNSIGNED_SHORT, _ib);
    checkGlError("glDrawElements");

    /** END DRAWING OBJECT ***/

その後、いくつかの基本的な変換を行い、行列を onDrawFrame 関数でシェーダーに送信します。

public void onDrawFrame(GL10 glUnused) {
    // Ignore the passed-in GL10 interface, and use the GLES20
    // class's static methods instead.
    GLES20.glClearColor(.0f, .0f, .0f, 1.0f);
    GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);

    GLES20.glUseProgram(0);
    // the current shader
    Shader shader = _shaders[this._currentShader]; // PROBLEM!
    int program = shader.get_program();

    // Start using the shader
    GLES20.glUseProgram(program);
    checkGlError("glUseProgram");

    // eye position
    GLES20.glUniform3fv(GLES20.glGetUniformLocation(program, "eyePos")/*shader.eyeHandle*/, 1, eyePos, 0);

    setLight(program);


    Matrix.setIdentityM(mMMatrix, 0);
    Matrix.setIdentityM(mTransMatrix, 0);

    Matrix.translateM(mTransMatrix, 0, 2.0f, 5.0f, 5.0f);

    Matrix.multiplyMM(mMMatrix, 0, mMMatrix, 0, mTransMatrix, 0);    //Translate
    Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);      //View
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0); //Proj

    // send to the shader
    GLES20.glUniformMatrix4fv(GLES20.glGetUniformLocation(program, "uMVPMatrix"), 1, false, mMVPMatrix, 0);

    // Create the normal modelview matrix
    // Invert + transpose of mvpmatrix
    Matrix.invertM(normalMatrix, 0, mMVPMatrix, 0);
    Matrix.transposeM(normalMatrix, 0, normalMatrix, 0);

    // send to the shader
    GLES20.glUniformMatrix4fv(GLES20.glGetUniformLocation(program, "normalMatrix"), 1, false, mMVPMatrix, 0);

    drawCar(program);


    //**********************************************************************************************************

    Matrix.setIdentityM(mMMatrix, 0);

    Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);      //View
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0); //Proj

    // send to the shader
    GLES20.glUniformMatrix4fv(GLES20.glGetUniformLocation(program, "uMVPMatrix"), 1, false, mMVPMatrix, 0);

    // Create the normal modelview matrix
    // Invert + transpose of mvpmatrix
    Matrix.invertM(normalMatrix, 0, mMVPMatrix, 0);
    Matrix.transposeM(normalMatrix, 0, normalMatrix, 0);

    // send to the shader
    GLES20.glUniformMatrix4fv(GLES20.glGetUniformLocation(program, "normalMatrix"), 1, false, mMVPMatrix, 0);


    drawRoad(program);



}

両方のオブジェクトが描画されますが、問題は、2 つの異なるオブジェクトが 2 つの異なる世界に存在することです。最初に道路を描画し、drawCar 関数を呼び出した後、Y 軸上で -100.0 に変換しても、車 (実際には立方体です) は常に表示されます。

オブジェクトはメッシュ ファイルから読み取られ、頂点バッファーとインデックス バッファーに正しく解析され、単独で完全に表示されます。

2 つ (またはそれ以上) のオブジェクトを同じスペースに配置するにはどうすればよいですか?

4

0 に答える 0