3

我正在使用 OpenGL 2.0 来绘制一个矩形。最初的视口是这样的,我从上面看,我可以看到我预期的矩形。然后我开始围绕 x 轴旋转这个矩形。当旋转角度等于 -90 度(如果向另一个方向旋转,则为 +90 度),矩形消失。当我旋转超过 90 度/-90 度时,我希望看到矩形的底面,但视图却消失了。当上表面即将显示时,它确实会重新出现,总旋转角度为 -270 度(或 +270 度)。

我如何确保我可以一直看到矩形(旋转时上下表面都必须可见)?

这是相关的代码:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch * touch = [touches anyObject];
    if ([touches count] == 1) {
        CGPoint currLoc = [touch locationInView:self];
        CGPoint lastLoc = [touch previousLocationInView:self];
        CGPoint diff = CGPointMake(lastLoc.x - currLoc.x, lastLoc.y - currLoc.y);

        rotX = -1 * GLKMathDegreesToRadians(diff.y / 2.0);
        rotY = -1 * GLKMathDegreesToRadians(diff.x / 2.0);

        totalRotationX += ((rotX * 180.0f)/3.141592f);

        NSLog(@"rotX: %f, rotY: %f, totalRotationX: %f", rotX, rotY, totalRotationX);

        //rotate around x axis
        GLKVector3 xAxis = GLKMatrix4MultiplyVector3(GLKMatrix4Invert(_rotMatrix, &isInvertible), GLKVector3Make(1, 0, 0));
        _rotMatrix = GLKMatrix4Rotate(_rotMatrix, rotX, xAxis.v[0], 0, 0);
    }
}


-(void)update{
    GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0, 0, -6.0f);
    modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, _rotMatrix);
    self.effect.transform.modelviewMatrix = modelViewMatrix;

    float aspect = fabsf(self.bounds.size.width / self.bounds.size.height);
    GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0, 10.0f);
    self.effect.transform.projectionMatrix = projectionMatrix;
}

- (void)setupGL {

    NSLog(@"setupGL");
    isInvertible = YES;
    totalRotationX = 0;
    [EAGLContext setCurrentContext:self.context];
    glEnable(GL_CULL_FACE);

    self.effect = [[GLKBaseEffect alloc] init];

    // New lines
    glGenVertexArraysOES(1, &_vertexArray);
    glBindVertexArrayOES(_vertexArray);

    // Old stuff
    glGenBuffers(1, &_vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);

    glGenBuffers(1, &_indexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);

    glViewport(0, 0, self.frame.size.width, self.frame.size.height);

    // New lines (were previously in draw)
    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, Position));
    glEnableVertexAttribArray(GLKVertexAttribColor);
    glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, Color));

    _rotMatrix = GLKMatrix4Identity;

    // New line
    glBindVertexArrayOES(0);

    initialized = 1;
}

我是 OpenGL 的新手,我正在使用 GLKit 和 OpenGL 2.0

谢谢。

4

1 回答 1

2

在 OpenGL 中无法渲染的原因有很多。在这种情况下,它是背面剔除(参见问题的评论)。背面剔除很有用,因为它可以忽略背对相机的三角形并节省一些光栅化/片段处理时间。由于许多网格/对象是不透水的,而且您无论如何都不想看到内部,因此实际上需要双面着色是不常见的。此功能从定义三角形的前/后开始。这是按照给定顶点的顺序(有时称为缠绕方向)完成的。glFrontFace选择定义向前的顺时针/逆时针方向,glCullFace选择剔除前或后(我猜有些人可能认为两者都没有多大意义),最后启用/禁用:

glEnable(GL_CULL_FACE); //discards triangles facing away from the camera
glDisable(GL_CULL_FACE); //default, two-sided rendering

我检查几何图形不可见的其他一些事情包括......

  • 几何颜色是否与背景相同。在这里选择非黑色/白色背景会很方便。
  • 几何图形是否实际绘制在查看体积内。抛出一个简单的对象(立即模式有帮助),并可能使用身份投影/模型视图来排除它们。
  • 观看音量是否正确。近/远平面相距太远(导致 z-fighting)或0.0f近平面是常见问题。此外,当切换到投影矩阵时,在 Z=0 平面上绘制的任何内容都将不再可见。
  • 是否启用混合,一切都是透明的。
  • 深度缓冲区是否未被清除并导致后续帧被丢弃。
  • 在固定管道渲染中,从前一帧继承glTranslate/glRotate变换会导致对象射向远处。始终保持glLoadIdentity显示功能的顶部。
  • 渲染循环的结构是否正确 - clear/draw/swapbuffers
  • 当然还有更多——几何着色器不输出任何东西,顶点着色器将顶点转换到相同的位置(所以它们都是退化的),片段着色器在不应该调用丢弃时调用丢弃,VBO 绑定/索引问题等。检查 GL 错误是必须但永远不会发现所有错误。
于 2013-10-27T07:53:12.670 回答