diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index c1e2bc19..d1ce92ac 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -1,5 +1,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/common) +SET(VULKAN_APP_FRAMEWORK ${CMAKE_CURRENT_SOURCE_DIR}/common/VulkanAppFramework.h) + add_subdirectory(Vulkan) add_subdirectory(2dVector) -add_subdirectory(GUI) \ No newline at end of file +add_subdirectory(GUI) diff --git a/example/Vulkan/CMakeLists.txt b/example/Vulkan/CMakeLists.txt index d23b00ab..7ab6e714 100644 --- a/example/Vulkan/CMakeLists.txt +++ b/example/Vulkan/CMakeLists.txt @@ -1,5 +1,5 @@ macro(CreateProject name) - add_executable(${name} ${ARGN}) + add_executable(${name} ${ARGN} ${VULKAN_APP_FRAMEWORK}) target_link_libraries(${name} ${ULRE}) IF(WIN32) diff --git a/example/Vulkan/DeferredModel.cpp b/example/Vulkan/DeferredModel.cpp index 4ab2458b..ae11c750 100644 --- a/example/Vulkan/DeferredModel.cpp +++ b/example/Vulkan/DeferredModel.cpp @@ -53,7 +53,7 @@ private: struct { RenderTarget *rt; - GPUCmdBuffer *cmd; + RenderCommand *cmd; public: @@ -116,7 +116,7 @@ private: if(!gbuffer.rt)return(false); - gbuffer.cmd=device->CreateCommandBuffer(size_t(GBufferAttachment::RANGE_SIZE)+1); + gbuffer.cmd=device->CreateRenderCommandBuffer(); return(gbuffer.rt); } @@ -298,7 +298,10 @@ private: if(!gbuffer.cmd->BindFramebuffer(gbuffer.rt->GetRenderPass(),gbuffer.rt->GetFramebuffer())) return(false); - render_list.Render(gbuffer.cmd); + if(!gbuffer.cmd->BeginRenderpass()) + return(false); + + render_list.Render(gbuffer.cmd); gbuffer.cmd->EndRenderPass(); gbuffer.cmd->End(); diff --git a/example/Vulkan/Geometry3D.cpp b/example/Vulkan/Geometry3D.cpp index ce33da4b..0356c4ac 100644 --- a/example/Vulkan/Geometry3D.cpp +++ b/example/Vulkan/Geometry3D.cpp @@ -66,19 +66,6 @@ private: render_root.Add(ri,mat); } - bool InitScene() - { - Add(ro_round_rectangle,m2d); - Add(ro_plane_grid[0],m3d); - Add(ro_plane_grid[1],m3d,rotate(HGL_RAD_90,0,1,0)); - Add(ro_plane_grid[2],m3d,rotate(HGL_RAD_90,1,0,0)); - - render_root.RefreshMatrix(); - render_root.ExpendToList(&render_list); - - return(true); - } - void CreateRenderObject() { struct PlaneGridCreateInfo pgci; @@ -121,6 +108,19 @@ private: camera.eye.Set(200,200,200,1.0); } + bool InitScene() + { + Add(ro_round_rectangle,m2d); + Add(ro_plane_grid[0],m3d); + Add(ro_plane_grid[1],m3d,rotate(HGL_RAD_90,0,1,0)); + Add(ro_plane_grid[2],m3d,rotate(HGL_RAD_90,1,0,0)); + + render_root.RefreshMatrix(); + render_root.ExpendToList(&render_list); + + return(true); + } + public: bool Init() diff --git a/example/Vulkan/OffscreenRender.cpp b/example/Vulkan/OffscreenRender.cpp index 164131a6..f6a00c72 100644 --- a/example/Vulkan/OffscreenRender.cpp +++ b/example/Vulkan/OffscreenRender.cpp @@ -22,7 +22,7 @@ class TestApp:public CameraAppFramework struct:public RenderObject { RenderTarget * render_taget =nullptr; - GPUCmdBuffer * command_buffer =nullptr; + RenderCommand * command_buffer =nullptr; Pipeline * pipeline =nullptr; RenderableInstance *renderable_instance =nullptr; @@ -82,7 +82,7 @@ public: os.render_taget=device->CreateRenderTarget(&fbi); if(!os.render_taget)return(false); - os.command_buffer=device->CreateCommandBuffer(fbi.GetAttachmentCount()); + os.command_buffer=device->CreateRenderCommandBuffer(); if(!os.command_buffer)return(false); os.material_instance=db->CreateMaterialInstance(OS_TEXT("res/material/VertexColor2D")); diff --git a/example/common/VulkanAppFramework.h b/example/common/VulkanAppFramework.h index 4d2bf130..0520a511 100644 --- a/example/common/VulkanAppFramework.h +++ b/example/common/VulkanAppFramework.h @@ -53,7 +53,7 @@ protected: int32_t swap_chain_count =0; - GPUCmdBuffer ** cmd_buf =nullptr; + RenderCommand ** cmd_buf =nullptr; Color4f clear_color; @@ -166,23 +166,23 @@ public: { const VkExtent2D extent=sc_render_target->GetExtent(); - cmd_buf=hgl_zero_new(swap_chain_count); + cmd_buf=hgl_zero_new(swap_chain_count); for(int32_t i=0;iCreateCommandBuffer(2); + cmd_buf[i]=device->CreateRenderCommandBuffer(); } } - bool BuildCommandBuffer(GPUCmdBuffer *cb,RenderPass *rp,Framebuffer *fb,RenderableInstance *ri) + bool BuildCommandBuffer(RenderCommand *cb,RenderPass *rp,Framebuffer *fb,RenderableInstance *ri) { if(!ri)return(false); const IndexBuffer *ib=ri->GetIndexBuffer(); - cb->SetClearColor(0,clear_color.r,clear_color.g,clear_color.b); - cb->Begin(); cb->BindFramebuffer(rp,fb); + cb->SetClearColor(0,clear_color.r,clear_color.g,clear_color.b); + cb->BeginRenderpass(); cb->BindPipeline(ri->GetPipeline()); cb->BindDescriptorSets(ri->GetDescriptorSets()); cb->BindVAB(ri); @@ -198,7 +198,7 @@ public: return(true); } - void BuildCommandBuffer(GPUCmdBuffer *cb,RenderTarget *rt,RenderableInstance *ri) + void BuildCommandBuffer(RenderCommand *cb,RenderTarget *rt,RenderableInstance *ri) { if(!cb||!rt||!ri) return; @@ -234,14 +234,14 @@ public: { if(!rl)return; - GPUCmdBuffer *cb=cmd_buf[index]; - - cb->SetClearColor(0,clear_color.r,clear_color.g,clear_color.b); + RenderCommand *cb=cmd_buf[index]; cb->Begin(); - cb->BindFramebuffer(sc_render_target->GetRenderPass(),sc_render_target->GetFramebuffer(index)); - rl->Render(cb); - cb->EndRenderPass(); + cb->BindFramebuffer(sc_render_target->GetRenderPass(),sc_render_target->GetFramebuffer(index)); + cb->SetClearColor(0,clear_color.r,clear_color.g,clear_color.b); + cb->BeginRenderpass(); + rl->Render(cb); + cb->EndRenderPass(); cb->End(); } diff --git a/inc/hgl/graph/RenderList.h b/inc/hgl/graph/RenderList.h index dedc4c94..81fe6e36 100644 --- a/inc/hgl/graph/RenderList.h +++ b/inc/hgl/graph/RenderList.h @@ -11,7 +11,7 @@ namespace hgl { class RenderList { - GPUCmdBuffer *cmd_buf; + RenderCommand *cmd_buf; private: @@ -41,7 +41,7 @@ namespace hgl void Add (SceneNode *node) {if(node)scene_node_list.Add(node);} void Clear () {scene_node_list.ClearData();} - bool Render(GPUCmdBuffer *); + bool Render (RenderCommand *); };//class RenderList }//namespace graph }//namespace hgl diff --git a/inc/hgl/graph/VK.h b/inc/hgl/graph/VK.h index 19f05c17..9d64a353 100644 --- a/inc/hgl/graph/VK.h +++ b/inc/hgl/graph/VK.h @@ -45,6 +45,8 @@ using VAB=VertexAttribBuffer; class IndexBuffer; class GPUCmdBuffer; +class RenderCommand; +class TextureCommand; class RenderPass; class GPUFence; class GPUSemaphore; diff --git a/inc/hgl/graph/VKCommandBuffer.h b/inc/hgl/graph/VKCommandBuffer.h index 70f042fd..27372c06 100644 --- a/inc/hgl/graph/VKCommandBuffer.h +++ b/inc/hgl/graph/VKCommandBuffer.h @@ -9,27 +9,44 @@ VK_NAMESPACE_BEGIN //所以我们将每个对象的独立变换矩阵存在push constant中 class GPUCmdBuffer { +protected: + VkDevice device; VkCommandPool pool; VkCommandBuffer cmd_buf; +public: + + GPUCmdBuffer(VkDevice dev,VkCommandPool cp,VkCommandBuffer cb); + virtual ~GPUCmdBuffer(); + + operator VkCommandBuffer(){return cmd_buf;} + operator const VkCommandBuffer()const{return cmd_buf;} + operator const VkCommandBuffer *()const{return &cmd_buf;} + + bool Begin(); + bool End(){return(vkEndCommandBuffer(cmd_buf)==VK_SUCCESS);} +};//class GPUCmdBuffer + +class RenderCommand:public GPUCmdBuffer +{ uint32_t cv_count; VkClearValue *clear_values; VkRect2D render_area; VkViewport viewport; float default_line_width; - + + Framebuffer *fbo; + RenderPassBeginInfo rp_begin; VkPipelineLayout pipeline_layout; + void SetFBO(Framebuffer *); + public: - GPUCmdBuffer(VkDevice dev,const uint32_t att_count,VkCommandPool cp,VkCommandBuffer cb); - ~GPUCmdBuffer(); - - operator VkCommandBuffer(){return cmd_buf;} - operator const VkCommandBuffer()const{return cmd_buf;} - operator const VkCommandBuffer *()const{return &cmd_buf;} + RenderCommand(VkDevice dev,VkCommandPool cp,VkCommandBuffer cb); + ~RenderCommand(); void SetRenderArea(const VkRect2D &ra){render_area=ra;} void SetRenderArea(const VkExtent2D &); @@ -59,15 +76,10 @@ public: //以上设定在Begin开始后即不可改变 - bool Begin(); - - template void PipelineBarrier (ARGS...args){vkCmdPipelineBarrier (cmd_buf,args...);} - template void CopyBufferToImage (ARGS...args){vkCmdCopyBufferToImage(cmd_buf,args...);} - template void CopyImageToBuffer (ARGS...args){vkCmdCopyImageToBuffer(cmd_buf,args...);} - template void BlitImage (ARGS...args){vkCmdBlitImage (cmd_buf,args...);} - bool BindFramebuffer(RenderPass *rp,Framebuffer *fb); + bool BeginRenderpass(); + bool BindPipeline(Pipeline *p) { if(!p)return(false); @@ -120,7 +132,18 @@ public: //draw void NextSubpass(){vkCmdNextSubpass(cmd_buf,VK_SUBPASS_CONTENTS_INLINE);} void EndRenderPass(){vkCmdEndRenderPass(cmd_buf);} - bool End(){return(vkEndCommandBuffer(cmd_buf)==VK_SUCCESS);} -};//class GPUCmdBuffer +};//class RenderCommand:public GPUCmdBuffer + +class TextureCommand:public GPUCmdBuffer +{ +public: + + using GPUCmdBuffer::GPUCmdBuffer; + + template void PipelineBarrier (ARGS...args){vkCmdPipelineBarrier (cmd_buf,args...);} + template void CopyBufferToImage (ARGS...args){vkCmdCopyBufferToImage(cmd_buf,args...);} + template void CopyImageToBuffer (ARGS...args){vkCmdCopyImageToBuffer(cmd_buf,args...);} + template void BlitImage (ARGS...args){vkCmdBlitImage (cmd_buf,args...);} +};//class TextureCommand:public GPUCmdBuffer VK_NAMESPACE_END #endif//HGL_GRAPH_VULKAN_COMMAND_BUFFER_INCLUDE diff --git a/inc/hgl/graph/VKDevice.h b/inc/hgl/graph/VKDevice.h index 9e7ebc67..c3614a2e 100644 --- a/inc/hgl/graph/VKDevice.h +++ b/inc/hgl/graph/VKDevice.h @@ -31,11 +31,15 @@ class GPUDevice GPUDeviceAttribute *attr; GPUQueue *textureSQ; - GPUCmdBuffer *texture_cmd_buf; + TextureCommand *texture_cmd_buf; Swapchain *swapchain; SwapchainRenderTarget *swapchainRT; +private: + + VkCommandBuffer CreateCommandBuffer(); + bool CreateSwapchainColorTexture(); bool CreateSwapchainDepthTexture(); @@ -180,7 +184,8 @@ public: //shader & material public: //Command GPUBuffer 相关 - GPUCmdBuffer * CreateCommandBuffer(const uint32_t attachment_count); + RenderCommand * CreateRenderCommandBuffer(); + TextureCommand *CreateTextureCommandBuffer(); RenderPass * CreateRenderPass( const List &desc_list, const List &subpass, diff --git a/inc/hgl/graph/VKRenderTarget.h b/inc/hgl/graph/VKRenderTarget.h index 4c295037..31ccf795 100644 --- a/inc/hgl/graph/VKRenderTarget.h +++ b/inc/hgl/graph/VKRenderTarget.h @@ -64,7 +64,7 @@ public: //pipeline public: // command buffer GPUSemaphore * GetRenderCompleteSemaphore (){return render_complete_semaphore;} - virtual bool Submit (GPUCmdBuffer *,GPUSemaphore *present_complete_semaphore=nullptr); + virtual bool Submit (RenderCommand *,GPUSemaphore *present_complete_semaphore=nullptr); };//class RenderTarget /** diff --git a/src/RenderDevice/CMakeLists.txt b/src/RenderDevice/CMakeLists.txt index 40abcb00..d95e665b 100644 --- a/src/RenderDevice/CMakeLists.txt +++ b/src/RenderDevice/CMakeLists.txt @@ -75,7 +75,6 @@ SET(VK_RENDER_PASS_SOURCE ${VK_INCLUDE_PATH}/VKFramebuffer.h ${VK_INCLUDE_PATH}/VKRenderPass.h ${VK_INCLUDE_PATH}/VKRenderTarget.h ${VK_INCLUDE_PATH}/VKSwapchain.h - ${VK_INCLUDE_PATH}/VKCommandBuffer.h ${VK_INCLUDE_PATH}/VKSemaphore.h ${VK_INCLUDE_PATH}/VKFence.h VKQueue.cpp @@ -88,10 +87,16 @@ SET(VK_RENDER_PASS_SOURCE ${VK_INCLUDE_PATH}/VKFramebuffer.h VKRenderTargetPipeline.cpp VKSwapchainRenderTarget.cpp VKSwapchain.cpp - VKCommandBuffer.cpp) + ) SOURCE_GROUP("Render Pass" FILES ${VK_RENDER_PASS_SOURCE}) +SET(VK_CMD_BUFFER_SOURCE ${VK_INCLUDE_PATH}/VKCommandBuffer.h + VKCommandBuffer.cpp + VKCommandBufferRender.cpp) + +SOURCE_GROUP("Command Buffer" FILES ${VK_CMD_BUFFER_SOURCE}) + SET(VK_RENDERABLE_SOURCE ${VK_INCLUDE_PATH}/VKVertexAttributeBinding.h ${VK_INCLUDE_PATH}/VKRenderable.h ${VK_INCLUDE_PATH}/VKRenderableInstance.h @@ -122,5 +127,6 @@ add_cm_library(ULRE.VulkanRender "ULRE" ${VK_RR_SOURCE} ${VK_TEXTURE_SOURCE} ${VK_MATERIAL_SOURCE} ${VK_RENDER_PASS_SOURCE} + ${VK_CMD_BUFFER_SOURCE} ${VK_RENDERABLE_SOURCE} ${VK_RENDER_DEVICE_SOURCE}) diff --git a/src/RenderDevice/VKCommandBuffer.cpp b/src/RenderDevice/VKCommandBuffer.cpp index c5cdb96f..c16e8fbe 100644 --- a/src/RenderDevice/VKCommandBuffer.cpp +++ b/src/RenderDevice/VKCommandBuffer.cpp @@ -1,59 +1,18 @@ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include VK_NAMESPACE_BEGIN -GPUCmdBuffer::GPUCmdBuffer(VkDevice dev,const uint32_t atta_count,VkCommandPool cp,VkCommandBuffer cb) +GPUCmdBuffer::GPUCmdBuffer(VkDevice dev,VkCommandPool cp,VkCommandBuffer cb) { device=dev; pool=cp; cmd_buf=cb; - - cv_count=atta_count; - - if(cv_count>0) - { - clear_values=hgl_zero_new(cv_count); - - clear_values[cv_count-1].depthStencil.depth = 1.0f; - clear_values[cv_count-1].depthStencil.stencil = 0; - } - else - { - clear_values=nullptr; - } - - render_area.offset.x=0; - render_area.offset.y=0; - render_area.extent.width=0; - render_area.extent.height=0; - - default_line_width=1.0; - - pipeline_layout=VK_NULL_HANDLE; } GPUCmdBuffer::~GPUCmdBuffer() { - delete[] clear_values; - vkFreeCommandBuffers(device,pool,1,&cmd_buf); } -void GPUCmdBuffer::SetRenderArea(const VkExtent2D &ext2d) -{ - render_area.offset.x=0; - render_area.offset.y=0; - render_area.extent=ext2d; -} - bool GPUCmdBuffer::Begin() { CommandBufferBeginInfo cmd_buf_info; @@ -65,56 +24,4 @@ bool GPUCmdBuffer::Begin() return(true); } - -bool GPUCmdBuffer::BindFramebuffer(RenderPass *rp,Framebuffer *fb) -{ - RenderPassBeginInfo rp_begin; - - render_area.offset.x=0; - render_area.offset.y=0; - render_area.extent=fb->GetExtent(); - - rp_begin.renderPass = *rp; - rp_begin.framebuffer = *fb; - rp_begin.renderArea = render_area; - rp_begin.clearValueCount = cv_count; - rp_begin.pClearValues = clear_values; - - vkCmdBeginRenderPass(cmd_buf, &rp_begin, VK_SUBPASS_CONTENTS_INLINE); - - viewport.x = 0; - viewport.y = 0; - viewport.minDepth = 0.0f; - viewport.maxDepth = 1.0f; - viewport.width = render_area.extent.width; - viewport.height = render_area.extent.height; - - vkCmdSetViewport(cmd_buf,0,1,&viewport); - vkCmdSetScissor(cmd_buf,0,1,&render_area); - vkCmdSetLineWidth(cmd_buf,default_line_width); - - pipeline_layout=VK_NULL_HANDLE; - - return(true); -} - -bool GPUCmdBuffer::BindVAB(RenderableInstance *ri) -{ - if(!ri) - return(false); - - const uint count=ri->GetBufferCount(); - - if(count<=0) - return(false); - - vkCmdBindVertexBuffers(cmd_buf,0,count,ri->GetBuffer(),ri->GetBufferSize()); - - IndexBuffer *indices_buffer=ri->GetIndexBuffer(); - - if(indices_buffer) - vkCmdBindIndexBuffer(cmd_buf,indices_buffer->GetBuffer(),ri->GetIndexBufferOffset(),VkIndexType(indices_buffer->GetType())); - - return(true); -} VK_NAMESPACE_END diff --git a/src/RenderDevice/VKDevice.cpp b/src/RenderDevice/VKDevice.cpp index 55b75b39..1722dc74 100644 --- a/src/RenderDevice/VKDevice.cpp +++ b/src/RenderDevice/VKDevice.cpp @@ -47,7 +47,7 @@ bool GPUDevice::Resize(const VkExtent2D &extent) if(!CreateSwapchain(extent)) return(false); - texture_cmd_buf=CreateCommandBuffer(0); + texture_cmd_buf=CreateTextureCommandBuffer(); textureSQ=new GPUQueue(this,attr->graphics_queue,1); swapchainRT=new SwapchainRenderTarget(this,swapchain); @@ -55,10 +55,10 @@ bool GPUDevice::Resize(const VkExtent2D &extent) return(true); } -GPUCmdBuffer *GPUDevice::CreateCommandBuffer(const uint32_t attachment_count) +VkCommandBuffer GPUDevice::CreateCommandBuffer() { if(!attr->cmd_pool) - return(nullptr); + return(VK_NULL_HANDLE); CommandBufferAllocateInfo cmd; @@ -71,9 +71,27 @@ GPUCmdBuffer *GPUDevice::CreateCommandBuffer(const uint32_t attachment_count) VkResult res=vkAllocateCommandBuffers(attr->device,&cmd,&cmd_buf); if(res!=VK_SUCCESS) - return(nullptr); + return(VK_NULL_HANDLE); - return(new GPUCmdBuffer(attr->device,attachment_count,attr->cmd_pool,cmd_buf)); + return cmd_buf; +} + +RenderCommand *GPUDevice::CreateRenderCommandBuffer() +{ + VkCommandBuffer cb=CreateCommandBuffer(); + + if(cb==VK_NULL_HANDLE)return(nullptr); + + return(new RenderCommand(attr->device,attr->cmd_pool,cb)); +} + +TextureCommand *GPUDevice::CreateTextureCommandBuffer() +{ + VkCommandBuffer cb=CreateCommandBuffer(); + + if(cb==VK_NULL_HANDLE)return(nullptr); + + return(new TextureCommand(attr->device,attr->cmd_pool,cb)); } /** diff --git a/src/RenderDevice/VKDeviceRenderTarget.cpp b/src/RenderDevice/VKDeviceRenderTarget.cpp index 9267ba5c..6b7b69f0 100644 --- a/src/RenderDevice/VKDeviceRenderTarget.cpp +++ b/src/RenderDevice/VKDeviceRenderTarget.cpp @@ -44,15 +44,10 @@ RenderTarget *GPUDevice::CreateRenderTarget(const FramebufferInfo *fbi,const uin if(fb) { - GPUCmdBuffer *cb=CreateCommandBuffer(fb->GetAttachmentCount()); + RenderTarget *rt=new RenderTarget(this,rp,fb,color_texture_list,color_count,depth_texture,fence_count); - if(cb) - { - RenderTarget *rt=new RenderTarget(this,rp,fb,color_texture_list,color_count,depth_texture,fence_count); - - color_texture_list.DiscardObject(); - return rt; - } + color_texture_list.DiscardObject(); + return rt; } SAFE_CLEAR(depth_texture); diff --git a/src/RenderDevice/VKDeviceTexture.cpp b/src/RenderDevice/VKDeviceTexture.cpp index 4a2297b5..746e4809 100644 --- a/src/RenderDevice/VKDeviceTexture.cpp +++ b/src/RenderDevice/VKDeviceTexture.cpp @@ -50,7 +50,7 @@ namespace } };// - void GenerateMipmaps(GPUCmdBuffer *texture_cmd_buf,VkImage image,VkImageAspectFlags aspect_mask,const int32_t width,const int32_t height,const uint32_t mipLevels) + void GenerateMipmaps(TextureCommand *texture_cmd_buf,VkImage image,VkImageAspectFlags aspect_mask,const int32_t width,const int32_t height,const uint32_t mipLevels) { //VkImage image, VkFormat imageFormat, int32_t texWidth, int32_t texHeight, uint32_t mipLevels) { // Check if image format supports linear blitting diff --git a/src/RenderDevice/VKRenderTarget.cpp b/src/RenderDevice/VKRenderTarget.cpp index db081c70..c3c66e9b 100644 --- a/src/RenderDevice/VKRenderTarget.cpp +++ b/src/RenderDevice/VKRenderTarget.cpp @@ -62,7 +62,7 @@ RenderTarget::~RenderTarget() SAFE_CLEAR(render_pass); } -bool RenderTarget::Submit(GPUCmdBuffer *command_buffer,GPUSemaphore *present_complete_semaphore) +bool RenderTarget::Submit(RenderCommand *command_buffer,GPUSemaphore *present_complete_semaphore) { return this->GPUQueue::Submit(*command_buffer,present_complete_semaphore,render_complete_semaphore); } diff --git a/src/SceneGraph/RenderList.cpp b/src/SceneGraph/RenderList.cpp index 0d7100cb..6f3bd6a7 100644 --- a/src/SceneGraph/RenderList.cpp +++ b/src/SceneGraph/RenderList.cpp @@ -85,7 +85,7 @@ namespace hgl } } - bool RenderList::Render(GPUCmdBuffer *cb) + bool RenderList::Render(RenderCommand *cb) { if(!cb) return(false);