我正在为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
答案 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)
这不是您问题的准确答案,但您可能想要检查的内容很少:
glTexCoordPointer(4, GL_FLOAT, 32 /* stride*/, (GLvoid*)((char*)vertexData + 3*4));
尝试在其他Android设备或平台上运行您的应用