【发布时间】:2015-01-18 10:41:16
【问题描述】:
我正在开始简单的 2d gles 2.0 android 应用程序。 出于某种奇怪的原因,我总是在屏幕中心得到一个点,而不是传递给着色器的顶点坐标。 我显然做错了什么。想不通是什么。 附言我没有使用任何投影矩阵,因为我需要标准四边形进行绘图。尝试投影 - 没有帮助。
public class TestActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GLSurfaceView glv = new GLSurfaceView(this);
glv.setEGLContextClientVersion(2);
SimpleRenderer renderer = new SimpleRenderer(this);
glv.setRenderer(renderer);
glv.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
setContentView(glv);
}
}
public class SimpleRenderer implements GLSurfaceView.Renderer {
private final float[] squareVertices = {
-1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, 1.0f,
};
private FloatBuffer squareBuffer;
private final Context context;
private int text_program;
private int aPositionLocation2;
public SimpleRenderer(Context context) {
this.context = context;
squareBuffer = ByteBuffer.allocateDirect(squareVertices.length * 4).asFloatBuffer();
squareBuffer.put(squareVertices).position(0);
}
public void onDrawFrame(GL10 gl) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(text_program);
glEnableVertexAttribArray(aPositionLocation2);
glVertexAttribPointer(aPositionLocation2, 2, GL_FLOAT, false, 0, squareBuffer);
glDrawArrays(GL_POINTS, 0, 4);
glDisableVertexAttribArray(aPositionLocation2);
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
glViewport(0, 0, width, height);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
text_program = ShaderHelper.buildProgram(TextResourceReader.readTextFileFromResource(context, R.raw.texture_vertex_shader),
TextResourceReader.readTextFileFromResource(context, R.raw.texture_fragment_shader));
aPositionLocation2 = glGetAttribLocation(text_program, "a_Position");
glClearColor(0f, 0f, 0f, 0f);
}
}
public class ShaderHelper {
private static final String TAG = "ShaderHelper";
public static int compileVertexShader(String shaderCode) {
return compileShader(GL_VERTEX_SHADER, shaderCode);
}
public static int compileFragmentShader(String shaderCode) {
return compileShader(GL_FRAGMENT_SHADER, shaderCode);
}
private static int compileShader(int type, String shaderCode) {
final int shaderObjectId = glCreateShader(type);
if (shaderObjectId == 0) Log.w(TAG, "Shader not created!");
glShaderSource(shaderObjectId, shaderCode);
glCompileShader(shaderObjectId);
final int[] compileStatus = new int[1];
glGetShaderiv(shaderObjectId, GL_COMPILE_STATUS, compileStatus, 0);
Log.v(TAG, "Results of compiling source:" + "\n" + shaderCode + "\n:"
+ glGetShaderInfoLog(shaderObjectId));
if (compileStatus[0] == 0) {
// If it failed, delete the shader object.
glDeleteShader(shaderObjectId);
Log.w(TAG, "Compilation of shader failed.");
return 0;
}
return shaderObjectId;
}
public static int linkProgram(int vertexShaderId, int fragmentShaderId) {
final int programObjectId = glCreateProgram();
if (programObjectId == 0) {
Log.w(TAG, "Could not create new program");
return 0;
}
glAttachShader(programObjectId, vertexShaderId);
glAttachShader(programObjectId, fragmentShaderId);
glLinkProgram(programObjectId);
final int[] linkStatus = new int[1];
glGetProgramiv(programObjectId, GL_LINK_STATUS, linkStatus, 0);
Log.v(TAG, "Results of linking program:\n"
+ glGetProgramInfoLog(programObjectId));
if (linkStatus[0] == 0) {
// If it failed, delete the program object.
glDeleteProgram(programObjectId);
Log.w(TAG, "Linking of program failed.");
return 0;
}
return programObjectId;
}
public static boolean validateProgram(int programObjectId) {
glValidateProgram(programObjectId);
final int[] validateStatus = new int[1];
glGetProgramiv(programObjectId, GL_VALIDATE_STATUS, validateStatus, 0);
Log.v(TAG, "Results of validating program: " + validateStatus[0]
+ "\nLog:" + glGetProgramInfoLog(programObjectId));
return validateStatus[0] != 0;
}
public static int buildProgram(String vertexShaderSource,
String fragmentShaderSource) {
int program;
// Compile the shaders.
int vertexShader = compileVertexShader(vertexShaderSource);
int fragmentShader = compileFragmentShader(fragmentShaderSource);
// Link them into a shader program.
program = linkProgram(vertexShader, fragmentShader);
validateProgram(program);
return program;
}
}
顶点着色器:
attribute vec4 a_Position;
void main()
{
gl_Position = a_Position;
gl_PointSize = 10.0;
}
片段着色器:
void main()
{
gl_FragColor = vec4(1.0,1.0,1.0,1.0);
}
【问题讨论】:
-
也许有人知道可靠的调试工具来查看着色器中的顶点数据。任何帮助都会很棒。在这个愚蠢的问题上已经花了 2 天时间!
-
是否至少调用了一次 onSurfaceChanged()?宽度和高度的值是多少?
-
是的,在onSurfaceCreated()之后调用,width=720 height=1022。
-
你尝试过其他顶点位置吗? -1.0 和 1.0 将位于屏幕边缘并且可能会被剪裁(尽管这并不能解释中心点)。那么 -0.5 和 0.5 呢?
-
也许尝试在每个 gl 调用之后添加对 glGetError 的调用,以查看是否有问题。 glVertexAttribPointer 没有在正确的位置发送值,或者 squareBuffer 以某种方式包含零。
标签: android opengl-es glsl opengl-es-2.0 vertex-shader