[英]Android OpenGL ES 2.0
我試圖在 Android OpenGL ES 2.0 示例中顯示一個簡單的三角形。 但是什么都沒有出現,我只是不明白為什么:),我沒有收到任何錯誤或任何東西,只是藍屏(那是我的清晰顏色)。 也許將我的 model 放在外面的投影矩陣有問題?
package dk.madslee.modelviewer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ConfigurationInfo;
import android.content.res.Resources;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;
import android.os.Bundle;
import android.util.Log;
// http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/GLES20TriangleRenderer.html
public class MainActivity extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
final Resources resources = getResources();
GLSurfaceView surfaceView = new GLSurfaceView(this);
surfaceView.setEGLContextClientVersion(2); // enable OpenGL 2.0
Log.e("opengl", Boolean.toString(detectOpenGLES20()));
surfaceView.setRenderer(new GLSurfaceView.Renderer()
{
public static final int FLOAT_BYTE_LENGTH = 4;
private int mProgram;
private int mVertexPositionAttributeLocation;
private int mMVMatrixUniformLocation;
private int mPMatrixUniformLocation;
private float[] mMVMatrix = new float[16];
private float[] mPMatrix = new float[16];
private float[] mVertices = {
1.0f, 1.0f, 0.0f,
-1.0f, 1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
};
private FloatBuffer mVertexBuffer;
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
mVertexBuffer = ByteBuffer.allocateDirect(mVertices.length * FLOAT_BYTE_LENGTH).order(ByteOrder.nativeOrder()).asFloatBuffer();
mVertexBuffer.put(mVertices);
mVertexBuffer.position(0);
mProgram = createProgram();
mVertexPositionAttributeLocation = GLES20.glGetAttribLocation(mProgram, "aVertexPosition");
mMVMatrixUniformLocation = GLES20.glGetUniformLocation(mProgram, "uMVMatrix");
mPMatrixUniformLocation = GLES20.glGetUniformLocation(mProgram, "mPMatrix");
checkGlError("glGetUniformLocation");
Matrix.setLookAtM(mMVMatrix, 0, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height)
{
GLES20.glViewport(0, 0, width, height);
Matrix.frustumM(mPMatrix, 0, -1, 1, -1, 1, 3, 7); // [UPDATED but didnt solve the problem]
}
@Override
public void onDrawFrame(GL10 gl)
{
GLES20.glClearColor(0, 0, 1.0f, 1.0f);
GLES20.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
GLES20.glUseProgram(mProgram);
checkGlError("glUseProgram");
mVertexBuffer.position(0);
GLES20.glVertexAttribPointer(mVertexPositionAttributeLocation, 3, GLES20.GL_FLOAT, false, 3 * FLOAT_BYTE_LENGTH, mVertexBuffer);
checkGlError("glVertexAttribPointer");
GLES20.glEnableVertexAttribArray(mVertexPositionAttributeLocation);
checkGlError("glEnableVertexAttribArray");
GLES20.glUniformMatrix4fv(mMVMatrixUniformLocation, 1, false, mMVMatrix, 0);
GLES20.glUniformMatrix4fv(mPMatrixUniformLocation, 1, false, mPMatrix, 0);
checkGlError("glUniform4fv");
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
checkGlError("glDrawArrays");
}
private int createProgram()
{
int program = GLES20.glCreateProgram();
int vertexShader = getShader(GLES20.GL_VERTEX_SHADER, R.string.vertex_shader);
int fragmentShader = getShader(GLES20.GL_FRAGMENT_SHADER, R.string.fragment_shader);
GLES20.glAttachShader(program, vertexShader);
GLES20.glAttachShader(program, fragmentShader);
GLES20.glLinkProgram(program);
GLES20.glUseProgram(program);
return program;
}
private int getShader(int type, int source)
{
int shader = GLES20.glCreateShader(type);
String shaderSource = resources.getString(source);
GLES20.glShaderSource(shader, shaderSource);
GLES20.glCompileShader(shader);
int[] compiled = new int[1];
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
if (compiled[0] == 0)
{
Log.e("opengl", "Could not compile shader");
Log.e("opengl", GLES20.glGetShaderInfoLog(shader));
Log.e("opengl", shaderSource);
}
return shader;
}
private void checkGlError(String op) {
int error;
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
Log.e("opengl", op + ": glError " + error);
throw new RuntimeException(op + ": glError " + error);
}
}
});
setContentView(surfaceView);
}
private boolean detectOpenGLES20() {
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
ConfigurationInfo info = am.getDeviceConfigurationInfo();
return (info.reqGlEsVersion >= 0x20000);
}
}
我的着色器看起來像這樣
頂點
attribute vec3 aVertexPosition;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
void main() {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
}
分段
precision highp float;
void main() {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
確保禁用背面剔除(通過glDisable(GL_CULL_FACE)
),因為此時您正在查看幾何體的背面,或者嘗試在查看時使用 5 而不是 -5。 它實際上應該默認禁用,但我不確定。
否則它可能是你的投影矩陣。 請記住,平截頭體的參數是通用(3d 世界)單位,不一定以像素為單位,因此如果您不希望世界單位表示像素,則不應采用與glViewport
相同的值。 所以目前你的圖像平面是 (2*width)x(2*height) 並且你的三角形只占用一個像素(實際上甚至更少,由於透視失真)。 嘗試類似Matrix.frustumM(mPMatrix, 0, -1, 1, -1, 1, 3, 7)
或使用與gluPerspective
等效的方法,您可以在其中輸入所需的視角和窗口的縱橫比,這很比直接截錐體參數更自然。
編輯:剛剛發現問題。 在glGetUniformLocation
中,您編寫了mPMatrix
而不是uPMatrix
,因此您從未獲得投影矩陣的有效統一位置。 奇怪的是 GL 沒有在這上面拋出錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.