2011-12-19 58 views
1

我正在为Android开发一个OpenGL ES 1.1应用程序(OpenGL调用是由通过NDK调用的C代码制作的)。Android上的OpenGL ES 1.1:Q纹理坐标没有任何效果

我的问题是,我试图使用Q纹理坐标以及通常的(S,T)纹理坐标。但是,我对Q所做的任何事情都没有任何明显的影响。 (另外:想要用Q坐标来玩的原因是我想用正确的透视效果(即不是仿射)将矩形纹理映射到空间中的梯形四边形 - 如http://www.xyzw.us/~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野火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

+0

您的示例是否适用于某些平台/操作系统?您是否在使用OpenGLES二进制文件的Mac/Win/Linux上尝试过? – rockeye 2011-12-22 14:58:04

+0

嗨rockeye,还没有尝试过,但它确实在我的待办事项列表(在这一刻缺乏时间)。我肯定有其他人使用Q坐标来获得效果的例子。 – occulus 2011-12-22 15:52:52

+0

'glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST)'改变了什么? – genpfault 2011-12-22 22:22:23

回答

0

这不是一个确切的答案,你的问题,但也有,你可能想看看几件事情:

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

尝试在其他Android设备或平台

+0

嗨rockeye。是的,两个高度和宽度的功率(512 x 512)。 R坐标以0.0开始,所以我试过了 - 但我最终还是把其他值也放在那里,以防我的理解或R和Q的顺序切换 - 只是为了看看我能否影响呈现的内容以任何方式(我不能))。 我传递我的数据已经使用glTextCoordPointer和glVertexPointer - 事实上,您的代码示例实际上是我发布的代码的引用。 – occulus 2011-12-23 10:10:28

+0

不,请仔细看看,我的代码示例的最后一个参数是vertexData,而不是NULL(如代码示例中所示)。但我想你是以另一种方式指定你的数据? – rockeye 2011-12-23 10:15:28

+0

对不起,请原谅,是的。我使用glBindBuffer绑定缓冲区: glBindBuffer(GL_ARRAY_BUFFER,sphereVBO); glBufferData(GL_ARRAY_BUFFER,vertexBufferSize,vertexData,GL_STATIC_DRAW);.所以在这个调用之后,给出的索引被放入指定的数组中。所以我相信最终效果和你的片段一样。 – occulus 2011-12-23 14:27:37

1

我同意你的应用程序运行你。一些android设备不支持OpenGL ES 1.1中的纹理坐标。

以我的经验,Galaxy S,S2,S3工作。银河Note,Galaxy S2 HD不。 (可能是GPU问题??)

但是OpenGL ES 2.0中的纹理坐标处理这些有问题的设备。

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支持装置和1.0上的其他人使用OpenGL 2.0。

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

希望得到这个帮助。