无法让samplerCube / textureCube在OpenGL ES 2.0(Android)中运行

时间:2012-03-07 21:50:13

标签: android opengl-es-2.0 textures shader cube

我迫切需要帮助让samplerCube / textureCube工作。我花了很多时间尝试,但无法让它发挥作用。我搜索过谷歌,但我找不到一个有效的完整示例,我可以从中复制。

下面的代码显示了一个带有中心线的翻滚深蓝色立方体(放在那里以帮助调试)。中心线的存在意味着我正确地定义了纹理坐标。我不能做的是检查纹理的加载 - 每个纹理都是48x48像素。

我做错了什么?

public class HelloTexturedCubeRenderer implements GLSurfaceView.Renderer
{   //  constructor
    //  ===========

    public HelloTexturedCubeRenderer( GLSurfaceView view )
    {   m_view             = view;
        m_matrixModel      = new float[ 16 ];
        m_matrixProjection = new float[ 16 ];
        m_matrixView       = new float[ 16 ];
        m_matrixViewProj   = new float[ 16 ];

        float[] faces   =  {  1.0f,  1.0f,  1.0f,    -1.0f,  1.0f,  1.0f,    -1.0f, -1.0f,  1.0f,     1.0f, -1.0f,  1.0f,
                              1.0f,  1.0f,  1.0f,     1.0f, -1.0f,  1.0f,     1.0f, -1.0f, -1.0f,     1.0f,  1.0f, -1.0f,
                              1.0f, -1.0f, -1.0f,    -1.0f, -1.0f, -1.0f,    -1.0f,  1.0f, -1.0f,     1.0f,  1.0f, -1.0f,
                             -1.0f,  1.0f,  1.0f,    -1.0f,  1.0f, -1.0f,    -1.0f, -1.0f, -1.0f,    -1.0f, -1.0f,  1.0f,
                              1.0f,  1.0f,  1.0f,     1.0f,  1.0f, -1.0f,    -1.0f,  1.0f, -1.0f,    -1.0f,  1.0f,  1.0f,
                              1.0f, -1.0f,  1.0f,    -1.0f, -1.0f,  1.0f,    -1.0f, -1.0f, -1.0f,     1.0f, -1.0f, -1.0f,
                           };
        short[] indices  = {  0,  1,  2,     0,  2,  3,
                              4,  5,  6,     4,  6,  7,
                              8,  9, 10,     8, 10, 11,
                             12, 13, 14,    12, 14, 15,
                             16, 17, 18,    16, 18, 19,
                             20, 21, 22,    20, 22, 23
                           };
        float[] vertices = {  1.0f,  1.0f,  1.0f,    -1.0f,  1.0f,  1.0f,    -1.0f, -1.0f,  1.0f,     1.0f, -1.0f,  1.0f,
                              1.0f,  1.0f,  1.0f,     1.0f, -1.0f,  1.0f,     1.0f, -1.0f, -1.0f,     1.0f,  1.0f, -1.0f,
                              1.0f, -1.0f, -1.0f,    -1.0f, -1.0f, -1.0f,    -1.0f,  1.0f, -1.0f,     1.0f,  1.0f, -1.0f,
                             -1.0f,  1.0f,  1.0f,    -1.0f,  1.0f, -1.0f,    -1.0f, -1.0f, -1.0f,    -1.0f, -1.0f,  1.0f,
                              1.0f,  1.0f,  1.0f,     1.0f,  1.0f, -1.0f,    -1.0f,  1.0f, -1.0f,    -1.0f,  1.0f,  1.0f,
                              1.0f, -1.0f,  1.0f,    -1.0f, -1.0f,  1.0f,    -1.0f, -1.0f, -1.0f,     1.0f, -1.0f, -1.0f
                           };

        ByteBuffer byteBuffer;

        byteBuffer = ByteBuffer.allocateDirect( 4 * faces.length );
        byteBuffer.order( ByteOrder.nativeOrder( ));
        m_bufferFaces = byteBuffer.asFloatBuffer( );
        m_bufferFaces.put( faces );
        m_bufferFaces.position( 0 );

        byteBuffer = ByteBuffer.allocateDirect( 4 * indices.length );
        byteBuffer.order( ByteOrder.nativeOrder( ));
        m_bufferIndices = byteBuffer.asShortBuffer( );
        m_bufferIndices.put( indices );
        m_bufferIndices.position( 0 );

        byteBuffer = ByteBuffer.allocateDirect( 4 * vertices.length );
        byteBuffer.order( ByteOrder.nativeOrder( ));
        m_bufferVertex = byteBuffer.asFloatBuffer( );
        m_bufferVertex.put( vertices );
        m_bufferVertex.position( 0 );
    }

    //  loadProgram
    //  ===========

    private void loadProgram( )
    {   m_programId        = -1;
        int fragmentShader = loadShader( FragmentShaderCode, GLES20.GL_FRAGMENT_SHADER );
        int vertexShader   = loadShader( VertexShaderCode,   GLES20.GL_VERTEX_SHADER   );

        if( fragmentShader == 0 || vertexShader == 0 )
            return;

        m_programId = GLES20.glCreateProgram( );

        GLES20.glAttachShader( m_programId, vertexShader   );
        GLES20.glAttachShader( m_programId, fragmentShader );
        GLES20.glLinkProgram( m_programId );
        GLES20.glDeleteShader( vertexShader   );
        GLES20.glDeleteShader( fragmentShader );
    }

    //  loadShader
    //  ==========

    private int loadShader( String source, int type )
    {   int[] array  = new int[ 1 ];
        int   shader = GLES20.glCreateShader( type );

        GLES20.glShaderSource( shader, source );
        GLES20.glCompileShader( shader );
        GLES20.glGetShaderiv( shader, GLES20.GL_COMPILE_STATUS, array, 0 );

        if( array[ 0 ] != 0 )
            return shader;

        GLES20.glGetShaderiv( shader, GLES20.GL_INFO_LOG_LENGTH, array, 0 );
        Log.e( "loadShader", "compile of shader failed - shader log: " + GLES20.glGetShaderInfoLog( shader ));

        return 0;
    }

    //  loadTexture
    //  ===========

    private void loadTexture( )
    {
        int textures[] = new int[ 1 ];

        GLES20.glGenTextures( 1, textures, 0 );
        GLES20.glBindTexture( GLES20.GL_TEXTURE_CUBE_MAP, textures[ 0 ]);

        GLUtils.texImage2D( GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, BitmapFactory.decodeResource( m_view.getResources( ), R.raw.brick1 ), 0 );
        GLUtils.texImage2D( GLES20.GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, BitmapFactory.decodeResource( m_view.getResources( ), R.raw.brick2 ), 0 );
        GLUtils.texImage2D( GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, BitmapFactory.decodeResource( m_view.getResources( ), R.raw.brick3 ), 0 );
        GLUtils.texImage2D( GLES20.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, BitmapFactory.decodeResource( m_view.getResources( ), R.raw.brick4 ), 0 );
        GLUtils.texImage2D( GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, BitmapFactory.decodeResource( m_view.getResources( ), R.raw.brick5 ), 0 );
        GLUtils.texImage2D( GLES20.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, BitmapFactory.decodeResource( m_view.getResources( ), R.raw.brick6 ), 0 );

        GLES20.glGenerateMipmap( GLES20.GL_TEXTURE_CUBE_MAP );

        GLES20.glTexParameteri( GLES20.GL_TEXTURE_CUBE_MAP, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST );
        GLES20.glTexParameteri( GLES20.GL_TEXTURE_CUBE_MAP, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST );
        GLES20.glTexParameteri( GLES20.GL_TEXTURE_CUBE_MAP, GLES20.GL_TEXTURE_WRAP_S,     GLES20.GL_CLAMP_TO_EDGE        );
        GLES20.glTexParameteri( GLES20.GL_TEXTURE_CUBE_MAP, GLES20.GL_TEXTURE_WRAP_T,     GLES20.GL_CLAMP_TO_EDGE        );

        m_textureId = textures[ 0 ];
    }

    //  onDrawFrame
    //  ===========

    public void onDrawFrame( GL10 unused )
    {   GLES20.glClear( GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT );
        GLES20.glUseProgram( m_programId );

        float angle = (SystemClock.uptimeMillis( ) / 15) % 360;
        Matrix.setRotateM( m_matrixModel, 0, angle, 1.0f, 1.0f, 1.0f );

        Matrix.multiplyMM( m_matrixViewProj, 0, m_matrixView,       0, m_matrixModel,    0 );
        Matrix.multiplyMM( m_matrixViewProj, 0, m_matrixProjection, 0, m_matrixViewProj, 0 );

        GLES20.glUniformMatrix4fv( m_vpMatrixPtr, 1, false, m_matrixViewProj, 0 );
        GLES20.glDrawElements( GLES20.GL_TRIANGLES, 36, GLES20.GL_UNSIGNED_SHORT, m_bufferIndices );
    }

    //  onSurfaceChanged
    //  ================

    public void onSurfaceChanged( GL10 unused, int width, int height )
    {   GLES20.glViewport( 0, 0, width, height );

        float ratio = (float) width / height;
        Matrix.frustumM( m_matrixProjection, 0, -ratio, ratio, -1, 1, 1, 15 );
    }

    //  onSurfaceCreated
    //  ================

    public void onSurfaceCreated( GL10 unused, EGLConfig config )
    {   GLES20.glClearColor( 0.5f, 0.5f, 0.5f, 1.0f );

        GLES20.glEnable( GLES20.GL_DEPTH_TEST );
        GLES20.glDepthFunc( GLES20.GL_LEQUAL );
        GLES20.glFrontFace( GLES20.GL_CCW );

        GLES20.glEnable( GLES20.GL_CULL_FACE );
        GLES20.glCullFace( GLES20.GL_BACK );

        Matrix.setLookAtM( m_matrixView, 0, 0.0f, 0.0f, 4.0f,
                                            0.0f, 0.0f, 0.0f,
                                            0.0f, 1.0f, 0.0f );
        loadProgram( );

        m_facesPtr    = GLES20.glGetAttribLocation(  m_programId, "faces"    );
        m_texturePtr  = GLES20.glGetUniformLocation( m_programId, "texture"  );
        m_verticesPtr = GLES20.glGetAttribLocation(  m_programId, "vertices" );
        m_vpMatrixPtr = GLES20.glGetUniformLocation( m_programId, "vpMatrix" );

        GLES20.glUseProgram( m_programId );

        GLES20.glVertexAttribPointer( m_facesPtr,    3, GLES20.GL_FLOAT, false, 0, m_bufferFaces  );
        GLES20.glVertexAttribPointer( m_verticesPtr, 3, GLES20.GL_FLOAT, false, 0, m_bufferVertex );

        GLES20.glEnableVertexAttribArray( m_facesPtr    );
        GLES20.glEnableVertexAttribArray( m_verticesPtr );

        loadTexture( );

        GLES20.glActiveTexture( GLES20.GL_TEXTURE0 );
        GLES20.glBindTexture( GLES20.GL_TEXTURE_CUBE_MAP, m_textureId );
        GLES20.glUniform1i( m_texturePtr, 0 );
    }

    //  private stuff
    //  =============

    private FloatBuffer   m_bufferFaces;
    private ShortBuffer   m_bufferIndices;
    private FloatBuffer   m_bufferVertex;
    private int           m_facesPtr;
    private float[]       m_matrixModel;
    private float[]       m_matrixProjection;
    private float[]       m_matrixView;
    private float[]       m_matrixViewProj;
    private int           m_programId;
    private int           m_textureId;
    private int           m_texturePtr;
    private int           m_verticesPtr;
    private GLSurfaceView m_view;
    private int           m_vpMatrixPtr;

    private final String FragmentShaderCode = "precision mediump     float;\n"   +
                                              "varying   vec3        face;\n"    +
                                              "uniform   samplerCube texture;\n" +

                                              "void main( )\n"                   +
                                              "{    if( abs( face.x ) < 0.01 )"  +
                                              "         gl_FragColor = vec4( 1, 0, 0, 1 );\n" +
                                              "     else\n"                      +
                                              "     if( abs( face.y ) < 0.01 )"  +
                                              "         gl_FragColor = vec4( 0, 1, 0, 1 );\n" +
                                              "     else\n"                      +
                                              "     if( abs( face.z ) < 0.01 )"  +
                                              "         gl_FragColor = vec4( 0, 0, 1, 1 );\n" +
                                              "     else\n"                      +
                                              "     {   gl_FragColor = textureCube( texture, face );\n" +

                                              "         if( gl_FragColor.b < 0.01 )\n" +
                                              "             gl_FragColor.b = 0.3;\n"   +
                                              "     }\n" +
                                              "}\n";

    private final String VertexShaderCode  =  "varying   vec3 face;\n"     +
                                              "attribute vec3 faces;\n"    +
                                              "attribute vec4 vertices;\n" +
                                              "uniform   mat4 vpMatrix;\n" +

                                              "void main( )\n"             +
                                              "{    face = faces;\n"       +
                                              "     gl_Position = vpMatrix * vertices;\n" +
                                              "}";
}

1 个答案:

答案 0 :(得分:1)

问题不在代码中,而是在我用作纹理的两个图像中。

虽然在我的笔记本电脑上打开时显示正常,但它们一定存在问题。当我在Gimp打开它们时,做了一些转换,转换了转换并重新保存了图像,一切都很顺利。

呼!!!!!