从&QUOT映射贴图,1D"到" 2D"用OpenGL矩阵变换 [英] Mapping a texture from "1D" to "2D" with OpenGL matrix transformations

查看:142
本文介绍了从&QUOT映射贴图,1D"到" 2D"用OpenGL矩阵变换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(带着这个问题,我想调查的想法我有解决的这另一个

如果我有尺寸的标准二维数组的宽度的记忆,我可以把它转换成长的一维数组的宽度的* 的,然后通过的指数指数为 = X + 的*的宽度的。分配和释放内存的阵列作为存储管理器并不需要担心包装结构的2D,但只需要担心的每一个分配阵列的总长度,如果EX pressed在1D时,这个映射是非常有用的。

If I have a standard 2D array of dimensions width and height in memory, I can turn that into a 1D array of length width * height and then index it via index = x + y * width. This mapping is extremely helpful when allocating and freeing memory for the array as the memory manager does not need to worry about packing the structures in 2D but only needs to worry about the overall length of every allocated array if expressed in 1D.

我想看看我是否可以使用图像内存管理同样的方法对OpenGL纹理。这个想法(如上面的链接问题描述)是通过的装箱他们(即绘制它们彼此相邻),进入大的纹理。这有助于在渲染过程中最大限度地减少昂贵的纹理绑定操作。

I am trying to see if I can use this same approach for image-memory management for OpenGL textures. The idea (as described in the above linked question) is to combine a whole bunch of needed textures into a single bigger one by bin-packing them (i.e. drawing them next to each other) into the big texture. This helps minimize costly texture-binding operations during rendering.

比方说,我的大纹理8倍; 8个像素(即64像素总数):

Let's say my big texture is 8×8 pixels (i.e. 64 pixels total):

8x8 texture:                5x5 image:            4x5 image:

   | 0 1 2 3 4 5 6 7           | 0 1 2 3 4           | 0 1 2 3
---+-----------------       ---+-----------       ---+---------
 0 | . . . . . . . .         0 | A B C D E         0 | a b c d
 1 | . . . . . . . .         1 | F G H I J         1 | e f g h
 2 | . . . . . . . .         2 | K L M N O         2 | i j k l
 3 | . . . . . . . .         3 | P Q R S T         3 | m n o p
 4 | . . . . . . . .         4 | U V W X Y         4 | q r s t
 5 | . . . . . . . .
 6 | . . . . . . . .
 7 | . . . . . . . .

和我想存储5次; 5图像和4倍; 5图像中它(即25 + 20 = 45个像素总数)。从技术上讲,我有足够的可用像素,但我不能把这些图像彼此相邻进入大纹理,将需要9的最小尺寸在另一个方向,5。

And I would like to store a 5×5 image and a 4×5 image in it (i.e. 25 + 20 = 45 pixels total). Technically, I have plenty of pixels available, but I can't place these images next to each other into the big texture as that would require a minimum dimension of 9 in one direction and 5 in the other.

如果我可以简单地把我的8倍,8个纹理64延续了记忆像素并映射两个图像到内存里面的一维块,我可以安排的图像,如下所示纹理内:     8x8的质地:

If I could simply treat my 8×8 texture as 64 continues pixels of memory and map the two images into 1D blocks of memory inside that, I could arrange the images as follows inside the texture: 8x8 texture:

   | 0 1 2 3 4 5 6 7
---+-----------------
 0 | A B C D E F G H
 1 | I J K L M N O P             
 2 | Q R S T U V W X
 3 | Y a b c d e f g             
 4 | h i j k l m n o             
 5 | p q r s t . . .
 6 | . . . . . . . .
 7 | . . . . . . . .

如果我画我的所有图片的比例为1:1,即在任何地方没有小数像素坐标和不需要任何线性过滤或其他像素混合,才有可能拿出我可以用它来转换矩阵绘制4倍;使用这种纹理5图像

If I draw all my images at a scale of 1:1, i.e. no fractional pixel coordinates anywhere and no need for any linear filtering or other pixel blending, is it possible to come up with a transformation matrix that I can use to draw the 4×5 image using this texture?

使用顶点和片段着色器,这看起来像它可能是相当容易的(除非我忘了什么东西,我没有尝试这样做):

With vertex and fragment shaders, this looks like it might be fairly easy (unless I'm forgetting something; I haven't tried this):

  • 顶点着色器映射的四角的图像绘制到pssed作为64&倍纹理前$ P $ 1图像:

  • The vertex shader maps the four corners of the image to draw to the texture expressed as a 64×1 image:

  • A :(0,0)RARR; (0 + 0 * 4 + 25,0)=(25,0)    其中25是在4倍的偏移量; 5图像
  • D :(3,0)RARR; (3 + 0×4 + 25,0)=(28,0)
  • :(0,4)RARR; (0 + 4 * 4 + 25,0)=(41,0)
  • T :(3,4)RARR; (3 + 4 * 4 + 25,0)=(44,0)
  • a: (0, 0) → (0 + 0*4 + 25, 0) = (25, 0)     where 25 is the offset of the 4×5 image
  • d: (3, 0) → (3 + 0*4 + 25, 0) = (28, 0)
  • q: (0, 4) → (0 + 4*4 + 25, 0) = (41, 0)
  • t: (3, 4) → (3 + 4*4 + 25, 0) = (44, 0)

其他坐标的纹理内的内插的应该的(?),那么也映射到右沿着这条线的整数坐标偏移

The interpolation of other coordinates inside the texture should (?) then also map to the right offset along this line for integer coordinates

  • A :(0,25)RARR; (25%8,25/8)=(1,3)
  • D :(0,28)RARR; (28%8,28/8)=(4,3)
  • K :(0,35)RARR; (35%8,35/8)=(3,4)
  • :(0,41)RARR; (41%8,41/8)=(1,5)
  • T :(0,44)RARR; (44%8,44/8)=(4,5)
  • a: (0, 25) → (25 % 8, 25 / 8) = (1, 3)
  • d: (0, 28) → (28 % 8, 28 / 8) = (4, 3)
  • k: (0, 35) → (35 % 8, 35 / 8) = (3, 4)
  • q: (0, 41) → (41 % 8, 41 / 8) = (1, 5)
  • t: (0, 44) → (44 % 8, 44 / 8) = (4, 5)

不幸的是自定义的着色器需要的OpenGL ES 2.0或更高,这​​是不是适用于所有设备。

Unfortunately custom shaders require OpenGL ES v2.0 or better, which is not available on all devices.

是它在某种程度上可能只是通过通过的OpenGL ES 1.1?

Is it somehow possible to achieve this mapping just via the matrix transformations offered by OpenGL ES 1.1?

推荐答案

我还没有试过这个,但我想那里扔出去的想法早已:

I haven't tried this yet, but I wanted to throw it out there as an idea already:

更新:我尝试过了,现在,它精美的作品有一个微小的变化(见注释)

UPDATE: I tried it now and it works beautifully with one minor change (see comment)!

比方说,我的大纹理的宽度尺寸,我想绘制图像的宽度宽度,并开始在偏移偏移里面的大纹理,其中偏移是的偏移量,即1-D再presentation X + * 尺寸

Let's say my big texture has width size and the image I want to draw has width width and starts at offset offset inside the big texture, where offset is the 1-D representation of the offset, i.e. x + y * size.

于是,以下4x4矩阵几乎达到这个映射:

Then, the following 4x4 matrix will almost achieve this mapping:

     _                                           _
    |      1        width        offset      0    |
    |                                             |
    |   1/size   width/size   offset/size    0    |
M = |                                             |
    |      0          0            0         0    |
    |                                             |
    |_     0          0            0         1   _|

因此​​,在上面的例子中,以绘制4倍; 5图像,所述基质将是

So, in the example above, to draw the 4×5 image, the matrix would be

 _                    _
|   1    4    25    0  |
|  1/8  1/2  25/8   0  |
|   0    0     0    0  |
|_  0    0     0    1 _|

图片坐标将则需要与含有4-向量指定的

The image coordinates will then need to be specified with a 4-vector containing

( x, y, 1, 1 )

因此​​, K 的例如坐标(即(2,2))将映射到:

So, for example the coordinates of k (i.e. (2,2)) will map to:

M*( 2, 2, 1, 1 ) => ( 35, 4.375, 0, 1 )

这将是除preTED为纹理坐标(35,4.375)。

which will be interpreted as texture coordinate (35, 4.375).

如果我们现在打开最近邻作为内插规则,并启用纹理包裹在x方向,这应该对应于:

If we now turn on nearest neighbor as the interpolation rule and enable texture wrapping in the x-direction, this should correspond to:

( 3, 4 )

(我使用整数坐标此处,而在最后的实施方式中,最终的坐标将需要在范围从0到1,这可能是可以实现的浮体很容易通过更换 1 在基体与右下角尺寸,因为这最终会在输出载体的第四位,从而划分其他三个。这正如@ chbaker0指出的那样,只会工作,但是,如果纹理坐标都受到了通常的角度划分,如果他们都没有,整个矩阵 M 需要通过尺寸,而不是达到了预期的结果进行分配。)

(I was using integer coordinates here, whereas in the final implementation, the final coordinates would need to be floats in the range from 0 to 1. This might be achievable very easily by replacing the 1 in the bottom right corner of the matrix with size, since that will end up in the fourth position of the output vector and thus divide the other three. This, as @chbaker0 pointed out, would only work, though, if the texture coordinates are subject to the usual perspective division. If they are not, the entire matrix M needs to be divided by size instead to achieve the desired result.)

这听起来是不是合理的,或者可以有人看到这个问题之前,我继续前进,努力实现这一点? (可能要花费几天时间,因为我必须首先做一对夫妇的其他事情得到一个可测试的应用程序...)

Does this sound reasonable at all or can someone see a problem with this before I go ahead and try to implement this? (Might take me a few days, since I have to do a couple other things first to get to a testable app...)

这篇关于从&QUOT映射贴图,1D"到" 2D"用OpenGL矩阵变换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆