我受 XNA/MonoGame 界面的启发,正在 OpenGL 中制作一个 2D 批处理渲染器,但我遇到了一个小设计问题,我正在寻找一些输入。目前,您可以通过四种通用方式提交顶点数据:
void Render(const Sprite& sprite);
void Render(const Shape& shape);
void Render(const Vertex* vertices, unsigned int length);
void Render(const Vertex* vertices, unsigned int length, const Texture* texture);
一个 Sprite 包含四个顶点、颜色和纹理坐标,而其他三个可以包含任意数字( Sprite 和形状具有独特的变换)。一切都可以是有纹理的或无纹理的。我想对所有内容进行批处理以减少状态更改和 OpenGL 绘制调用的次数。我觉得假设大多数提交都将共享顶点是合理的,这样我就可以使用 glDrawElements 而不是 glDrawArrays,但是根据我上面的描述,我很难弄清楚如何正确地批处理事情。
XNA/MonoGame sprite 批处理程序之所以有效,是因为它们只处理带纹理的四边形/三角形,而不是任意形状。或者,我可以像 SFML 渲染器那样为每个可绘制对象发出绘制调用,但这违背了批量渲染的目的。
我觉得我的渲染器正在尝试“做所有事情”,这是我想避免的事情,因为根据我的经验,它通常很快就会变得过于复杂。
我要问的是:如何重新设计我的渲染器?我可以为不同的提交保留单独的批处理列表吗?我能以某种方式模块化我的渲染器吗?我是否应该像在 XNA/MonoGame 中那样只允许有纹理的对象?
最佳答案
好的,所以我们需要尽量减少状态更改和绘制调用的次数。我假设您使用的是现代 OpenGL,包括 Vertex Buffer Objects和着色器。
一种方法是确保所有顶点数据具有相同的格式。例如,每个顶点都有一个位置、颜色和纹理坐标(xyz、rgba、uv)。如果我们在 VBO 中交错我们的顶点数据,我们只需要在渲染之前调用一次 glVertexAttribPointer 和 glEnableVertexAttribArray。
这意味着无纹理对象的一些冗余数据,但我们可以将所有内容塞进一个批处理中,这很好。
要处理无纹理对象,您可以绑定(bind)一个空白的白色纹理并将其视为带纹理的对象。或者,您可以在片段着色器中使用统一变量(0 和 1 之间的 float ),并使用 mix 在纹理颜色和顶点颜色之间进行混合。功能。
要批处理 Sprite 和形状,我们应该首先在 CPU 上处理转换,以便我们始终将“世界”坐标上传到 GPU。这使我们不必为每个 Sprite 设置变换制服,而每个 Sprite 都需要单独的绘制调用。
此外,我们需要尽可能按纹理排序,因为纹理绑定(bind)是您可以执行的更昂贵的操作之一。
我们的方法基本上归结为以下几点:
可以通过不同的方式将数据从 CPU 获取到 GPU 内存。例如,首先在 GPU 上分配一个足够大的空内存缓冲区,然后使用 glBufferSubData上传顶点/索引数据的一个子集,每当你进行一个渲染调用时。
在做这种工作的时候做profiling是非常重要的。例如,比较批处理和单个绘制调用之间的性能,或者 glDrawArrays 与 glDrawElements。我建议使用 gDebugger ,这是一个免费且非常好的 OpenGL 分析器。
另请注意,太大的 VBO 可以 hurt your performance .因此,请将其保持在合理的大小,并在其填满时通过绘制调用将其刷新。
关于c++ - 在 OpenGL 批处理渲染器中批处理任意顶点数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18100953/
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这
有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳
我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
如何将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.你能做的最好的事情是: