1

我正在为 Android 开发一个 OpenGL ES 1.1 应用程序(OpenGL 调用是由通过 NDK 调用的 C 代码进行的)。

我的问题是我正在尝试使用 Q 纹理坐标以及通常的 (S, T) 纹理坐标。但是,我放入 Q 中的任何内容都没有任何明显的效果。

(除此之外:想要使用 Q 坐标的原因是我想将矩形纹理映射到空间中具有正确透视效果(即非仿射)的梯形四边形——如http://www.xyzw 所述。我们/~cass/qcoord/)。

我尝试设置 Q 坐标(默认 1.0f 以外的其他值)的方法是通常的:我提供 4 个纹理坐标而不是通常的 2。我尝试将各种值放在 Q 坐标中(甚至进入通常未使用的 R 坐标,以防两者混淆)对我的纹理的明显影响为零。我希望看到 Q != 1.0 对我的纹理产生的影响——例如,每个纹理坐标的 Q = 0.5 应该只是每个派生 (S, T) 值的两倍——实际上,将表观纹理大小减半。但没有变化。

我不能真正发布完整的代码,但这里是基础:

我的顶点结构定义如下:

typedef struct
{
    GLfloat x, y, z;        // 3 x spacial coord - 12 bytes
    GLfloat tx, ty, tr, tq; // 4 x texture coord - 16 bytes
    GLfloat padding[1];     // make it up to 32 bytes (or 8 floats, in effect)
} VertexData;

创建每个顶点缓冲区对象(VBO):

// alloc space for my vertex buffer
int vertexBufferSize = numVertices * sizeof(VertexData);
VertexData* vertexData = (VertexData *)malloc(vertexBufferSize);

..//for each vertex I'm creating:
    vertex.x =  (... appropriate coord)
    vertex.y =  (... appropriate coord)
    vertex.z =  (... appropriate coord)
    vertex.tx = (... appropriate coord) // AKA the 's' texture coord
    vertex.ty = (... appropriate coord) // AKA the 't' texture coord
    vertex.tr = 0.5f;   // 'R' texture coord. Usually ignored, but I set in case of mixup between Q and R
    vertex.tq = 0.5f;   // 'Q' texture coord

以下是我给出顶点和文本坐标指针的方式:

glVertexPointer(3, GL_FLOAT, stride, (GLvoid*)((char*)NULL));

// note the 4 below - we want to give 4 tex coordinates, not 2.
// 3*4 corresponds to the offset of texture coords in the VertexData struct
glTexCoordPointer(4, GL_FLOAT, 32 /*stride*/,  (GLvoid*)((char*)NULL + 3*4));

这一切都很好,除了我说的,我的 Q 坐标没有任何区别。如果将我的glTextCoordPointer调用更改为仅提供 2 或 3 个坐标,则程序行为没有变化:

glTexCoordPointer(2, GL_FLOAT, 32 /*stride*/,  (GLvoid*)((char*)NULL + 3*4));
// OR:
glTexCoordPointer(3, GL_FLOAT, 32 /*stride*/,  (GLvoid*)((char*)NULL + 3*4));

我的问题是:为什么我的 Q 纹理坐标没有任何效果?如果它是特定于设备或 Android API 级别的,我能否找出它适用于哪些设备或 API 级别?如果我不能依靠 Q 坐标做任何有用的事情,我还能如何实现相同的效果(逼真的、非仿射纹理映射到梯形)?

我正在实际的 Android 设备上测试我的代码:HTC Wildfire S。

为了方便起见,我正在使用SOIL 库加载我的纹理。

更新

我已经为第 6 课下载了 NeHe Android 端口。这使用 Java OpenGL ES 接口(无 NDK)。我在其中添加了随机的 R 和 Q 纹理坐标,同样,没有明显的效果。

更新 2

我放弃了尝试让 Q 纹理坐标产生任何效果;我认为并非所有设备都支持它。仍然对这方面的权威信息感兴趣。

相关链接:

http://www.xyzw.us/~cass/qcoord/

http://www.gamedev.net/topic/419296-skewedsheared-texture-mapping-in-opengl

http://hacksoflife.blogspot.com/2009/11/perspective-correct-texturing-q.html

3D纹理坐标的透视校正

http://sfml-dev.org/forum/viewtopic.php?t=2893

http://fly.cc.fer.hr/~unreal/theredbook/chapter09.html

4

2 回答 2

1

我同意你的看法。某些 android 设备不支持 OpenGL ES 1.1 中的纹理 q 坐标。

根据我的经验,Galaxy S、S2、S3 有效。Galaxy Note,Galaxy S2 HD 没有。(可能是GPU问题??)

但是 OpenGL ES 2.0 中的纹理 q coord 在那些有问题的设备上工作。

下面是我的着色器代码。

private final String mVertexShader =
    "uniform mat4 uMVPMatrix;\n" +
        "attribute vec4 aPosition;\n" +
        "attribute vec4 aTextureCoord;\n" +
        "varying vec4 vTextureCoord;\n" +
        "void main() {\n" +
        "  gl_Position = uMVPMatrix * aPosition;\n" +
        "  vTextureCoord = aTextureCoord;\n" +
        "}\n";

private final String mFragmentShader =
    "precision mediump float;\n" +
        "varying vec4 vTextureCoord;\n" +
        "uniform sampler2D sTexture;\n" +
        "void main() {\n" +
        "  gl_FragColor = texture2DProj(sTexture, vTextureCoord);\n" +
        "}\n";

所以我决定在支持 2.0 的设备上使用 OpenGL 2.0,在其他设备上使用 1.0。

我发布了应用程序,完成了大约 200 万次下载,还没有听到任何与渲染问题相关的投诉。

希望这有帮助。

于 2012-08-20T15:32:53.047 回答
0

这不是您问题的确切答案,但您可能需要检查几件事:

  • 您的纹理是否具有高度和宽度的二次幂?
  • R 坐标应始终为 0.f,因为它用于 3d 纹理。
  • 为什么不在 glTexCoordPointer 和 glVertexPointer 中传递数据?例如
glTexCoordPointer(4, GL_FLOAT, 32 /* stride*/, (GLvoid*)((char*)vertexData + 3*4));

尝试在其他 Android 设备或平台上运行您的应用

于 2011-12-23T09:09:43.320 回答