Android上的OpenGL ES 1.1:Q纹理坐标没有任何影响

时间:2011-12-19 23:43:50

标签: android opengl-es texture-mapping opengl-es-1.1

我正在为Android开发一个OpenGL ES 1.1应用程序(OpenGL调用是通过NDK编写的,通过NDK调用)。

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

(旁白:想要使用Q坐标的原因是我想将矩形纹理映射到空间中的梯形四边形,具有正确的透视效果(即不是仿射) - 如http://www.xyzw.us/~cass/qcoord/所述)。

我尝试设置Q坐标(不是默认的1.0f)的方法是通常的:我提供4个纹理坐标,而不是通常的2.我尝试将各种值放入Q coord(在两者之间混合的情况下甚至进入通常未使用的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 library加载纹理。

更新

我已下载NeHe Android port for Lesson 6。这使用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

perspective correction of texture coordinates in 3d

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

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

2 个答案:

答案 0 :(得分:1)

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

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

但OpenGL ES 2.0中的纹理q coord适用于那些有问题的设备。

Belows是我的着色器代码。

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。

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

希望得到这个帮助。

答案 1 :(得分:0)

这不是您问题的准确答案,但您可能想要检查的内容很少:

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

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