草庐IT

c++ - 管理 OpenGL 状态机的策略

coder 2023-06-03 原文

我目前正在掌握 OpenGL。我从 GLUT 开始,但决定“毕业”到 SFML 库。 SFML 实际上提供的 GL 实用程序比 GLUT 还要少,但它是可移植的并提供了一些其他功能。所以真的只有我,GL和GLU。是的,我很喜欢惩罚。

我想询问人们管理诸如矩阵变化、颜色变化、 Material 变化等事情的策略。

目前我正在按照“裸对象”设计理念从单个线程进行渲染。 IE。每个图形对象都有一个 Render() 函数来完成自己的绘图工作。这些对象本身可能是更多对象的集合,或图形基元的集合。当一个特定的 Render() 被调用时,它没有关于在它之前调用了哪些转换/ Material 更改的信息(当然是一件好事)。

随着事情的发展,我已经确定了某些策略,例如让每个函数 promise 在执行任何转换时推送然后弹出矩阵。使用其他设置,我在调用 glBegin() 之前明确设置了任何需要设置的内容,并且认为没有什么是理所当然的。当一个渲染函数对不太常见的状态变量进行一些更改时,问题就会蔓延,我开始考虑使用一些 RAII 来强制反转作用域中所做的所有状态更改。使用 OpenGL 有时会让我想起很多汇编编程。

为了使这一切都易于管理并帮助调试,我发现我实际上正在开发自己的 openGL 包装器,所以我认为最好听听其他人使用的策略,或者关于该主题的想法和考虑.或者是时候切换到场景图库之类的东西了?

更新:2011 年 13 月 5 日

现在研究了使用顶点/法线/颜色数组和 VBO 进行渲染后,我决定将所有实际的 openGL 通信合并到一个单独的模块中。渲染过程将包括从我的对象中获取与 GL 无关的空间/ Material 数据,然后以可解释的格式将所有这些信息传送到 openGL。这意味着所有原始数组处理和状态操作都将合并到一个区域中。它为渲染过程增加了额外的间接性和一点计算开销,但这意味着我可以对所有数据使用单个 VBO/数组,然后一次将其全部传递给 openGL,每帧一次。

最佳答案

So it's really just me, GL and GLU

我觉得这没什么不好。如果可能的话,我什至会摆脱 GLU。

With other settings, I explicitly set anything that needs setting before calling glBegin() and take nothing for granted.

这也是一个很好的策略,但是您当然应该将昂贵的状态切换保持在最低限度。而不是立即模式 (glBegin/glEnd),您应该迁移到使用顶点数组和可用的顶点缓冲区对象。

Problems creep in when one render function makes some changes to less common state variables, and I am starting to consider using some RAII to enforce the reversal of all state changes made in a scope.

旧版本的 OpenGL 为您提供具有访问功能的属性堆栈 glPushAttrib / glPopAttrib glPushClientAttrib / glPopClientAttrib 为客户状态。

但是,是的,旧 OpenGL 版本的巨大状态空间是精简 OpenGL-3 的主要原因之一;很多固定功能管道状态所涵盖的内容现在通过着色器进行配置和访问,其中每个着色器封装了数十个 OpenGL 状态变量值。

Using OpenGL sometimes reminds me alot of assembly programming.

这一点也不奇怪,因为 OpenGL 的第一个化身是在假设某个抽象机器(实现)的情况下设计的,在该机器上 OpenGL 调用是该机器的操作代码。

关于c++ - 管理 OpenGL 状态机的策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5973147/

有关c++ - 管理 OpenGL 状态机的策略的更多相关文章

  1. ruby - i18n Assets 管理/翻译 UI - 2

    我正在使用i18n从头开始​​构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在ruby​​onrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi

  2. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

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

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

  4. ruby-on-rails - 跳过状态机方法的所有验证 - 2

    当我的预订模型通过rake任务在状态机上转换时,我试图找出如何跳过对ActiveRecord对象的特定实例的验证。我想在reservation.close时跳过所有验证!叫做。希望调用reservation.close!(:validate=>false)之类的东西。仅供引用,我们正在使用https://github.com/pluginaweek/state_machine用于状态机。这是我的预订模型的示例。classReservation["requested","negotiating","approved"])}state_machine:initial=>'requested

  5. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

    我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

  6. ruby - 字符串文字中的转义状态作为 `String#tr` 的参数 - 2

    对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一

  7. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  8. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

    是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

  9. 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.你能做的最好的事情是:

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

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

随机推荐