Opengl ES 1.1/Android——2011 年纹理映射到正方形的惨败

发布于 2024-11-07 09:51:23 字数 3362 浏览 0 评论 0原文

我正在尝试将纹理映射到正方形上,其中纹理拉伸以适合正方形。目前是纹理贴图,但它没有映射到正确的位置,并且 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:

enter image description here
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 perspective
gl.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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

避讳 2024-11-14 09:51:23

您使用 GL_TEXTURE_COORD_ARRAY 作为缓冲区绑定点。那是错误的。 glTexCoordPointer 从当前 GL_ARRAY_BUFFER 获取数据,就像 glVertexPointer 一样。因此,在第一部分中替换

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);

gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, textureCoordPointer);
gl11.glBufferData(GL11.GL_ARRAY_BUFFER, textureBuffer.capacity() 
   * 4, textureBuffer, GL11.GL_STATIC_DRAW);
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0);

并在渲染代码中替换

gl11.glBindBuffer(GL11.GL_TEXTURE_COORD_ARRAY, textureCoordPointer);

gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, textureCoordPointer);

这是有效的,因为 gl...Pointer 命令从绑定到 GL_ARRAY_BUFFER 的缓冲区中获取数据当他们被召唤的那一刻。所以只要选择合适的缓冲区,然后调用gl...Pointer,然后就可以将另一个缓冲区绑定到GL_ARRAY_BUFFER(但是索引缓冲区需要绑定到当然,在调用 glDrawElements 时使用 GL_ELMENT_ARRAY_BUFFER 但正如 Tommy 在评论中提到的那样,您也可以不使用简单的索引缓冲区而使用 glDrawArrays)。

因此,当调用 glBindBuffer(GL_TEXTURE_COORD_ARRAY, ...) 失败时(因为 GL_TEXTURE_COORD_ARRAY 不是有效的绑定点),在设置 texcoord 时,顶点缓冲区仍然绑定指针。但是,由于您指定顶点具有 3 个分量和 texcoords 2,因此您实际上得到 { 1f, 1f, 0f, 1f, -1f, 0f, -1f, 1f } 作为纹理坐标(第一个顶点数组的八个值)。因此,当您渲染数组时,

2   0

3   1

您会得到纹理坐标:

-1,0   1,1

-1,1   0,1

在进行建议的更改后,您将得到

1,0   0,0

1,1   0,1

所以您的纹理仍然水平和垂直翻转(我不知道这是否是有意的)。您必须确保您的纹理坐标与您的顶点相匹配。但是在更改了上述缓冲区错误之后,它至少应该看起来好一点。

You use GL_TEXTURE_COORD_ARRAY as buffer binding point. That is just wrong. The glTexCoordPointer sources its data from the current GL_ARRAY_BUFFER, like the glVertexPointer. So in your first part substitute

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);

by

gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, textureCoordPointer);
gl11.glBufferData(GL11.GL_ARRAY_BUFFER, textureBuffer.capacity() 
   * 4, textureBuffer, GL11.GL_STATIC_DRAW);
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0);

and in the rendering code substitute

gl11.glBindBuffer(GL11.GL_TEXTURE_COORD_ARRAY, textureCoordPointer);

by

gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, textureCoordPointer);

This works because the gl...Pointer commands take their data from the buffer that is bound to GL_ARRAY_BUFFER at the moment they are called. So just select the appropriate buffer, then call gl...Pointer and then you can bind another buffer to GL_ARRAY_BUFFER (but the index buffer needs to be bound to GL_ELEMENT_ARRAY_BUFFER when calling glDrawElements, of course. But as Tommy already mentioned in a comment, you could also just go without the trivial index buffer and with glDrawArrays).

So, as the call to glBindBuffer(GL_TEXTURE_COORD_ARRAY, ...) fails (as GL_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 as

2   0

3   1

you get as texture coords:

-1,0   1,1

-1,1   0,1

After making the proposed changes you will get

1,0   0,0

1,1   0,1

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文