我迫切需要帮助让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" +
"}";
}
答案 0 :(得分:1)
问题不在代码中,而是在我用作纹理的两个图像中。
虽然在我的笔记本电脑上打开时显示正常,但它们一定存在问题。当我在Gimp打开它们时,做了一些转换,转换了转换并重新保存了图像,一切都很顺利。
呼!!!!!