如何使用鼠标改变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相机 的相关文章

  • 如何检测位图中的红色像素

    android中的getPixels 是上下左右读取像素 还是左右上下读取像素 基本上是按行或列读取 如果我想知道图片中的红色值较高的位置 我可以这样做吗 我假设它是按列读取的 Bitmap thumbnail Bitmap data ge
  • 如何在Matlab中计算两个矩阵之间的快速外积?

    我有两个 n m 矩阵 A and B 我想创建一个新的矩阵C类似于 for i 1 n C C outerProduct A i B i end i e C是一个大小为 m x m 的矩阵 即各行的所有外积之和A and B 有没有一种无
  • Android 屏幕坐标到画布视图坐标

    我正在尝试将屏幕 x 和 y 坐标转换为用于在屏幕上绘制的坐标 因此 我从触摸侦听器触发的 MotionEvent 获取屏幕 X 和 Y 坐标 我认为它应该像将它们乘以用于在画布上绘制的矩阵一样简单 所以我在创建视图时创建了 Matrix
  • 将 OpenCV 的 findHomography 透视矩阵转换为 iOS 的 CATransform3D

    我想获取从 OpenCV 返回的透视变换矩阵findHomography http docs opencv org modules calib3d doc camera calibration and 3d reconstruction h
  • 由于“erf”函数使用率较高而导致性能瓶颈

    我使用大型矩阵 100x100 到 3000x3000 进行一些计算 大量求和和矩阵向量乘法 我使用 Eigen 库来处理向量和矩阵 我的代码是简单的类似 C 的代码 只有函数 没有类 并将被编译为 DLL 以在 Excel 上使用 我发现
  • Android相机无法从后台服务拍照

    我已经实现了一项从后台线程拍照的服务 但照片永远不会在我的任何设备上拍摄 这是代码 下面记录输出 public class PhotoCaptureService extends Service private static final S
  • 由两个向量 (n,1) 构建的 R 距离矩阵

    我有两个向量 x n 1 and y n 1 真实值 我想创建一个矩阵M n n 这些向量包含每两对之间的距离 您可以使用outer功能 x lt sample 5 y lt sample 5 x 1 1 5 3 4 2 y 1 2 3 5
  • 为什么 pageX 和 pageY 与包装器相关,而不是与文档相关?

    好的 所以我想让 div prodimg 跟随鼠标位置 这是可行的 只不过它是相对于 wrapper 的左侧 pos 定位的 wrapper 是 details 和 prodimg 的父 div 为什么会发生这种情况 有什么建议来修复它或跟
  • 如何存储(和使用)当前鼠标位置?

    存储当前鼠标位置 系统范围 然后 稍后 将鼠标放在该存储点的最佳方法是什么 NSEvent mouseLocation http developer apple com mac library documentation Cocoa Ref
  • Opengl 非同步/非阻塞地图

    我刚刚找到以下内容OpenGL 规范ARB map buffer range http www opengl org registry specs ARB map buffer range txt 我想知道是否可以使用此扩展进行非阻塞地图调
  • Matlab:通过扩展向量来扩展矩阵

    我有一个dxmxn matrix A 解释 对于每个n 有m维度向量d 我想将每个 d 维向量扩展如下 考虑一个向量v维度 d 1 2 d 它是 x 1 x 2 x d 但为了简单起见 我删除了 x 目标是延长v获得一个d d向量形式 1
  • matlab中的分箱

    我一直无法在 matlab 或 Octave 中找到函数来完成我想要的操作 我有一个两列的矩阵 m x 和 y 值 我知道我可以通过执行 m 1 或 m 2 来提取列 我想将其分成 可能 大小相等的较小矩阵 并绘制这些矩阵的平均值 换句话说
  • 独特的柱组合

    这是我的简化数据集 foo lt data frame var1 c 1 10 var2 rep 1 5 2 var3 rep 1 2 5 var4 rep 3 7 2 总共 20 个变量 foo var1 var2 var3 var4 v
  • Android:想要在相机预览上放置剪影叠加

    我想知道如何在相机预览上添加剪影 到目前为止 我已经完成了以下示例 它只是预览相机 http developer android com reference android view TextureView html http develo
  • 从上三角初始化对称 Theano dmatrix

    我正在尝试拟合一个部分由对称矩阵参数化的 Theano 模型A 为了加强对称性A 我希望能够构建A通过仅传入上三角形中的值 等效的 numpy 代码可能如下所示 import numpy as np def make symmetric p
  • 退出 glutFullScreen()

    我不明白为什么当我按 f 时它进入全屏但不退出全屏 在这个方法的开头我已经设置了bool fullscreen false 这是我的切换代码 case f toggle screenmode if fullscreen glutFullSc
  • 使用 Opengl 绘制立方体 3D

    我想使用 OpenGL 绘制 3D 立方体这是我的代码如何纠正错误 float ver 8 3 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
  • (定义一个宏)方便OpenGL命令调试?

    有时插入条件打印和检查需要很长时间glGetError 使用二分搜索的形式来缩小范围 其中第一个函数调用是 OpenGL 首先报告错误 我认为如果有一种方法可以构建一个宏 我可以包装所有可能失败的 GL 调用 并有条件地调用 那就太酷了gl
  • 如何有效地对一个数组中某个值在另一个数组中的位置出现的次数求和

    我正在寻找一种有效的 for 循环 避免解决方案来解决我遇到的数组相关问题 我想使用一个巨大的一维数组 A gt size 250 000 用于一维索引的 0 到 40 之间的值 以及用于第二维索引的具有 0 到 9995 之间的值的相同大
  • 法线在 openGL 中表现得很奇怪

    我一直在为 openGl 编写一个 obj 加载器 几何体加载得很好 但法线总是混乱的 我尝试在两个不同的程序中导出模型 但似乎没有任何效果 据我所知 这就是将法线放入 GL TRIANGLES 的方法 glNormal3fv norm1

随机推荐

  • 在单个 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 等 而是自己设置模型视图投影矩阵并在我的顶点着色器中使用它 正交投影就足够