我正在尝试在我的应用中加载纹理(480x720px)作为背景,但它显示为黑色。我有点像GLES20的菜鸟所以我在互联网上跟随了一些例子来构建我的代码,但它没有给我带来好运。如何解决?
这是我的着色器代码:
public class Shaders {
private int mProgram;
private int maPositionHandle;
private int texCoords;
FloatBuffer texBuffer;
int iBaseMap;
private final String vertexShaderCode =
"attribute vec4 a_position;" +
"attribute vec2 a_texCoords;" +
"varying vec2 v_texCoords;" +
"void main()" +
"{" +
"gl_Position = a_position;" +
"v_texCoords = a_texCoords;" +
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"varying vec2 v_texCoords;" +
"uniform sampler2D u_baseMap;" +
"void main()" +
"{" +
"gl_FragColor = texture2D(u_baseMap, v_texCoords);" +
"}";
private int loadShader(int type, String shaderCode){
// create a vertex shader type (GLES20.GL_VERTEX_SHADER)
// or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
int shader = GLES20.glCreateShader(type);
// add the source code to the shader and compile it
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
public void initShaders() {
GLES20.glEnable(GLES20.GL_TEXTURE_2D);
GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
mProgram = GLES20.glCreateProgram(); // create empty OpenGL Program
GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program
GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
GLES20.glLinkProgram(mProgram); // creates OpenGL program executables
// get handle to the vertex shader's vPosition member
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "a_position");
iBaseMap = GLES20.glGetUniformLocation(mProgram, "u_baseMap");
texCoords = GLES20.glGetAttribLocation(mProgram, "a_texCoords");
GLES20.glDeleteShader(vertexShader);
GLES20.glDeleteShader(fragmentShader);
GLES20.glViewport(0, 0, Settings.width, Settings.height);
}
public int getMPH() {
return maPositionHandle;
}
public int getMProg() {
return mProgram;
}
public int getIBaseMap() {
return iBaseMap;
}
public int getTexCoords() {
return texCoords;
}
public int loadTexture(GLSurfaceView view, int imgResID){
Bitmap img = null;
int textures[] = new int[1];
img = BitmapFactory.decodeResource(view.getResources(), imgResID);
System.out.println(imgResID);
GLES20.glGenTextures(1, textures, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, img, 0);
img.recycle();
return textures[0];
}
}
和我绘制背景的类:
public class Background {
Shaders shaders;
int texId;
private GLSurfaceView mGLView;
private float BackgroundCoords[] = {
// X, Y, Z
-1f, -1f, 0, 0,0,
-1f, 1f, 0, 0, 1,
1f, 1f, 0, 1, 0,
1f, -1f, 0, 1, 1
};
private FloatBuffer backBuffer;
public void setAct(Shaders s, GLSurfaceView v) {
shaders = s;
mGLView = v;
texId = shaders.loadTexture(mGLView, R.raw.ground_tex);
System.out.println(texId);
}
public Background() {
// a float has 4 bytes so we allocate for each coordinate 4 bytes
ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(BackgroundCoords.length * 4);
vertexByteBuffer.order(ByteOrder.nativeOrder());
// allocates the memory from the byte buffer
backBuffer = vertexByteBuffer.asFloatBuffer();
// fill the vertexBuffer with the vertices
backBuffer.put(BackgroundCoords);
// set the cursor position to the beginning of the buffer
backBuffer.position(0);
}
/** The draw method for the square with the GL context */
public void draw() {
// Add program to OpenGL environment
GLES20.glUseProgram(shaders.getMProg());
// Point to our vertex buffer
backBuffer.position(0);
GLES20.glVertexAttribPointer(shaders.getMPH(), 3, GLES20.GL_FLOAT, false, 5 * 4, backBuffer);
GLES20.glEnableVertexAttribArray(shaders.getMPH());
backBuffer.position(3);
GLES20.glVertexAttribPointer(shaders.getTexCoords(), 2, GLES20.GL_FLOAT, false, 5 * 4, backBuffer);
GLES20.glEnableVertexAttribArray(shaders.getTexCoords());
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
GLES20.glUniform1i(shaders.getIBaseMap(), 0);
// Draw the vertices as triangle strip
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 4);
}
}
如果我只使用一个简单的着色器尝试此代码,但填充背景的两个三角形中只有一个会变色。
有一个错误“E / libEGL(8971):调用OpenGL ES API没有当前上下文(每个线程记录一次)”来自每次调用GLES时的loadTexture函数“=。
我真的希望有人可以帮助我。
答案 0 :(得分:0)
"color = texture2D(u_baseMap, gl_PointCoord);"
你为什么决定在这里使用gl_PointCoord?您正在绘制三角形,并根据documentation:
如果当前基元不是一个点,则读取值 来自gl_PointCoord的未定义。
如果你想使用gl_PointCoord,那么绘制GL_POINTS,而不是GL_TRIANGLES。否则生成并发送纹理坐标。