- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试在 OpenGL 中设置相机来查看 3 维中的某些点。为了实现这一点,我不想使用旧的、固定的功能样式(glMatrixMode()、glTranslate 等),而是自己设置模型 View 投影矩阵并在我的顶点着色器中使用它。正交投影就足够了。
很多关于这方面的教程似乎都使用 glm 库,但由于我对 OpenGL 完全陌生,我想以正确的方式学习它,然后使用一些第三方库。此外,大多数教程没有描述如何使用 glMotionFunc() 和 glMouseFunc() 在空间中定位相机。
所以,我想我正在寻找一些示例代码和指导如何以 3D 形式查看我的点。这是我编写的顶点着色器:
const GLchar *vertex_shader = // Vertex Shader
"#version 330\n"
"layout (location = 0) in vec4 in_position;"
"layout (location = 1) in vec4 in_color;"
"uniform float myPointSize;"
"uniform mat4 myMVP;"
"out vec4 color;"
"void main()"
"{"
" color = in_color;"
" gl_Position = in_position * myMVP;"
" gl_PointSize = myPointSize;"
"}\0";
我在着色器设置方法中将 MVP 的初始值设置为单位矩阵,这为我的点提供了正确的 2D 表示:
// Set up initial values for uniform variables
glUseProgram(shader_program);
location_pointSize = glGetUniformLocation(shader_program, "myPointSize");
glUniform1f(location_pointSize, 25.0f);
location_mvp = glGetUniformLocation(shader_program, "myMVP");
float mvp_array[16] = {1.0f, 0.0f, 0.0f, 0.0f, // 1st column
0.0f, 1.0f, 0.0f, 0.0f, // 2nd column
0.0f, 0.0f, 1.0f, 0.0f, // 3rd column
0.0f, 0.0f, 0.0f, 1.0f // 4th column
};
glUniformMatrix4fv(location_mvp, 1, GL_FALSE, mvp_array);
glUseProgram(0);
现在我的问题是如何调整“motion”和“mouse”这两个函数,到目前为止,这两个函数只有前面示例中的一些代码,其中使用了已弃用的执行此操作的样式:
// OLD, UNUSED VARIABLES
int mouse_old_x;
int mouse_old_y;
int mouse_buttons = 0;
float rotate_x = 0.0;
float rotate_y = 0.0;
float translate_z = -3.0;
...
// set view matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, translate_z);
glRotatef(rotate_x, 1.0, 0.0, 0.0);
glRotatef(rotate_y, 0.0, 1.0, 0.0);
...
// OLD, UNUSED FUNCTIONS
void mouse(int button, int state, int x, int y)
{
if (state == GLUT_DOWN)
{
mouse_buttons |= 1<<button;
}
else if (state == GLUT_UP)
{
mouse_buttons = 0;
}
mouse_old_x = x;
mouse_old_y = y;
}
void motion(int x, int y)
{
float dx, dy;
dx = (float)(x - mouse_old_x);
dy = (float)(y - mouse_old_y);
if (mouse_buttons & 1)
{
rotate_x += dy * 0.2f;
rotate_y += dx * 0.2f;
}
else if (mouse_buttons & 4)
{
translate_z += dy * 0.01f;
}
mouse_old_x = x;
mouse_old_y = y;
}
最佳答案
I'd like to learn it the right way and afterwards use some third party libraries.
使用 GLM 没有任何问题,因为 GLM 只是一个处理矩阵的数学库。您想学习最基本的知识是一件非常好的事情。如今这种特征很少见。在进行高级 OpenGL 开发时,了解这些知识非常宝贵。
好的,您需要学习三件事:
基本离散线性代数,即如何处理具有离散元素的矩阵和向量。标量和复杂元素暂时就足够了。
一点数字。您必须能够编写执行基本线性代数运算的代码:缩放、添加向量、执行向量的内积和外积。执行矩阵-向量和矩阵-矩阵乘法。矩阵求逆。
了解齐次坐标。
(4.如果你想让事情变得有趣,学习四元数,那些东西很摇滚!)
完成第 3 步后,您就可以编写自己的线性数学代码了。即使您还不知道齐次坐标。只需编写它就可以有效地处理 4×4 维矩阵和 4 维向量。
一旦掌握了齐次坐标,您就会了解 OpenGL 的实际用途。然后:放弃那些最初的编码步骤来编写自己的线性数学库。为什么?因为它会充满错误。我维护的那一小本 linmath.h 就充满了它们;每次我在新项目中使用它时,我都会修复其中的一些问题。因此,我建议您使用经过充分测试的东西,例如 GLM 或 Eigen。
I set up the initial value of the MVP to be the identity matrix in my shader set up method which gives me the correct 2D representation of my points:
您应该将它们分成 3 个矩阵:模型、 View 和投影。在你的着色器中你应该有两个,模型 View 和投影。 IE。您按原样将投影传递给着色器,但计算以单独的统一形式传递的复合Model·View = Modelview
矩阵。
要移动“相机”,您需要修改View
矩阵。
Now my question is how to adapt the two functions "motion" and "mouse", which to this point only have some code from a previous example, where the deprecated style of doing this was used:
大部分代码保持不变,因为它不涉及 OpenGL。您必须替换的是那些 glRotate 和 glTranslate 调用。
如前所述,您正在处理View
矩阵。首先让我们看看 glRotate 做了什么。在固定函数 OpenGL 中,有一个内部别名,我们称之为 M,它被设置为使用 glMatrixMode 选择的任何矩阵。然后我们可以将glRotate的伪代码写为
proc glRotate(angle, vec_x, vec_y, vec_z):
mat4x4 R = make_rotation_matrix(angle, vec_x, vec_y, vec_z)
M = M · R
好吧,所有的魔力似乎都在于函数 make_rotation_matrix
中。那个看起来怎么样。既然你正在学习线性代数,这对你来说是一个很好的练习。查找具有以下属性的矩阵 R
:
l a = R·a
,其中a是旋转轴
cos(phi) = b·c && b·a = 0 && b·c = 0
,其中 phi 是旋转角度
由于您可能只想完成这件事,因此您也可以查看 OpenGL-1.1 规范,该规范在有关 glRotatef 的部分中记录了该矩阵
在它们旁边,您可以找到所有其他矩阵操作函数的规范。
现在,您不再需要对使用 glMatrixMode 选择的某些隐藏状态变量进行操作,而是让矩阵数学库直接对您定义和提供的矩阵变量进行操作。在您的情况下查看
。与Projection
和Model
类似。然后,当您进行渲染时,您将模型和 View 收缩到已经提到的复合体中。原因是,您通常需要将顶点位置带入视空间的中间结果(对于片段着色器来说,Modelview *position
)。确定矩阵值后,您可以绑定(bind)程序 (glUseProgram) 并设置统一值,然后渲染几何图形。 (glDraw...)
关于opengl - 如何使用鼠标改变OpenGL相机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14172331/
在 OpenGL/ES 中,在实现渲染到纹理功能时,您必须小心,不要引起反馈循环(从正在写入的同一纹理中读取像素)。由于显而易见的原因,当您读取和写入纹理的相同像素时,行为是未定义的。但是,如果您正在
正如我们最终都知道的那样,规范是一回事,实现是另一回事。大多数错误是我们自己造成的,但有时情况并非如此。 我相信列出以下内容会很有用: GPU 驱动程序中当前已知的与最新版本的 OpenGL 和 GL
很难说出这里问的是什么。这个问题是模棱两可的、模糊的、不完整的、过于宽泛的或修辞的,无法以目前的形式得到合理的回答。为了帮助澄清这个问题以便可以重新打开它,visit the help center
我正在学习 OpenGL,非常想知道与显卡的交互如何。 我觉得了解它是如何在图形驱动程序中实现的,会让我了解 opengl 的完整内部结构(通过这个我可以知道哪些阶段/因素影响我对 opengl 性能
我正在尝试绘制到大于屏幕尺寸(即 320x480)的渲染缓冲区 (512x512)。 执行 glReadPixels 后,图像看起来是正确的,除非图像的尺寸超过屏幕尺寸——在本例中,超过 320 水平
我正在 Windows 中制作一个 3D 小行星游戏(使用 OpenGL 和 GLUT),您可以在其中穿过一堆障碍物在太空中移动并生存下来。我正在寻找一种方法来针对无聊的 bg 颜色选项设置图像背景。
如果我想要一个包含 100 个 10*10 像素 Sprite 的 Sprite 表,是否可以将它们全部排成一排来制作 1,000*10 像素纹理?还是 GPU 对不那么窄的纹理表现更好?这对性能有什
这个问题在这里已经有了答案: Rendering 2D sprites in a 3D world? (7 个答案) 关闭 6 年前。 我如何概念化让图像始终面对相机。我尝试将三角函数与 arcta
是否可以在 OpenGL 中增加缓冲区? 假设我想使用实例化渲染。每次在世界上生成一个新对象时,我都必须用实例化数据更新缓冲区。 在这种情况下,我有一个 3 个 float 的缓冲区 std::v
有人可以向我解释为什么下面的代码没有绘制任何东西,但如果我使用 GL_LINE_LOOP 它确实形成了一个闭环吗? glBegin(GL_POLYGON); for(int i = 0; i <= N
正如标题所说,OpenGL 中的渲染目标是什么?我对 OpenGL 很陌生,我看到的所有网站都让我很困惑。 它只是一个缓冲区,我在其中放置稍后将用于渲染的东西吗? 如果您能提供一个很好的引用来阅读它,
当使用 OpenGL 1.4 固定功能多纹理时,每个纹理阶段的输出在传递到下一个阶段之前是否都固定在 [0, 1]? spec说(第 153 页): If the value of TEXTURE_E
我比较了 2 个函数 openGL ES 和 openGL gvec4 texelFetchOffset(gsampler2DArray sampler, ivec3 P, int lod, ivec
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 10 年前。 Improve thi
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?将问题更新为 on-topic对于堆栈溢出。 6年前关闭。 Improve this qu
那么当你调用opengl函数时,比如glDraw或者gLBufferData,是否会导致程序线程停止等待GL完成调用呢? 如果不是,那么 GL 如何处理调用像 glDraw 这样的重要函数,然后立即更
我正在尝试实现级联阴影贴图,当我想访问我的视锥体的每个分区的相应深度纹理时,我遇到了一个错误。 更具体地说,当我想选择正确的阴影纹理时会出现我的问题,如果我尝试下面的代码,我会得到一个像 this 中
我想为OpenGL ES和OpenGL(Windows)使用相同的着色器源。为此,我想定义自定义数据类型并仅使用OpenGL ES函数。 一种方法是定义: #define highp #define
我尝试用 6 个位图映射立方体以实现天空盒效果。我的问题是一个纹理映射到立方体的每个面。我已经检查了 gDEBugger,在立方体纹理内存中我只有一个 图像(因为我尝试加载六个图像)。 代码准备纹理:
在 OpenGL 中偏移深度的最佳方法是什么?我目前每个多边形都有索引顶点属性,我将其传递给 OpenGL 中的顶点着色器。我的目标是在深度上偏移多边形,其中最高索引始终位于较低索引的前面。我目前有这
我是一名优秀的程序员,十分优秀!