c++ - 如何创建匹配当前投影矩阵的 glClipPlanes?

标签 c++ opengl clipping clip projection-matrix

我正在渲染空间中的一组点,用户已手动旋转、平移、缩放这些点,并最终在所需部分上绘制了一个选择矩形。当他们这样做时,我调用 gluPickMatrix 然后调用 gluPerspective 构建投影矩阵,然后使用 GL_SELECT 渲染模式在他们选择的位置中查找点地区。

我只想显示所选区域中的点。为了测试每个点都有一个 bool 值 isSelected,我知道选择有效,因为正确的点被选中了。但是,有太多的点使它不可行,所以我想使用 glClipPlane 来构造对应于直角棱柱的四个平面(编辑:我的意思是平截头体) 由用户的选择矩形定义。设置投影矩阵后,如何推导传递给 glClipPlane 的系数?

现在我正在这样做,但它最终会剪掉所有的点:

// Set up projection matrix
int viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
gluPickMatrix(x, y, w, h, viewport);
gluPerspective(FOV_Y, ASPECT_RATIO, NEAR_PLANE, FAR_PLANE);

// Derive clip planes - this doesn't work
// Based on the paper "Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix"
// http://graphics.cs.ucf.edu/cap4720/fall2008/plane_extraction.pdf
double t[4], r[4], b[4], l[4];
double m[16];
glGetDoublev(GL_PROJECTION_MATRIX, m);
t[0] = m[3] - m[1]; t[1] = m[7] - m[5]; t[2] = m[11] - m[9]; t[3] = m[15] - m[13];
r[0] = m[3] - m[0]; r[1] = m[7] - m[4]; r[2] = m[11] - m[8]; r[3] = m[15] - m[12];
b[0] = m[3] + m[1]; b[1] = m[7] + m[5]; b[2] = m[11] + m[9]; b[3] = m[15] + m[13];
l[0] = m[3] + m[0]; l[1] = m[7] + m[4]; l[2] = m[11] + m[8]; l[3] = m[15] + m[12];

// ... Render points in GL_SELECT mode, then go back to GL_RENDER mode ...

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// ... Apply user's pan/rotate/zoom choices here ...
// Apply clip planes
glEnable(GL_CLIP_PLANE0);
glClipPlane(GL_CLIP_PLANE0, t);
glEnable(GL_CLIP_PLANE1);
glClipPlane(GL_CLIP_PLANE1, r);
glEnable(GL_CLIP_PLANE2);
glClipPlane(GL_CLIP_PLANE2, b);
glEnable(GL_CLIP_PLANE3);
glClipPlane(GL_CLIP_PLANE3, l);

我也尝试过归一化和/或否定平面坐标,这似乎最终还是会剪掉所有的点。

最佳答案

仔细阅读那篇论文后,我发现了问题所在。我没有考虑模型 View 矩阵。

这个:

double m[16];
glGetDoublev(GL_PROJECTION_MATRIX, m);
// ... derive t, r, b, and l from m

应该是这样的:

double vm[16], pm[16], m[16];
glGetDoublev(GL_MODELVIEW_MATRIX, vm);
glGetDoublev(GL_PROJECTION_MATRIX, pm);
matrix_mul(vm, pm, m); // m = vm * pm
// ... derive t, r, b, and l from m

关于c++ - 如何创建匹配当前投影矩阵的 glClipPlanes?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14926732/

相关文章:

c++ - 是否可以在 C++ 中将可变长度数组作为参数传递?

c++ - 使指针指向数组c++的开头

c++ - 从 C++ 自动登录网站

c++ - gprof 输出问题

c++ - 获取错误 : "error: conflicting types for ‘call_celsius’ "and "note: previous implicit declaration of ‘call_celsius’ was here"

opengl - 如何反转3D look_at函数?

Silverlight: Canvas 溢出

opengl - 核心视频 - displaylink 我需要帮助解释 CVTimeStamp

ios - 如何让 CGContextClip 包含边框像素?

tensorflow - 有没有办法剪辑 tensorflow 中的中间爆炸梯度