如何使用鼠标改变OpenGL相机

2024-04-09

我正在尝试在 OpenGL 中设置一个相机来查看 3 维中的一些点。 为了实现这一点,我不想使用旧的、固定的功能样式(glMatrixMode()、glTranslate 等),而是自己设置模型视图投影矩阵并在我的顶点着色器中使用它。正交投影就足够了。

很多关于这方面的教程似乎都使用 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;
}

我想以正确的方式学习它,然后使用一些第三方库。

使用 GLM 没有任何问题,因为 GLM 只是一个处理矩阵的数学库。您想学习最基本的知识是一件非常好的事情。如今这种特征很少见。在进行高级 OpenGL 开发时,了解这些知识是非常宝贵的。

好的,我要教你三件事:

  1. 基本离散线性代数,即如何处理具有离散元素的矩阵和向量。标量和复数元素暂时就足够了。

  2. 一点点数字。您必须能够编写执行基本线性代数运算的代码:缩放、添加向量、执行向量的内积和外积。执行矩阵-向量和矩阵-矩阵乘法。矩阵求逆。

  3. 了解齐次坐标。

(4.如果你想让事情变得有趣,学习四元数,那些东西太棒了!)

第 3 步之后,您就可以编写自己的线性数学代码了。即使您还不知道齐次坐标。只需编写它就可以有效地处理 4×4 维矩阵和 4 维向量。

一旦掌握了齐次坐标,您就会了解 OpenGL 的实际用途。进而:放弃最初的编码步骤,编写您自己的线性数学库。为什么?因为它会充满错误。我维护的那一小本 linmath.h 就充满了它们;每次我在新项目中使用它时,我都会修复其中的一些问题。因此,我建议您使用经过充分测试的东西,例如 GLM 或 Eigen。

我在着色器设置方法中将 MVP 的初始值设置为单位矩阵,这为我的点提供了正确的 2D 表示:

您应该将它们分为 3 个矩阵:模型、视图和投影。在你的着色器中你应该有两个,模型视图和投影。 IE。您将投影按原样传递给着色器,但计算一个复合值Model · View = Modelview矩阵以单独的制服传递。

要移动“相机”,您需要修改View matrix.

现在我的问题是如何调整“motion”和“mouse”这两个函数,到目前为止,这两个函数只有前面示例中的一些代码,其中使用了已弃用的执行此操作的样式:

大部分代码保持不变,因为它不涉及 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 选择的某些隐藏状态变量进行操作,而是让矩阵数学库直接对您定义和提供的矩阵变量进行操作。在你的情况下View。和你做的类似Projection and Model。然后,当您进行渲染时,您将模型和视图收缩到已经提到的复合体中。原因是,您通常需要将顶点位置带入视空间的中间结果(Modelview * position对于片段着色器)。确定矩阵值后,绑定程序 (glUseProgram) 并设置统一值,然后渲染几何图形。 (gl绘制...)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用鼠标改变OpenGL相机 的相关文章

  • Windows 上的 OpenGL SDK

    我正在尝试编写一个 OpenGL 应用程序 因此我安装了 Windows 7 SDK 然而 它似乎是OpenGL 1 1 define GL VERSION 1 1 1 如何找到我安装的 OpenGL 版本 dll 以及在哪里可以找到较新的
  • 如何在片段着色器中将 gl_FragCoord 转换为世界空间点?

    我的理解是 如果您有视图投影矩阵 屏幕宽度和屏幕高度的逆矩阵 则可以将 gl FragCoord 转换为片段着色器中世界坐标中的点 首先 你转换gl FragCoord x and gl FragCoord y通过分别除以宽度和高度 然后将
  • 将代表扩展到矩阵?

    如果你打电话rep在矩阵上 它重复其元素而不是整个矩阵 传统的修复方法是调用rep list theMatrix 我想延长rep以便它自动执行此操作 我尝试使用 rep matrix lt function x rep list x 这确实
  • 对二进制二维矩阵进行排序?

    我在这里寻找一些指示 因为我不太知道从哪里开始研究这个 我有一个二维矩阵 每个单元格中有 0 或 1 例如 1 2 3 4 A 0 1 1 0 B 1 1 1 0 C 0 1 0 0 D 1 1 0 0 我想对其进行排序 使其尽可能 上三角
  • 拍摄的相机图像看起来模糊

    我的问题捕获的图像在我的应用程序中看起来很模糊 而使用设备相机组件捕获的图像看起来不错 一旦用户单击捕获按钮 就会出现自动缩放效果 有人可以帮助我实现这一场景 我 应该如何以及在哪里申请 这是代码 public void surfaceCh
  • 有没有比“[”更快的方法来对稀疏矩阵进行子集化?

    我是 seqMeta 包的维护者 正在寻找如何加速将大矩阵多次分割成小块的瓶颈的想法 背景 seqMeta 包用于分析遗传数据 所以你有一组受试者 n subject 和一些遗传标记 n snps 这导致 n subject x n snp
  • UIImage 数据始终处于横向模式

    似乎当我用相机以肖像模式拍照时 UIImage具有正确的尺寸 长宽比 1536x2048 3 4 和方向 右 导出到文件 带有UIImage AsPNG Save 它始终以横向模式显示 2048x1536 4 3 这是真的吗 还是我做错了什
  • OpenGL 与 OpenCL,选择哪个以及为什么?

    哪些功能使 OpenCL 能够独特地选择 OpenGL 和 GLSL 进行计算 尽管有与图形相关的术语和不实用的数据类型 OpenGL 是否有任何真正的警告 例如 可以通过使用其他纹理将 a 渲染到纹理来完成并行函数评估 减少操作可以通过迭
  • 为贝塞尔曲线中的每个点绘制切线

    我设法绘制了一条贝塞尔曲线 如下所示 glColor3f 0 1 0 glBegin GL LINE STRIP for int i 3 i lt nPt i 3 glColor3f 0 0 0 for float k 0 k lt NLI
  • 之前对 GL.Color3 的调用使我的纹理使用了错误的颜色

    制作 2D OpenGL 游戏 渲染帧时 我需要首先绘制一些计算的四边形几何体 然后绘制一些纹理精灵 当我的渲染方法主体仅绘制精灵时 一切正常 但是 当我尝试在精灵之前绘制几何四边形时 精灵的纹理会更改为之前使用的最后一个 GL Color
  • VideoCapture 未检测到 uEye 摄像头

    我的 uEye 相机遇到了一个问题 使用我的笔记本电脑摄像头 id 0 或 USB 上的网络摄像头 id 1 此行完美运行 TheVideoCapturer open 1 TheVideoCapturer 属于 VideoCapture 类
  • 是否可以在 Mac OS X 上构建 FreeGLUT?

    我正在做一些关于 OpenGL 的教程 http www arcsynthesis org gltut Basics Tutorial 2001 html那个使用FreeGLUT http freeglut sourceforge net
  • 如何找到平面和 3d 矩阵之间的交平面

    如果我有一堆图像并且尺寸如下 size M 256 256 124 我有 3 个点 它们的坐标是 coor a 100 100 124 coor b 256 156 0 coor c 156 256 0 如何创建 M 与这 3 个点定义的平
  • 如何使用 MPI_Scatterv 将矩阵的行发送到所有进程?

    我正在使用 MPI 接口 我想分割一个矩阵 按行 并将各个部分分配给每个进程 例如 我有这个7x7的方阵M M 0 00 1 00 2 00 3 00 4 00 5 00 6 00 7 00 8 00 9 00 10 00 11 00 12
  • OpenGL/GLSL - 纹理过滤的实现

    我想在 GLSL 着色器中自己实现纹理过滤 min 和 magfilter 因为我想使用 image load and store 而不是采样器 而且我想以特殊方式处理未定义的像素 并且我正在寻找一篇文章或者这样讨论过滤过程 我记得如何从我
  • sRGB 纹理。它是否正确?

    我最近阅读了一些有关 sRGB 格式以及它们如何允许硬件自动对典型显示器执行色彩校正的文章 作为我阅读的一部分 我发现您可以使用普通纹理和返回结果上的 pow 函数来模拟此步骤 无论如何 我想问两个问题 因为我以前从未使用过此功能 首先 有
  • 在 Unity 中实现 Fur with Shells 技术

    我正在尝试在 Unity 中实现皮毛贝壳技术 http developer download nvidia com SDK 10 5 direct3d Source Fur doc FurShellsAndFins pdf Fins 技术被
  • 如何在 Android 中保存相机的临时照片?

    在尝试从相机拍照并将其保存到应用程序的缓存文件夹中时 我没有得到任何可见的结果 应用程序不会崩溃 但在 LogCat 上 当我尝试将 ImageView src 字段设置为刚刚获取的文件的 URI 时 我收到此消息 09 17 14 03
  • glsl 着色器 - 颜色混合,正常模式(就像在 Photoshop 中一样)

    我试图创建混合 2 种颜色的效果 实际上是图像和颜色作为图像叠加 就像在 Photoshop 颜色叠加 和 正常混合 模式中一样 我正在使用 libgdx 这就是我到目前为止所拥有的 attribute vec4 a position at
  • GLKit的GLKMatrix“列专业”如何?

    前提A 当谈论线性存储器中的 列主 矩阵时 列被一个接一个地指定 使得存储器中的前 4 个条目对应于矩阵中的第一列 另一方面 行主 矩阵被理解为依次指定行 以便内存中的前 4 个条目指定矩阵的第一行 A GLKMatrix4看起来像这样 u

随机推荐

  • 在单个 matplotlib 图上嵌入多个 gridspec 布局?

    我正在使用 python 图形库 matplotlib 来绘制报告中的几项内容 我发现自己需要在较小图形的任意网格上方有几个固定计数的图形 我四处搜索 但找不到任何可以让我在单个 matplotlib 图上使用两个 gridspec 布局的
  • 我可以使用购买状态 API 来验证应用程序是否是通过 Play 商店购买的

    我有一个与我的后端通信的应用程序 我希望后端仅在用户通过游戏商店购买该应用程序并且没有窃取它时接受并响应 所以想法是 用户通过 Playstore 购买应用程序 应用程序通过服务器进行通信并发送使用该应用程序的用户的gmail地址 服务器询
  • Django 基于类的 DeleteView 示例

    有谁知道或有人可以制作一个 Django 基于类的通用 DeleteView 的简单示例吗 我想子类化 DeleteView 并确保当前登录的用户在删除该对象之前拥有该对象的所有权 任何帮助将非常感激 先感谢您 这是一个简单的 from d
  • FITS文件的坐标转换问题

    我已经在 python 中加载并绘制了一个 FITS 文件 在上一篇文章的帮助下 我成功地将轴从像素转换为天体坐标 但我无法正确地以毫角秒 mas 为单位获取它们 代码如下 import numpy as np import matplot
  • os.walk 在第一次找到后停止查找子目录

    我需要获取目录中第一次出现的repository config 文件并停止在子目录中查找 这是我的目录树 WAS80 base disk1 ad repository config WAS80 base disk1 md repositor
  • 在脚本中调用matlab脚本

    我有两个 matlab 脚本文件 m 不是函数文件 如果我想在当前脚本中调用另一个脚本 我应该使用哪个命令 谢谢 我找到了答案 只需在另一个脚本中命名该脚本即可 myOtherScript 如果您愿意 可以使用 run myOtherScr
  • WCF 客户端传递用户名令牌,并将 MustUnderstand 设置为 true

    我的任务是创建一个将由外部客户端使用的 WCF 服务 客户端使用 WSSE 安全性 具体来说 他们通过 SOAP 标头传递用户名令牌 WCF 服务托管在启用了 SSL 的 IIS 服务器上 至此 我已经有了一个半工作原型 我现在处理的问题是
  • 检测画布内的鼠标单击位置

    我在尝试定义一个单击空白区域的函数时遇到了一个真正的问题 到目前为止 我已经成功地定义了单击一个对象的位置 其中有 10 个 但现在我需要一个单独的函数 以便在不单击任何对象时使用 总体思路可以在以下位置找到 http deciballs
  • IIS 无法将 Windows 凭据传递到 SQL Server for ASP.NET Core 应用程序

    我在一家大公司工作 每个人都有 Intranet 和 Windows AD 登录 我们有许多内部 SQL Server 数据库 允许我们使用 Windows 身份验证登录 我正在尝试通过 ASP NET Core 应用程序连接到其中一个数据
  • 工作表/范围选择(组合)不起作用

    我的 VBA 发生了一些变化 不允许我完成某些例程 我在下面列出了一个非常简单的例子 如果有人经历过此问题 我将非常感谢为解决此问题提供的任何支持 问题的简单示例 当我使用以下代码时 它工作正常 Sheets Sheet1 Select R
  • 使用 T-SQL 计算“nvarchar”字符串的 SHA1 哈希值

    我正在尝试计算SHA1使用 T SQL 计算 unicode 字符串的哈希值 下面的代码可以很好地工作ASCII字符串 declare input varchar 50 set input some text print SHA1 Hash
  • SQL LIKE 条件检查整数?

    我正在使用一组 SQL LIKE 条件来遍历字母表并列出以适当字母开头的所有项目 例如获取标题以字母 A 开头的所有书籍 SELECT FROM books WHERE title ILIKE A 这对于字母来说没问题 但是如何列出以任意数
  • 使用 xpath 和 nightwatch.js 单击动态文本

    我希望在我的应用程序中单击带有动态文本的元素 通常 要单击带有文本的元素 我会执行以下操作 useXpath click contains text some text 对于具有动态名称的测试 我尝试以下操作 useXpath click
  • window.opener 在 Firefox 中为空

    我有一个页面 打开弹出窗口为 openWindow top prcsTypeSelectionPopup event prcsTypeSelection lovWindow width 750 height 550 true dialog
  • 如何在R中保存包含很多点的pdf

    所以我必须保存一个包含很多点的pdf图 那不是问题 问题是当我打开它时 绘制所有这些点需要很长时间 我怎样才能以这样的方式保存这个pdf 当有人打开它时 它不必逐点绘制 如果图片质量下降一点我也没关系 这是一个示例 我认为这不会使您的计算机
  • 在 Android 中清除 AdMob 生成的缓存文件是一个好习惯吗?

    我已将 AdMob 集成到我的 Android 应用程序中 我注意到该应用程序在应用程序数据文件夹内 AdMob 生成的名为 app webview 的文件夹中占用了越来越多的存储空间 我应该在每次应用程序退出时清除此文件夹的内容吗 我应该
  • @Constraint 中清空 validatedBy

    我注意到所有内置约束都有一个空值validatedBy参数输入 Constraint i e Constraint validatedBy 首先 为什么允许它们具有空值validatedBy 我认为您可以仅将不需要额外验证的约束组合留空 另
  • Eclipse 抱怨 Web 应用程序属性

    我的 web xml 中的网络应用程序声明是
  • 如何强制MySQL将0作为有效的自增值

    长话短说 我有一个 SQL 文件 我想将其导入为skelstyle 文件 因此这将以编程方式重复完成 我可以根据需要编辑 SQL 文件 但我不想碰应用程序本身 该应用程序使用userid 0代表匿名用户 它在数据库中还有一个相关 空白 条目
  • 如何使用鼠标改变OpenGL相机

    我正在尝试在 OpenGL 中设置一个相机来查看 3 维中的一些点 为了实现这一点 我不想使用旧的 固定的功能样式 glMatrixMode glTranslate 等 而是自己设置模型视图投影矩阵并在我的顶点着色器中使用它 正交投影就足够