我应该按什么顺序将顶点发送到 OpenGL 进行剔除

问题描述 投票:0回答:3

我正在学习 3d opengl,进展相当顺利,目前我有一个很好的移动相机和一些简单的立方体对象。目前使用顶点数组,但我在这里很快就切换到 VBO。我只是想启用剔除,但是我不确定应该以什么顺序指定我的顶点,现在这就是我正在做的:

void cube::update_verts(){
GLushort cur=0;

///back face
verts[cur++]=x; verts[cur++]=y; verts[cur++]=z;
verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z;
verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z;
verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z;

///right face
verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z;
verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z;
verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z+sz;
verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z+sz;

///top face
verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z;
verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z;
verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z+sz;
verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z+sz;

///front face
verts[cur++]=x; verts[cur++]=y; verts[cur++]=z+sz;
verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z+sz;
verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z+sz;
verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z+sz;

///bottom face
verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z;
verts[cur++]=x; verts[cur++]=y; verts[cur++]=z;
verts[cur++]=x; verts[cur++]=y; verts[cur++]=z+sz;
verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z+sz;

///left face
verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z;
verts[cur++]=x; verts[cur++]=y; verts[cur++]=z;
verts[cur++]=x; verts[cur++]=y; verts[cur++]=z+sz;
verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z+sz;


}

///Drawing Code:

glVertexPointer(3,GL_FLOAT,0,object.verts);
glColorPointer(3,GL_UNSIGNED_BYTE,0,object.colors);
glDrawArrays(GL_QUADS,0,6*4);

但这绝对是错误的,因为当我

glEnable(GL_CULL_FACE);
时,我的立方体没有显示正确的面(如下所示)。

正常 Regular View From Top

问题儿童 View From Side

这两个图像都启用了剔除功能。

我应该按什么顺序指定顶点?


(编辑)更新的工作功能:

void cube::update_verts(){
GLushort cur=0;

///top face
verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z;
verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z+sz;
verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z+sz;
verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z;


///bottom face
verts[cur++]=x; verts[cur++]=y; verts[cur++]=z;
verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z;
verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z+sz;
verts[cur++]=x; verts[cur++]=y; verts[cur++]=z+sz;

///left face
verts[cur++]=x; verts[cur++]=y; verts[cur++]=z;
verts[cur++]=x; verts[cur++]=y; verts[cur++]=z+sz;
verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z+sz;
verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z;

///right face
verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z;
verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z;
verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z+sz;
verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z+sz;

///front face
verts[cur++]=x; verts[cur++]=y; verts[cur++]=z+sz;
verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z+sz;
verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z+sz;
verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z+sz;


///back face
verts[cur++]=x; verts[cur++]=y; verts[cur++]=z;
verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z;
verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z;
verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z;

}
c++ opengl sdl
3个回答
129
投票

默认?按逆时针顺序。

考虑一个面向相机的三角形:

A
|\
| \
|  \
B---C

A->B->C 为正面(逆时针顺序),A->C->B 为背面(顺时针顺序)。

您可以通过

glFrontFace()
:

更改 OpenGL 考虑“正面”的方式

据说多边形到窗口坐标的投影有 顺时针缠绕,如果一个假想的物体沿着从它的路径开始的路径 第一个顶点,第二个顶点,依此类推,直到最后一个顶点,并且 最后回到第一个顶点,沿顺时针方向移动约 多边形的内部。多边形的缠绕据说是 如果假想的物体沿着相同的路径移动,则逆时针移动 以围绕多边形内部的逆时针方向。

glFrontFace
指定多边形是否顺时针缠绕 窗口坐标,或在窗口坐标中逆时针缠绕, 被认为是正面的。将
GL_CCW
传递到
mode
选择 逆时针多边形为正面;
GL_CW
选择顺时针方向 多边形作为正面。

默认情况下,逆时针多边形被视为正面。

为了对顶点进行排序,请考虑一个理想的立方体:

  6---7
 /|  /|
2---3 |
| 4-|-5
|/  |/ 
0---1

对于每张脸,在心里旋转它以面对相机(你的心灵之眼):

Sides:
2---3  3---7  7---6  6---2
|   |  |   |  |   |  |   |
|   |  |   |  |   |  |   |
0---1  1---5  5---4  4---0

Bottom/Top:
0---1  6---7
|   |  |   |
|   |  |   |
4---5  2---3

然后您可以按正确的逆时针顺序直观地读出四边形或三角形对:

2---3                3         2---3 
|   |  becomes      /|   and   |  / 
|   |             /  |         |/ 
0---1            0---1         0 

Triangles 0-1-3 and 0-3-2
Quad 0-1-3-2

从哪个顶点开始三角形/四边形并不重要,例如第一个三角形

0-1-3
1-3-0
3-0-1
都是同样有效的正面三角形。


8
投票

我学到了另一个确定顶点顺序的经验法则(字面意思),称为“右手法则”。
想象一下你张开的手(右)在立方体内部,拇指指向立方体的中心。如果您随后将手握成拳头,您的手指将以正确的顺序经过顶点。由于您使用的是右手,因此称为“右手法则”。

相反,如果您从左手开始并将拇指远离立方体的中心,您的手指将再次以正确的顺序扫过顶点。这被称为“左手法则”(惊喜)。

这两种方法都可以为您提供逆时针顺序。对于顺时针顺序,只需使用另一只手即可。


0
投票

这是一个嵌套的立方体。使用 @genpfault 对立方体面进行编号的内部立方体和外部立方体。数据采用 *.ply(3D 点云)格式,还包含 RGB 颜色数据。

如果复制并粘贴到文件中,请务必检查每行的换行符终止符。我在这里添加了 2 个空格,因为这是显示新行所需的。

层数 格式 ascii 1.0
元素顶点 16
属性 float32 x
属性 float32 y
属性 float32 z
属性 uchar 红
房产 uchar 绿色
属性 uchar 蓝色
元素面24
属性列表 uint8 int32 vertex_indices
结束标题
-4.00 -4.00 4.00 255 0 0
4.00 -4.00 4.00 255 0 0
4.00 4.00 4.00 255 0 0
-4.00 4.00 4.00 255 0 0
-4.00 -4.00 -4.00 255 0 0
4.00 -4.00 -4.00 255 0 0
-4.00 4.00 -4.00 255 0 0
4.00 4.00 -4.00 255 0 0
-6.00 -6.00 6.00 255 255 255
6.00 -6.00 6.00 255 255 255
-6.00 6.00 6.00 255 255 255
6.00 6.00 6.00 255 255 255
-6.00 -6.00 -6.00 255 255 255
6.00 -6.00 -6.00 255 255 255
-6.00 6.00 -6.00 255 255 255
6.00 6.00 -6.00 255 255 255
3 0 1 2
3 1 3 2
3 1 5 3
3 5 7 3
3 5 4 7
3 4 6 7
3 4 0 6
3 0 2 6
3 4 5 0
3 5 1 0
3 2 3 6
3 3 7 6
3 8 9 10
3 9 11 10
3 9 13 11
3 13 15 11
3 13 12 15
3 12 14 15
3 12 8 14
3 8 10 14
3 12 13 8
3 13 9 8
3 10 11 14
3 11 15 14

© www.soinside.com 2019 - 2024. All rights reserved.