在我的项目中,我想创建 5 个纹理层。
每层由 4 个带纹理的矩形组成。一层的这四个部分被排列成一个大的纹理。这些层是部分透明的,并排列在彼此的前面以创建三维外观。
当我只启用一个图层运行项目时,一切看起来都很好,但是一旦我添加第二个(或更多)图层,一切都会变得混乱。某些部分丢失,其他部分的 z 坐标完全错误(值本身看起来不错,但背景层突然成为最前面的层)。有些部分甚至会移动它们的 x 坐标(如果我使用 NSLog 输出所有方形坐标,这个在设置上看起来也不错)。
这是我的 setupVBOs 函数,我将对象坐标写入 VBO(我只有一个 Index VBO,因为每个正方形都是相同的,但是一个 5x4 VBO 的数组来保存图层每个部分的坐标。)
- (void)setupVBOs {
glGenBuffers(1, &_indexBufferLayer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBufferLayer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(IndicesLayer), IndicesLayer, GL_STATIC_DRAW);
for (int layerNo = 1; layerNo < LAYER_COUNT + 1; ++layerNo)
{
for (int layerPart = 1; layerPart < LAYER_PARTS + 1; ++layerPart)
{
glGenBuffers(1, &_vertexBufferLayer[layerNo][layerPart]);
GLfloat x = -3.0 + (2.0 * (layerPart - 1));
GLfloat z = 0.0 + (50.0 * (layerNo - 1));
NSLog(@"Layer %d, Part %d: x=%f, z=%f", layerNo, layerPart, x, z);
// Alter the Texture slightly to
// remove errors from compression (x-Coord.)
Vertex Vertices[] = {
{{x + 1.0, -1.0, z}, {0.9865, 1.0}},
{{x + 1.0, +1.0, z}, {0.9865, 0}},
{{x - 1.0, +1.0, z}, {0.01, 0}},
{{x - 1.0, -1.0, z}, {0.01, 1.0}}
};
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferLayer[layerNo][layerPart]);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
x = z = 0;
}
}
}
这是我的渲染函数,我在其中绘制所有内容并添加纹理。
- (void)render: (CADisplayLink*)displayLink {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
CC3GLMatrix *projection = [CC3GLMatrix matrix];
float h = 4.0f * self.frame.size.height / self.frame.size.width;
[projection populateFromFrustumLeft:-1 andRight:1 andBottom:-h/4 andTop:h/4 andNear:2 andFar:500];
CC3GLMatrix *modelView = [CC3GLMatrix matrix];
// Translate the Modelviewmatrix
[modelView populateFromTranslation:CC3VectorMake(_cameraX, _cameraY, -5.0)];
// Rotate the Modelviewmatrix
[modelView rotateBy:CC3VectorMake(_currentRotation, 0, 90)];
[modelView translateByZ:_cameraZoom];
//
// Draw all layers
//
for (int layerNo = 1; layerNo < LAYER_COUNT + 1; layerNo++)
{
GLfloat layerFactor = (LAYER_COUNT + 1 - layerNo) * 22.0;
GLfloat scaleFactor = 100.0 + layerFactor;
[modelView scaleByX:scaleFactor];
[modelView scaleByY:scaleFactor];
for (int layerPart = 1; layerPart < LAYER_PARTS + 1; layerPart++)
{
glUniformMatrix4fv(_modelViewUniform, 1, 0, modelView.glMatrix);
glUniformMatrix4fv(_projectionUniform, 1, 0, projection.glMatrix);
GLuint uniformTexture = glGetUniformLocation(programHandle, "Texture");
// Bind Buffer and Texture
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferLayer[layerNo][layerPart]);
// Activate Texturing Pipeline and Bind Texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _layers[layerNo][layerPart][0]);
glUniform1i(uniformTexture, 0);
// Vertex Shader calls
glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) 0);
glVertexAttribPointer(_texCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 3));
glEnableVertexAttribArray(_positionSlot);
glEnableVertexAttribArray(_texCoordSlot);
glDrawElements(GL_TRIANGLES, sizeof(IndicesLayer)/sizeof(IndicesLayer[0]), GL_UNSIGNED_BYTE, 0);
glDisableVertexAttribArray(_texCoordSlot);
glDisableVertexAttribArray(_positionSlot);
}
[modelView scaleByX:1/scaleFactor];
[modelView scaleByY:1/scaleFactor];
}
[_context presentRenderbuffer:GL_RENDERBUFFER];
}