如何在OpenGL ES 2.0中设置背景?

时间:2012-02-14 13:41:04

标签: android opengl-es

我遇到了一个问题,我无法设置OpenGL ES 2.0 Android Live壁纸的背景。    目前我已经尝试了所有方面达到我的水平。

我想设置背景选择    可绘制并设置为渲染粒子的静态背景,这些粒子都可以在移动屏幕上进行渲染。

我正在使用此代码:

public static boolean usebg = true;


///
// Constructor
//
public ParticleSystemRenderer(Context context)
{
    mContext = context;

    Log.e("check","reeach ParticleSystemRenderer()");
}


///
//  Load texture from resource
//
private int loadTexture ( InputStream is )
{
    int[] textureId = new int[1];
    Bitmap bitmap;
    bitmap = BitmapFactory.decodeStream(is);
    byte[] buffer = new byte[bitmap.getWidth() * bitmap.getHeight() * 3];

    for ( int y = 0; y < bitmap.getHeight(); y++ )
        for ( int x = 0; x < bitmap.getWidth(); x++ )
        {
            int pixel = bitmap.getPixel(x, y);
            buffer[(y * bitmap.getWidth() + x) * 3 + 0] = (byte)((pixel >> 16) & 0xFF);
            buffer[(y * bitmap.getWidth() + x) * 3 + 1] = (byte)((pixel >> 8) & 0xFF);
            buffer[(y * bitmap.getWidth() + x) * 3 + 2] = (byte)((pixel >> 0) & 0xFF);
        }

    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(bitmap.getWidth() * bitmap.getHeight() * 3);
    byteBuffer.put(buffer).position(0);

    GLES20.glGenTextures ( 1, textureId, 0 );
    GLES20.glBindTexture ( GLES20.GL_TEXTURE_2D, textureId[0] );

    GLES20.glTexImage2D ( GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGB, bitmap.getWidth(), bitmap.getHeight(), 0, 
                          GLES20.GL_RGB, GLES20.GL_UNSIGNED_BYTE, byteBuffer );

    GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR );
    GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR );
    GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE );
    GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE );

    return textureId[0];
}


///
// Initialize the shader and program object
//
public void onSurfaceCreated(GL10 glUnused, EGLConfig config)
{
    String vShaderStr =
        "uniform float u_time;                                \n" +
        "uniform vec3 u_centerPosition;                       \n" +
        "attribute float a_lifetime;                          \n" +
        "attribute vec3 a_startPosition;                      \n" +
        "attribute vec3 a_endPosition;                        \n" +
        "varying float v_lifetime;                            \n" +
        "void main()                                          \n" +
        "{                                                    \n" +
        "  if ( u_time <= a_lifetime )                        \n" +
        "  {                                                  \n" +
        "    gl_Position.xyz = a_startPosition +              \n" +
        "                      (u_time * a_endPosition);      \n" +
        "    gl_Position.xyz += u_centerPosition;             \n" +
        "    gl_Position.w = 1.0;                             \n" +
        "  }                                                  \n" +
        "  else                                               \n" +
        "     gl_Position = vec4( -1000, -1000, 0, 0 );       \n" +
        "  v_lifetime = 1.0 - ( u_time / a_lifetime );        \n" +
        "  v_lifetime = clamp ( v_lifetime, 0.0, 1.0 );       \n" +
        "  gl_PointSize = ( v_lifetime * v_lifetime ) * 40.0; \n" +
        "}";


    String fShaderStr =
        "precision mediump float;                             \n" +
        "uniform vec4 u_color;                                \n" +
        "varying float v_lifetime;                            \n" +
        "uniform sampler2D s_texture;                         \n" +
        "void main()                                          \n" +
        "{                                                    \n" +
        "  vec4 texColor;                                     \n" +
        "  texColor = texture2D( s_texture, gl_PointCoord );  \n" +
        "  gl_FragColor = vec4( u_color ) * texColor;         \n" +
        "  gl_FragColor.a *= v_lifetime;                      \n" +
        "}                                                    \n";

 // Load the shaders and get a linked program object
    mProgramObject = ESShader.loadProgram(vShaderStr, fShaderStr);

    // Get the attribute locations
    mLifetimeLoc = GLES20.glGetAttribLocation(mProgramObject, "a_lifetime");
    mStartPositionLoc = GLES20.glGetAttribLocation(mProgramObject, "a_startPosition" );
    mEndPositionLoc = GLES20.glGetAttribLocation(mProgramObject, "a_endPosition" );

    // Get the uniform locations
    mTimeLoc = GLES20.glGetUniformLocation ( mProgramObject, "u_time" );
    mCenterPositionLoc = GLES20.glGetUniformLocation ( mProgramObject, "u_centerPosition" );
    mColorLoc = GLES20.glGetUniformLocation ( mProgramObject, "u_color" );
    mSamplerLoc = GLES20.glGetUniformLocation ( mProgramObject, "s_texture" );

    GLES20.glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );

    // Fill in particle data array
    Random generator = new Random();

    for ( int i = 0; i < NUM_PARTICLES; i++ )
    {        
       // Lifetime of particle
       mParticleData[i * 7 + 0] = generator.nextFloat();

       // End position of particle
       mParticleData[i * 7 + 1] = generator.nextFloat() * 2.0f - 1.0f;
       mParticleData[i * 7 + 2] = generator.nextFloat() * 2.0f - 1.0f;
       mParticleData[i * 7 + 3] = generator.nextFloat() * 2.0f - 1.0f;

       // Start position of particle
       mParticleData[i * 7 + 4] = generator.nextFloat() * 0.25f - 0.125f;
       mParticleData[i * 7 + 5] = generator.nextFloat() * 0.25f - 0.125f;
       mParticleData[i * 7 + 6] = generator.nextFloat() * 0.25f - 0.125f;                   
    }
    mParticles = ByteBuffer.allocateDirect(mParticleData.length * 4)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
    mParticles.put(mParticleData).position(0);        

    // Initialize time to cause reset on first update
    mTime = 1.0f;

    // Load particle texture
    mTextureId = loadTexture ( mContext.getResources().openRawResource( R.raw.smoke ) );              
}

private void update()
{

    if (mLastTime == 0)
        mLastTime = SystemClock.uptimeMillis();
    long curTime = SystemClock.uptimeMillis();
    long elapsedTime = curTime - mLastTime;
    float deltaTime = elapsedTime / 1000.0f;
    mLastTime = curTime;
    mTime += deltaTime;

    if ( mTime >= 1.0f)
    {
        Random generator = new Random();
        float[] centerPos = new float[3];
        float[] color = new float[4];
        mTime = 0.0f;
        // Pick a new start location and color
        centerPos[0] = generator.nextFloat() * 1.0f - 0.5f;
        centerPos[1] = generator.nextFloat() * 1.0f - 0.5f;
        centerPos[2] = generator.nextFloat() * 1.0f - 0.5f;

        GLES20.glUniform3f( mCenterPositionLoc, centerPos[0], centerPos[1], centerPos[2]);

        // Random color
        color[0] = generator.nextFloat() * 0.5f + 0.5f;
        color[1] = generator.nextFloat() * 0.5f + 0.5f;
        color[2] = generator.nextFloat() * 0.5f + 0.5f;
        color[3] = 0.5f;

        GLES20.glUniform4f ( mColorLoc, color[0], color[1], color[2], color[3] );
    }

    // Load uniform time variable
    GLES20.glUniform1f ( mTimeLoc, mTime );
}

///
// Draw a triangle using the shader pair created in onSurfaceCreated()
//
public void onDrawFrame(GL10 glUnused)
{
     if (usebg) {
            glUnused.glDepthMask(false);
                mBg.draw(glUnused);
                glUnused.glDepthMask(true);
            }

                glUnused.glMatrixMode(GL10.GL_MODELVIEW);
                glUnused.glLoadIdentity();
    update();

    // Set the viewport
    GLES20.glViewport ( 0, 0, mWidth, mHeight );

    // Clear the color buffer
    GLES20.glClear ( GLES20.GL_COLOR_BUFFER_BIT );

    // Use the program object
    GLES20.glUseProgram ( mProgramObject );

    // Load the vertex attributes
    mParticles.position(0);
    GLES20.glVertexAttribPointer ( mLifetimeLoc, 1, GLES20.GL_FLOAT, 
                                   false, PARTICLE_SIZE * 4, 
                                   mParticles );

    mParticles.position(1);
    GLES20.glVertexAttribPointer ( mEndPositionLoc, 3, GLES20.GL_FLOAT,
                                   false, PARTICLE_SIZE * 4,
                                   mParticles );

    mParticles.position(4);
    GLES20.glVertexAttribPointer ( mStartPositionLoc, 3, GLES20.GL_FLOAT,
                                   false, PARTICLE_SIZE * 4,
                                   mParticles );


    GLES20.glEnableVertexAttribArray ( mLifetimeLoc );
    GLES20.glEnableVertexAttribArray ( mEndPositionLoc );
    GLES20.glEnableVertexAttribArray ( mStartPositionLoc );

    // Blend particles
    GLES20.glEnable ( GLES20.GL_BLEND );
    GLES20.glBlendFunc ( GLES20.GL_SRC_ALPHA, GLES20.GL_ONE );

    // Bind the texture
    GLES20.glActiveTexture ( GLES20.GL_TEXTURE0 );
    GLES20.glBindTexture ( GLES20.GL_TEXTURE_2D, mTextureId );
    GLES20.glEnable ( GLES20.GL_TEXTURE_2D );

    // Set the sampler texture unit to 0
    GLES20.glUniform1i ( mSamplerLoc, 0 );

    GLES20.glDrawArrays( GLES20.GL_POINTS, 0, NUM_PARTICLES );  


}

///
// Handle surface changes
//
public void onSurfaceChanged(GL10 glUnused, int width, int height)
{
    mWidth = width;
    mHeight = height;
   // setTex(SLWP.Tex);
    if (usebg){
        mBg.Init(glUnused);
        mBg.setDims(mWidth, mHeight);
    }
}


// Handle to a program object
private int mProgramObject;

// Attribute locations
private int mLifetimeLoc;
private int mStartPositionLoc;
private int mEndPositionLoc;

// Uniform location
private int mTimeLoc;
private int mColorLoc;
private int mCenterPositionLoc;
private int mSamplerLoc;

// Texture handle
private int mTextureId;

// Update time
private float mTime;
private long mLastTime;

// Additional member variables
private int mWidth;
private int mHeight;
private FloatBuffer mParticles;
private Context mContext;

private final int NUM_PARTICLES = 1000;
private final int PARTICLE_SIZE = 7;

private final float[] mParticleData = new float[NUM_PARTICLES * PARTICLE_SIZE]; 

currentlly我的屏幕是黑色的。

1 个答案:

答案 0 :(得分:1)

首先,有一个关于android动态壁纸的精彩教程:
http://www.learnopengles.com/how-to-use-opengl-es-2-in-an-android-live-wallpaper/

如果看起来静态背景可能需要将位图绘制到画布上或作为纹理:
Set the Background Image of a SurfaceView