Opengl ES 1.1/Android——2011 年纹理映射到正方形的惨败
我正在尝试将纹理映射到正方形上,其中纹理拉伸以适合正方形。目前是纹理贴图,但它没有映射到正确的位置,并且 OGL 执行了一些我不知道的倾斜或类似操作。图像是 64x64,我尝试过的方块是从 -2 到 2(hor 和 ver)和 -1 到 1。 这是图像:
纹理代码是:
float texture[] = { 0,0,0,1, 1,0,1,1 };
ByteBuffer byteBuf = ByteBuffer.allocateDirect(texture.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
FloatBuffer textureBuffer = byteBuf.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.flip();
int[] buffer = new int[1];
gl11.glGenBuffers(1, buffer, 0);
textureCoordPointer = buffer[0];
gl11.glBindBuffer(GL11.GL_TEXTURE_COORD_ARRAY, textureCoordPointer);
gl11.glBufferData(GL11.GL_TEXTURE_COORD_ARRAY, textureBuffer.capacity()
* 4, textureBuffer, GL11.GL_STATIC_DRAW);
gl11.glBindBuffer(GL11.GL_TEXTURE_COORD_ARRAY, 0);
Bitmap bitmap = BitmapFactory.decodeResource(context
.getResources(),R.drawable.afd);
int textures[] = new int[1];
gl.glGenTextures(1, textures, 0);
texturePointer = textures[0];
gl.glBindTexture(GL10.GL_TEXTURE_2D, texturePointer);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
渲染代码是:
gl11.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, vertexPointerSquare);
gl11.glVertexPointer(3, GL10.GL_FLOAT, 0, 0);
gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, indexPointerSquare);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texturePointer);
gl11.glBindBuffer(GL11.GL_TEXTURE_COORD_ARRAY, textureCoordPointer);
gl11.glTexCoordPointer(2, GL10.GL_FLOAT, 0, 0);
gl11.glPushMatrix();
gl11.glScalef(.4f,.4f,0);
gl11.glColor4f(1,1,1,1);
gl11.glDrawElements(GL11.GL_TRIANGLE_STRIP, indicesSquare,
GL11.GL_UNSIGNED_SHORT, 0);
gl11.glPopMatrix();
gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);
正方形:
GL11 gl11 = (GL11) gl;
FloatBuffer vertexSquareBuffer = ByteBuffer.allocateDirect(verticesSquare * 3 * 4)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
ShortBuffer indexSquareBuffer = ByteBuffer.allocateDirect(indicesSquare * 2)
.order(ByteOrder.nativeOrder()).asShortBuffer();
float vertices[] = { 1f, 1f, 0, 1f, -1f, 0, -1f, 1f, 0, -1f, -1f, 0 };
short indices[] = { 0, 1, 2, 3 };
vertexSquareBuffer.put(vertices);
indexSquareBuffer.put(indices);
indexSquareBuffer.flip();
vertexSquareBuffer.flip();
int[] bufferSquare = new int[1];
gl11.glGenBuffers(1, bufferSquare, 0);
vertexPointerSquare = bufferSquare[0];
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, vertexPointerSquare);
gl11.glBufferData(GL11.GL_ARRAY_BUFFER, vertexSquareBuffer.capacity() * 4,
vertexSquareBuffer, GL11.GL_STATIC_DRAW);
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0);
gl11.glGenBuffers(1, bufferSquare, 0);
indexPointerSquare = bufferSquare[0];
gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, indexPointerSquare);
gl11.glBufferData(GL11.GL_ELEMENT_ARRAY_BUFFER, indexSquareBuffer.capacity() * 2,
indexSquareBuffer, GL11.GL_STATIC_DRAW);
我正在使用正交透视 gl.glOrthof(-windowRatio, windowRatio, -1,1, -4, 4)
。我尝试过drawArrays(),这没有什么区别,并且还使用了glTexParameter
的许多组合。问题似乎有两个:(1)图像没有拉伸以适应,(2)只有正方形的左三角形正确渲染纹理。我注意到改变纹理坐标对图像没有影响。我怎样才能让它按预期工作?感谢您的关注。
I am trying to map a texture onto a square where the texture stretches to fit the square. Currently the texture maps, but it doesn't map to the correct location and OGL performs some skewing or such that is unbeknownst to me. The image is 64x64 and the squares I've tried are from -2 to 2 (hor and ver) and -1 to 1. Here is the image:
The texture code is:
float texture[] = { 0,0,0,1, 1,0,1,1 };
ByteBuffer byteBuf = ByteBuffer.allocateDirect(texture.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
FloatBuffer textureBuffer = byteBuf.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.flip();
int[] buffer = new int[1];
gl11.glGenBuffers(1, buffer, 0);
textureCoordPointer = buffer[0];
gl11.glBindBuffer(GL11.GL_TEXTURE_COORD_ARRAY, textureCoordPointer);
gl11.glBufferData(GL11.GL_TEXTURE_COORD_ARRAY, textureBuffer.capacity()
* 4, textureBuffer, GL11.GL_STATIC_DRAW);
gl11.glBindBuffer(GL11.GL_TEXTURE_COORD_ARRAY, 0);
Bitmap bitmap = BitmapFactory.decodeResource(context
.getResources(),R.drawable.afd);
int textures[] = new int[1];
gl.glGenTextures(1, textures, 0);
texturePointer = textures[0];
gl.glBindTexture(GL10.GL_TEXTURE_2D, texturePointer);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
and the code for the rendering is:
gl11.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, vertexPointerSquare);
gl11.glVertexPointer(3, GL10.GL_FLOAT, 0, 0);
gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, indexPointerSquare);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texturePointer);
gl11.glBindBuffer(GL11.GL_TEXTURE_COORD_ARRAY, textureCoordPointer);
gl11.glTexCoordPointer(2, GL10.GL_FLOAT, 0, 0);
gl11.glPushMatrix();
gl11.glScalef(.4f,.4f,0);
gl11.glColor4f(1,1,1,1);
gl11.glDrawElements(GL11.GL_TRIANGLE_STRIP, indicesSquare,
GL11.GL_UNSIGNED_SHORT, 0);
gl11.glPopMatrix();
gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);
And the square:
GL11 gl11 = (GL11) gl;
FloatBuffer vertexSquareBuffer = ByteBuffer.allocateDirect(verticesSquare * 3 * 4)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
ShortBuffer indexSquareBuffer = ByteBuffer.allocateDirect(indicesSquare * 2)
.order(ByteOrder.nativeOrder()).asShortBuffer();
float vertices[] = { 1f, 1f, 0, 1f, -1f, 0, -1f, 1f, 0, -1f, -1f, 0 };
short indices[] = { 0, 1, 2, 3 };
vertexSquareBuffer.put(vertices);
indexSquareBuffer.put(indices);
indexSquareBuffer.flip();
vertexSquareBuffer.flip();
int[] bufferSquare = new int[1];
gl11.glGenBuffers(1, bufferSquare, 0);
vertexPointerSquare = bufferSquare[0];
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, vertexPointerSquare);
gl11.glBufferData(GL11.GL_ARRAY_BUFFER, vertexSquareBuffer.capacity() * 4,
vertexSquareBuffer, GL11.GL_STATIC_DRAW);
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0);
gl11.glGenBuffers(1, bufferSquare, 0);
indexPointerSquare = bufferSquare[0];
gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, indexPointerSquare);
gl11.glBufferData(GL11.GL_ELEMENT_ARRAY_BUFFER, indexSquareBuffer.capacity() * 2,
indexSquareBuffer, GL11.GL_STATIC_DRAW);
I am using an ortho perspectivegl.glOrthof(-windowRatio, windowRatio, -1,1, -4, 4)
. I have tried drawArrays(), which makes no difference, and also using many combinations of glTexParameter
. The problem seems twofold: (1) the image doesn't stretch to fit, and (2) only the left triangle of the square correctly renders the texture. Something I've noticed is that changing the texture coordinates has no effect on the image. How do I get this to work as intended? Thanks for looking.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您使用 GL_TEXTURE_COORD_ARRAY 作为缓冲区绑定点。那是错误的。
glTexCoordPointer
从当前GL_ARRAY_BUFFER
获取数据,就像glVertexPointer
一样。因此,在第一部分中替换为
并在渲染代码中替换
为
这是有效的,因为
gl...Pointer
命令从绑定到GL_ARRAY_BUFFER
的缓冲区中获取数据当他们被召唤的那一刻。所以只要选择合适的缓冲区,然后调用gl...Pointer
,然后就可以将另一个缓冲区绑定到GL_ARRAY_BUFFER
(但是索引缓冲区需要绑定到当然,在调用
但正如 Tommy 在评论中提到的那样,您也可以不使用简单的索引缓冲区而使用glDrawElements
时使用 GL_ELMENT_ARRAY_BUFFERglDrawArrays
)。因此,当调用
glBindBuffer(GL_TEXTURE_COORD_ARRAY, ...)
失败时(因为GL_TEXTURE_COORD_ARRAY
不是有效的绑定点),在设置 texcoord 时,顶点缓冲区仍然绑定指针。但是,由于您指定顶点具有 3 个分量和 texcoords 2,因此您实际上得到{ 1f, 1f, 0f, 1f, -1f, 0f, -1f, 1f }
作为纹理坐标(第一个顶点数组的八个值)。因此,当您渲染数组时,您会得到纹理坐标:
在进行建议的更改后,您将得到
所以您的纹理仍然水平和垂直翻转(我不知道这是否是有意的)。您必须确保您的纹理坐标与您的顶点相匹配。但是在更改了上述缓冲区错误之后,它至少应该看起来好一点。
You use
GL_TEXTURE_COORD_ARRAY
as buffer binding point. That is just wrong. TheglTexCoordPointer
sources its data from the currentGL_ARRAY_BUFFER
, like theglVertexPointer
. So in your first part substituteby
and in the rendering code substitute
by
This works because the
gl...Pointer
commands take their data from the buffer that is bound toGL_ARRAY_BUFFER
at the moment they are called. So just select the appropriate buffer, then callgl...Pointer
and then you can bind another buffer toGL_ARRAY_BUFFER
(but the index buffer needs to be bound toGL_ELEMENT_ARRAY_BUFFER
when callingglDrawElements
, of course. But as Tommy already mentioned in a comment, you could also just go without the trivial index buffer and withglDrawArrays
).So, as the call to
glBindBuffer(GL_TEXTURE_COORD_ARRAY, ...)
fails (asGL_TEXTURE_COORD_ARRAY
is no valid binding point), you have the vertex buffer still bound when setting the texcoord pointer. But since you specify your vertices to have 3 components and your texcoords 2, you actually get{ 1f, 1f, 0f, 1f, -1f, 0f, -1f, 1f }
as texture coordinates (the first eight values of your vertex array). So as you render your array asyou get as texture coords:
After making the proposed changes you will get
So your texture is still flipped horizontally and vertically (I don't know if that's intended). You have to make sure that your textrue coordinates match your vertices. But after changing your above mentioned buffer error, it should at least look a bit nicer.