问题描述
我试图让透明物体的OpenGL ES 2.0。这是一个动态壁纸,我使用GLWallpaperService作为这个基类。我设立的OpenGL是这样的:
I'm trying to make transparent object in OpenGL ES 2.0. It's a live wallpaper, I'm using GLWallpaperService as a base class for this. I'm setting up OpenGL in this way:
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glDepthFunc(GLES20.GL_GEQUAL);
GLES20.glClearDepthf(0.0f);
GLES20.glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
着色我用的是从样品的PowerVR采取OGLES2AlphaTest为阿尔法测试,我的HTC Desire设备上正常工作。
这里是code为着色器:
Shaders I use are taken from PowerVR sample OGLES2AlphaTest for alpha testing, which works fine on my HTC Desire device.Here is the code for shaders:
private final String mVertexShader = "uniform highp mat4 uMVPMatrix;\n" +
"attribute highp vec4 aPosition;\n" +
"attribute highp vec2 aTextureCoord;\n" +
"varying mediump vec2 vTextureCoord;\n" +
"void main() {\n" +
" gl_Position = uMVPMatrix * aPosition;\n" +
" vTextureCoord = aTextureCoord;\n" +
"}\n";
private final String mFragmentShader = "precision mediump float;\n" +
"varying mediump vec2 vTextureCoord;\n" +
"uniform sampler2D sTexture;\n" +
"void main() {\n" +
" vec4 base = texture2D(sTexture, vTextureCoord);\n" +
" if(base.a < 0.5){ discard; }\n" +
" gl_FragColor = base;\n" +
"}\n";
private int createProgram(String vertexSource, String fragmentSource) {
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
if (vertexShader == 0) {
return 0;
}
int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
if (pixelShader == 0) {
return 0;
}
int program = GLES20.glCreateProgram();
if (program != 0) {
GLES20.glAttachShader(program, vertexShader);
checkGlError("glAttachShader");
GLES20.glAttachShader(program, pixelShader);
checkGlError("glAttachShader");
GLES20.glLinkProgram(program);
int[] linkStatus = new int[1];
GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
if (linkStatus[0] != GLES20.GL_TRUE) {
Log.e(TAG, "Could not link program: ");
Log.e(TAG, GLES20.glGetProgramInfoLog(program));
GLES20.glDeleteProgram(program);
program = 0;
}
}
return program;
}
private int loadShader(int shaderType, String source) {
int shader = GLES20.glCreateShader(shaderType);
if (shader != 0) {
GLES20.glShaderSource(shader, source);
GLES20.glCompileShader(shader);
int[] compiled = new int[1];
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
if (compiled[0] == 0) {
Log.e(TAG, "Could not compile shader " + shaderType + ":");
Log.e(TAG, GLES20.glGetShaderInfoLog(shader));
GLES20.glDeleteShader(shader);
shader = 0;
}
}
return shader;
}
code渲染帧:
Code for rendering frame:
public void onDrawFrame(GL10 glUnused) {
//GLES20.glLinkProgram(mProgram);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
GLES20.glUseProgram(mProgram);
checkGlError("glUseProgram");
GLES20.glDisable(GLES20.GL_BLEND);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID);
mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
checkGlError("glVertexAttribPointer maPosition");
mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
GLES20.glEnableVertexAttribArray(maPositionHandle);
checkGlError("glEnableVertexAttribArray maPositionHandle");
GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
checkGlError("glVertexAttribPointer maTextureHandle");
GLES20.glEnableVertexAttribArray(maTextureHandle);
checkGlError("glEnableVertexAttribArray maTextureHandle");
long time = SystemClock.uptimeMillis() % 4000L;
float angle = 0.090f * ((int) time);
time = SystemClock.uptimeMillis();// % 4000L;
angle = 0.030f * ((int) time);
// Matrix.setRotateM(mMMatrix, 0, angle, 0, 0, 1.0f);
Matrix.setRotateM(mMMatrix, 0, angle, 0, 1.0f, 0);
Matrix.scaleM(mMMatrix, 0, 0.075f, 0.075f, 0.075f);
Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, numPolys);
checkGlError("glDrawArrays");
}
没有 GLES20.glLinkProgram(mProgram);
在 onDrawFrame的开始()
我得到不正确的结果(用不正确透明度):
Without GLES20.glLinkProgram(mProgram);
in the start of onDrawFrame()
I get incorrect result (with incorrect transparency): http://imgur.com/kESeO
当我加入 GLES20.glLinkProgram(mProgram);在
它呈现正确,但性能差, onDrawFrame开始
() glLinkProgram()
是耗时的功能。这里是正确的渲染截图:
When I add GLES20.glLinkProgram(mProgram);
in the start of onDrawFrame()
it renders correctly, but the performance is bad, glLinkProgram()
is time-consuming function. Here is screenshot of correct rendering: http://imgur.com/sw83z
请解释一下我做错了,显然我没有打电话给 glLinkProgram()
在每一帧重绘。
Please explain what am I doing wrong, apparently I don't have to call glLinkProgram()
on every frame redraw.
推荐答案
这不端行为的原因是不相关的 glLinkProgram()
。我已经修改了一些其他的GL初始化参数(不记得这在目前),现在它工作得很好。
The cause of this misbehavior was not related to glLinkProgram()
. I've modified some other GL init parameters (can't recall which at the moment) and now it works just fine.
这篇关于不工作的OpenGL ES着色器,调用glLinkProgram每一帧?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!