草庐IT

c++ - 反转 y 轴,并在 OpenGL 中设置坐标系

coder 2023-11-16 原文

在 OpenGL 中,我试图反转 y 轴,并设置特定类型的坐标系,就像 Allegro 的方式一样。假设我的窗口是 640x480,我希望屏幕的左上角是轴 (0, 0),右下角是 (640, 480)。到目前为止,我设法得到了我想要的正确坐标系,但我不知道它是否以正确的方式完成。至于翻转 y 轴,我无法在不修改当前坐标系的情况下将其反转。我不想要一些骇人听闻的东西,只是为了翻转 1 个形状。我希望它在保持坐标系的同时翻转我在 y 轴上制作的所有 future 形状。这是我目前所拥有的。

初始化:

const GLdouble XSize = 640, YSize = 480;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, XSize, YSize, 0, 1, 1000);
glMatrixMode(GL_MODELVIEW);

渲染:

float size = 30;

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0, 0, -500);

glPushMatrix();
glTranslatef(size, size, 0.0f);

glBegin(GL_TRIANGLES);
glColor3f(0.1, 0.3, 0.8);
glVertex3f( 0.0f, size, 0.0f);
glVertex3f(-size,-size, 0.0f);
glVertex3f( size,-size, 0.0f);
glEnd();
glPopMatrix();

编辑:

我发现添加 glScalef(1, -1, 1); 会翻转我的形状,但我必须将它包含在我的形状的 glPushMatrix() 中,我不知道这是否是正确的方法,或者它是否是一个 hackish 解决方案。

最佳答案

要更改坐标系,按顺序需要缩放和平移。

// Initialize OpenGL matrices
void init_gl() {
    const float WIDTH = 640.0f;
    const float HEIGHT = 480.0f;

    const float HALF_WIDTH = WIDTH / 2.0f;
    const float HALF_HEIGHT = HEIGHT / 2.0f;

    // Setup the projection matrix
    glMatrixMode(GL_PROECTION);
    glLoadIDentity();
    glOrtho(0, WIDTH, HEIGHT, 0.0f, 0.0f, 1000.0f);

    // Setup the Allegro-to-view matrix
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(-HALF_WIDTH, HALF_HEIGHT, 0.0f);
    glScalef(1.0f, -1.0f, 1.0f);
}

// Render scene
void render() {
    // Now render using points in Allegro coordinates
    const float size = 30.0f;
    glBegin(GL_TRIANGLES);
    glColor3f(0.1f, 0.3f, 0.8f);
    glVertex3f( 0.0f,  size, 0.0f);
    glVertex3f(-size, -size, 0.0f);
    glVertex3f( size, -size, 0.0f);
    glEnd();
}

请注意 glTranslatef 出现在 glScalef 之前,因为变换矩阵在当前矩阵值的右侧相乘。此外,您不必为每帧设置 Allegro-to-view 矩阵;对于大多数用例,初始化期间一次就足够了。但是,您可以按下 GL_MODELVIEW 并应用任何必要的模型转换。


这是对其工作原理的概念分析。目标是允许图形程序员使用“Allegro”或所需坐标指定点,即原点位于正交投影左上角的坐标(在本例中,这直接与屏幕相关)。为此,您设置 View 矩阵 GL_MODELVIEW 以将这些所需坐标转换为正交相机坐标(也称为 View 空间或眼睛空间)。

首先,您重新定向(缩放)所需坐标的 y 轴以匹配 View 坐标(中图)。其次,平移所需坐标的原点以匹配 View 坐标的原点。这种转换是相对于 View 坐标进行的(即 View 坐标的原点是水平向右的一半屏幕和垂直向下的一半屏幕)。这最后一步相当于在移动的相反方向上转换点。

象征性地,尺度将点 P = (P.x, P.y) 转换为 P' = (P.x, -P.y)。 translate 将点 P' 转换为 P'' = (P.x - w/2, P.y + h/2) 其中 w 是屏幕宽度 (480px),h 是高度 (640px)。 (抱歉,最终图表错误地将 hw 切换为 P'' 因为我不能很好地绘制图表)。

请注意,z 轴指向屏幕外,因为我们没有按 -1 缩放它。

我更喜欢概念化坐标系变化的方式(更准确地说,当我们包含原点概念时,框架的变化)是我们正在修改基 vector (x,y,等)和原点以及随后的缩放、旋转和平移操作(按此顺序)。这与我们通过在相机移动的相反方向应用平移来概念化移动相机的方式非常相似。

关于c++ - 反转 y 轴,并在 OpenGL 中设置坐标系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5984260/

有关c++ - 反转 y 轴,并在 OpenGL 中设置坐标系的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  3. ruby-on-rails - 如何在 Rails 中设置路由的默认格式? - 2

    路由有如下代码:resources:orders,only:[:create],defaults:{format:'json'}resources:users,only:[:create,:update],defaults:{format:'json'}resources:delivery_types,only:[:index],defaults:{format:'json'}resources:time_corrections,only:[:index],defaults:{format:'json'}是否可以使用1个字符串为所有资源设置默认格式,每行不带“默认值”散列?谢谢。

  4. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  5. ruby-on-rails - environment.rb 中设置的常量在开发模式中消失 - 2

    了解Rails缓存如何工作的人可以真正帮助我。这是嵌套在Rails::Initializer.runblock中的代码:config.after_initializedoSomeClass.const_set'SOME_CONST','SOME_VAL'end现在,如果我运行script/server并发出请求,一切都很好。然而,在我的Rails应用程序的第二个请求中,一切都因单元化常量错误而变得糟糕。在生产模式下,我可以成功发出第二个请求,这意味着常量仍然存在。我已通过将以上内容更改为以下内容来解决问题:config.after_initializedorequire'some_cl

  6. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

  7. += 的 Ruby 方法 - 2

    有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=

  8. ruby - Sinatra + Heroku + Datamapper 使用 dm-sqlite-adapter 部署问题 - 2

    出于某种原因,heroku尝试要求dm-sqlite-adapter,即使它应该在这里使用Postgres。请注意,这发生在我打开任何URL时-而不是在gitpush本身期间。我构建了一个默认的Facebook应用程序。gem文件:source:gemcuttergem"foreman"gem"sinatra"gem"mogli"gem"json"gem"httparty"gem"thin"gem"data_mapper"gem"heroku"group:productiondogem"pg"gem"dm-postgres-adapter"endgroup:development,:t

  9. ruby-on-rails - 如何在回形针 ruby​​ on rails 中设置默认图像 - 2

    最近我安装了Paperclipgem,我正在努力让默认图像在我的系统上工作,我将图像文件放在assets/images/pic.png中。这是我的模型User中的代码:has_attached_file:pic,:styles=>{:medium=>"300x300>",:thumb=>"100x100>"},:default_url=>'missing_:avatar.png'#:default_url=>'assets/images/avatar.png'has_attached_file:attach这是我的AddPicPaperClip迁移中的代码:defself.upadd_

  10. ruby-on-rails - Rails 中的类实例变量应该在互斥体中设置吗? - 2

    假设我的Rails项目中有一个设置实例变量的Ruby类。classSomethingdefself.objects@objects||=begin#somelogicthatbuildsanarray,whichisultimatelystoredin@objectsendendend是否可以多次设置@objects?是否有可能在一个请求期间,在上面的begin/end之间执行代码时,可以在第二个请求期间调用此方法?我想这实际上归结为Rails服务器实例如何fork的问题。我应该改用Mutex还是线程同步?例如:classSomethingdefself.objectsreturn@o

随机推荐