• Advertisement
  • Popular Tags

  • Popular Now

  • Advertisement
  • Similar Content

    • By Ty Typhoon
      Before read everything i am honest:
      Payment after release you get your percentage lifetime for that project.
       
      Second:
      i dont need your inspirations, ideas, music or designs.
      My head is full with that.
      I need workers who i can trust.
       
       
       
      Please let us talk in discord.
      I got a lot of stuff planned, there is much work to do.
       
      But first my team and me try to start with a small mini game and we need maybe exactly you.
      Planned for more than pc, like ps4, xbox one and mobile - so its very important to us to hopefully welcome a programmer.
       
      The mini game will be part of the planned big game. There will be never before seen guns and gameplay, you will get deeper info if youre a safe part of the team.
       
      I need:
      Programmers
      Animators
      Zbrush pros
       
      Join here please:
      https://discord.gg/YtjE3sV
       
      You find me here:
      Joerg Federmann Composing#2898
       
       
    • By tj8146
      I am using immediate mode for OpenGL and I am creating a 2D top down car game. I am trying to configure my game loop in order to get my car-like physics working on a square shape. I have working code but it is not doing as I want it to. I am not sure as to whether it is my game loop that is incorrect or my code for the square is incorrect, or maybe both! Could someone help because I have been trying to work this out for over a day now
      I have attached my .cpp file if you wish to run it for yourself.. 
      WinMain code:
      /******************* WIN32 FUNCTIONS ***************************/ int WINAPI WinMain( HINSTANCE hInstance, // Instance HINSTANCE hPrevInstance, // Previous Instance LPSTR lpCmdLine, // Command Line Parameters int nCmdShow) // Window Show State { MSG msg; // Windows Message Structure bool done=false; // Bool Variable To Exit Loop Car car; car.x = 220; car.y = 140; car.dx = 0; car.dy = 0; car.ang = 0; AllocConsole(); FILE *stream; freopen_s(&stream, "CONOUT$", "w", stdout); // Create Our OpenGL Window if (!CreateGLWindow("OpenGL Win32 Example",screenWidth,screenHeight)) { return 0; // Quit If Window Was Not Created } while(!done) // Loop That Runs While done=FALSE { if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Is There A Message Waiting? { if (msg.message==WM_QUIT) // Have We Received A Quit Message? { done=true; // If So done=TRUE break; } else // If Not, Deal With Window Messages { TranslateMessage(&msg); // Translate The Message DispatchMessage(&msg); // Dispatch The Message } } else // If There Are No Messages { if(keys[VK_ESCAPE]) done = true; void processKeys(Car& car); //process keyboard while (game_is_running) { loops = 0; while (GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP) { update(car); // update variables next_game_tick += SKIP_TICKS; loops++; } display(car); // Draw The Scene SwapBuffers(hDC); // Swap Buffers (Double Buffering) } } } // Shutdown KillGLWindow(); // Kill The Window return (int)(msg.wParam); // Exit The Program } //WIN32 Processes function - useful for responding to user inputs or other events. LRESULT CALLBACK WndProc( HWND hWnd, // Handle For This Window UINT uMsg, // Message For This Window WPARAM wParam, // Additional Message Information LPARAM lParam) // Additional Message Information { switch (uMsg) // Check For Windows Messages { case WM_CLOSE: // Did We Receive A Close Message? { PostQuitMessage(0); // Send A Quit Message return 0; // Jump Back } break; case WM_SIZE: // Resize The OpenGL Window { reshape(LOWORD(lParam),HIWORD(lParam)); // LoWord=Width, HiWord=Height return 0; // Jump Back } break; case WM_LBUTTONDOWN: { mouse_x = LOWORD(lParam); mouse_y = screenHeight - HIWORD(lParam); LeftPressed = true; } break; case WM_LBUTTONUP: { LeftPressed = false; } break; case WM_MOUSEMOVE: { mouse_x = LOWORD(lParam); mouse_y = screenHeight - HIWORD(lParam); } break; case WM_KEYDOWN: // Is A Key Being Held Down? { keys[wParam] = true; // If So, Mark It As TRUE return 0; // Jump Back } break; case WM_KEYUP: // Has A Key Been Released? { keys[wParam] = false; // If So, Mark It As FALSE return 0; // Jump Back } break; } // Pass All Unhandled Messages To DefWindowProc return DefWindowProc(hWnd,uMsg,wParam,lParam); }  
      C++ and OpenGL code:
      int mouse_x=0, mouse_y=0; bool LeftPressed = false; int screenWidth=1080, screenHeight=960; bool keys[256]; float radiansFromDegrees(float deg) { return deg * (M_PI / 180.0f); } float degreesFromRadians(float rad) { return rad / (M_PI / 180.0f); } bool game_is_running = true; const int TICKS_PER_SECOND = 50; const int SKIP_TICKS = 1000 / TICKS_PER_SECOND; const int MAX_FRAMESKIP = 10; DWORD next_game_tick = GetTickCount(); int loops; typedef struct { float x, y; float dx, dy; float ang; }Car; //OPENGL FUNCTION PROTOTYPES void display(const Car& car); //called in winmain to draw everything to the screen void reshape(int width, int height); //called when the window is resized void init(); //called in winmain when the program starts. void processKeys(Car& car); //called in winmain to process keyboard input void update(Car& car); //called in winmain to update variables /************* START OF OPENGL FUNCTIONS ****************/ void display(const Car& car) { const float w = 50.0f; const float h = 50.0f; glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); glTranslatef(100, 100, 0); glBegin(GL_POLYGON); glVertex2f(car.x, car.y); glVertex2f(car.x + w, car.y); glVertex2f(car.x + w, car.y + h); glVertex2f(car.x, car.y + h); glEnd(); glFlush(); } void reshape(int width, int height) // Resize the OpenGL window { screenWidth = width; screenHeight = height; // to ensure the mouse coordinates match // we will use these values to set the coordinate system glViewport(0, 0, width, height); // Reset the current viewport glMatrixMode(GL_PROJECTION); // select the projection matrix stack glLoadIdentity(); // reset the top of the projection matrix to an identity matrix gluOrtho2D(0, screenWidth, 0, screenHeight); // set the coordinate system for the window glMatrixMode(GL_MODELVIEW); // Select the modelview matrix stack glLoadIdentity(); // Reset the top of the modelview matrix to an identity matrix } void init() { glClearColor(1.0, 1.0, 0.0, 0.0); //sets the clear colour to yellow //glClear(GL_COLOR_BUFFER_BIT) in the display function //will clear the buffer to this colour. } void processKeys(Car& car) { if (keys[VK_UP]) { float cdx = sinf(radiansFromDegrees(car.ang)); float cdy = -cosf(radiansFromDegrees(car.ang)); car.dx += cdx; car.dy += cdy; } if (keys[VK_DOWN]) { float cdx = sinf(radiansFromDegrees(car.ang)); float cdy = -cosf(radiansFromDegrees(car.ang)); car.dx += -cdx; car.dy += -cdy; } if (keys[VK_LEFT]) { car.ang -= 2; } if (keys[VK_RIGHT]) { car.ang += 2; } } void update(Car& car) { car.x += car.dx*next_game_tick; }  
      game.cpp
    • By tj8146
      I am using immediate mode for OpenGL and I am creating a 2D top down car game. I am trying to configure my game loop in order to get my car-like physics working on a square shape. I have working code but it is not doing as I want it to. I am not sure as to whether it is my game loop that is incorrect or my code for the square is incorrect, or maybe both! Could someone help because I have been trying to work this out for over a day now
      I have attached my .cpp file if you wish to run it for yourself.. 
       
      This is my C++ and OpenGL code:
      int mouse_x=0, mouse_y=0; bool LeftPressed = false; int screenWidth=1080, screenHeight=960; bool keys[256]; float radiansFromDegrees(float deg) { return deg * (M_PI / 180.0f); } float degreesFromRadians(float rad) { return rad / (M_PI / 180.0f); } bool game_is_running = true; const int TICKS_PER_SECOND = 50; const int SKIP_TICKS = 1000 / TICKS_PER_SECOND; const int MAX_FRAMESKIP = 10; DWORD next_game_tick = GetTickCount(); int loops; typedef struct { float x, y; float dx, dy; float ang; }Car; //OPENGL FUNCTION PROTOTYPES void display(const Car& car); //called in winmain to draw everything to the screen void reshape(int width, int height); //called when the window is resized void init(); //called in winmain when the program starts. void processKeys(Car& car); //called in winmain to process keyboard input void update(Car& car); //called in winmain to update variables /************* START OF OPENGL FUNCTIONS ****************/ void display(const Car& car) { const float w = 50.0f; const float h = 50.0f; glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); glTranslatef(100, 100, 0); glBegin(GL_POLYGON); glVertex2f(car.x, car.y); glVertex2f(car.x + w, car.y); glVertex2f(car.x + w, car.y + h); glVertex2f(car.x, car.y + h); glEnd(); glFlush(); } void reshape(int width, int height) // Resize the OpenGL window { screenWidth = width; screenHeight = height; // to ensure the mouse coordinates match // we will use these values to set the coordinate system glViewport(0, 0, width, height); // Reset the current viewport glMatrixMode(GL_PROJECTION); // select the projection matrix stack glLoadIdentity(); // reset the top of the projection matrix to an identity matrix gluOrtho2D(0, screenWidth, 0, screenHeight); // set the coordinate system for the window glMatrixMode(GL_MODELVIEW); // Select the modelview matrix stack glLoadIdentity(); // Reset the top of the modelview matrix to an identity matrix } void init() { glClearColor(1.0, 1.0, 0.0, 0.0); //sets the clear colour to yellow //glClear(GL_COLOR_BUFFER_BIT) in the display function //will clear the buffer to this colour. } void processKeys(Car& car) { if (keys[VK_UP]) { float cdx = sinf(radiansFromDegrees(car.ang)); float cdy = -cosf(radiansFromDegrees(car.ang)); car.dx += cdx; car.dy += cdy; } if (keys[VK_DOWN]) { float cdx = sinf(radiansFromDegrees(car.ang)); float cdy = -cosf(radiansFromDegrees(car.ang)); car.dx += -cdx; car.dy += -cdy; } if (keys[VK_LEFT]) { car.ang -= 2; } if (keys[VK_RIGHT]) { car.ang += 2; } } void update(Car& car) { car.x += car.dx*next_game_tick; } My WinMain code:
      /******************* WIN32 FUNCTIONS ***************************/ int WINAPI WinMain( HINSTANCE hInstance, // Instance HINSTANCE hPrevInstance, // Previous Instance LPSTR lpCmdLine, // Command Line Parameters int nCmdShow) // Window Show State { MSG msg; // Windows Message Structure bool done=false; // Bool Variable To Exit Loop Car car; car.x = 220; car.y = 140; car.dx = 0; car.dy = 0; car.ang = 0; AllocConsole(); FILE *stream; freopen_s(&stream, "CONOUT$", "w", stdout); // Create Our OpenGL Window if (!CreateGLWindow("OpenGL Win32 Example",screenWidth,screenHeight)) { return 0; // Quit If Window Was Not Created } while(!done) // Loop That Runs While done=FALSE { if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Is There A Message Waiting? { if (msg.message==WM_QUIT) // Have We Received A Quit Message? { done=true; // If So done=TRUE break; } else // If Not, Deal With Window Messages { TranslateMessage(&msg); // Translate The Message DispatchMessage(&msg); // Dispatch The Message } } else // If There Are No Messages { if(keys[VK_ESCAPE]) done = true; void processKeys(Car& car); //process keyboard while (game_is_running) { loops = 0; while (GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP) { update(car); // update variables next_game_tick += SKIP_TICKS; loops++; } display(car); // Draw The Scene SwapBuffers(hDC); // Swap Buffers (Double Buffering) } } } // Shutdown KillGLWindow(); // Kill The Window return (int)(msg.wParam); // Exit The Program } //WIN32 Processes function - useful for responding to user inputs or other events. LRESULT CALLBACK WndProc( HWND hWnd, // Handle For This Window UINT uMsg, // Message For This Window WPARAM wParam, // Additional Message Information LPARAM lParam) // Additional Message Information { switch (uMsg) // Check For Windows Messages { case WM_CLOSE: // Did We Receive A Close Message? { PostQuitMessage(0); // Send A Quit Message return 0; // Jump Back } break; case WM_SIZE: // Resize The OpenGL Window { reshape(LOWORD(lParam),HIWORD(lParam)); // LoWord=Width, HiWord=Height return 0; // Jump Back } break; case WM_LBUTTONDOWN: { mouse_x = LOWORD(lParam); mouse_y = screenHeight - HIWORD(lParam); LeftPressed = true; } break; case WM_LBUTTONUP: { LeftPressed = false; } break; case WM_MOUSEMOVE: { mouse_x = LOWORD(lParam); mouse_y = screenHeight - HIWORD(lParam); } break; case WM_KEYDOWN: // Is A Key Being Held Down? { keys[wParam] = true; // If So, Mark It As TRUE return 0; // Jump Back } break; case WM_KEYUP: // Has A Key Been Released? { keys[wParam] = false; // If So, Mark It As FALSE return 0; // Jump Back } break; } // Pass All Unhandled Messages To DefWindowProc return DefWindowProc(hWnd,uMsg,wParam,lParam); }  
      game.cpp
    • By khawk
      LunarG has released new Vulkan SDKs for Windows, Linux, and macOS based on the 1.1.73 header. The new SDK includes:
      New extensions: VK_ANDROID_external_memory_android_hardware_buffer VK_EXT_descriptor_indexing VK_AMD_shader_core_properties VK_NV_shader_subgroup_partitioned Many bug fixes, increased validation coverage and accuracy improvements, and feature additions Developers can download the SDK from LunarXchange at https://vulkan.lunarg.com/sdk/home.

      View full story
    • By khawk
      LunarG has released new Vulkan SDKs for Windows, Linux, and macOS based on the 1.1.73 header. The new SDK includes:
      New extensions: VK_ANDROID_external_memory_android_hardware_buffer VK_EXT_descriptor_indexing VK_AMD_shader_core_properties VK_NV_shader_subgroup_partitioned Many bug fixes, increased validation coverage and accuracy improvements, and feature additions Developers can download the SDK from LunarXchange at https://vulkan.lunarg.com/sdk/home.
  • Advertisement
  • Advertisement

Vulkan Remove secondary buffer Vulkan / other ways to remove objects

Recommended Posts

Hey guys. Vulkan newbie from OpenGL here. Is there a way to remove a secondary buffer from a primary buffer in Vulkan? If not, how else can I remove objects? I'm binding my primary buffer to:

Bind RenderPass

Draw Related Secondary Command Buffers

End RenderPass

 

And my secondary buffers to:

Bind Graphics Pipeline

Bind Vertex Buffer

Bind Index Buffer

Bind Descriptors

Draw Indexed

 

The only other way I can guess to have objects be removeable is to have one command buffer per object and add them all to submitInfo.pCommandBuffers, but then I'll be rebinding the renderpass a lot, plus I figure it's more work for the GPU. Also, how would object removal be handled with indirect draws, as I'm planning on looking into that relatively soon?

 

EDIT: One more question, is there a way to bind one descriptor set (for the projection, view, model, and combination matrices) to multiple graphics pipelines? And is there a way to bind graphics pipelines to multiple secondary command buffers?

Edited by KarimIO

Share this post


Link to post
Share on other sites
Advertisement

If the number of draw calls changes, its best just to re-record the command buffer.  Recording command buffers in Vulkan is not an overly expensive operation, you can create dozens per frame.  Creating pipelines, renderpasses, etc... they can be slow, but the command buffers themselves are designed to be recreated each frame.  That's not to say you shouldn't re-use them where it makes sense, but you should not be splitting renderpasses up.

If you really want to do the 'only create command buffers once' approach, then the best option is to record the command buffer using vkCmdDrawIndirect().  Then each frame all you have to do is update the indirect buffer which stores all the actual draw commands.  That way you can change the number of objects without re-recording the command buffer and you also don't need lots of little command buffers, a few large will usually suffice. 

Share this post


Link to post
Share on other sites
11 minutes ago, Ryan_001 said:

If the number of draw calls changes, its best just to re-record the command buffer.  Recording command buffers in Vulkan is not an overly expensive operation, you can create dozens per frame.  Creating pipelines, renderpasses, etc... they can be slow, but the command buffers themselves are designed to be recreated each frame.  That's not to say you shouldn't re-use them where it makes sense, but you should not be splitting renderpasses up.

If you really want to do the 'only create command buffers once' approach, then the best option is to record the command buffer using vkCmdDrawIndirect().  Then each frame all you have to do is update the indirect buffer which stores all the actual draw commands.  That way you can change the number of objects without re-recording the command buffer and you also don't need lots of little command buffers, a few large will usually suffice. 

Thank you very much! That makes a lot of sense.

How, though, would I bind a graphics pipeline and descriptor set for multiple command buffers? 

Share this post


Link to post
Share on other sites
1 hour ago, KarimIO said:

Thank you very much! That makes a lot of sense.

How, though, would I bind a graphics pipeline and descriptor set for multiple command buffers? 

Yes :)

You are supposed to reuse graphics pipelines and descriptor sets in multiple command buffers.  In fact the design of pipelines was that the slow/computationally expensive portion of command buffer creation was moved to pipelines so that they only have to be created once and can be reused.

Share this post


Link to post
Share on other sites
1 minute ago, Ryan_001 said:

Yes :)

You are supposed to reuse graphics pipelines and descriptor sets in multiple command buffers.  In fact the design of pipelines was that the slow/computationally expensive portion of command buffer creation was moved to pipelines so that they only have to be created once and can be reused.

Yes, but what I mean is that, is there a way to bind one graphics pipeline once for some command buffers, and then bind another one once for others. Right now I'm just binding it for every single model (and therefore every single command buffer).

Share this post


Link to post
Share on other sites

 Its hard to say exactly what you 'should' and 'should not' do.  I'm hardly an expert, the spec is still rather new, drivers are still new, and there is quite a diverse amount of hardware out there.  That said I feel you are making the command buffers far too small.  One command buffer per object sounds like a sub-optimal approach.  I would personally attempt to place more objects in a command buffer; but I can't say for certain how/what you should exactly do, given how little I know about what you are attempting.

To answer your question binding a single pipeline to multiple command buffers isn't possible.  The only state that transfers between command buffers is from primary to secondary through VkCommandBufferInheritanceInfo.  So that list only includes (at this time) renderpass/subpass, framebuffer, query/pipeline stuff.

The spec states:

Quote

Each command buffer manages state independently of other command buffers. There is no inheritance of state across primary and secondary command buffers, or between secondary command buffers. When a command buffer begins recording, all state in that command buffer is undefined. When secondary command buffer(s) are recorded to execute on a primary command buffer, the secondary command buffer inherits no state from the primary command buffer, and all state of the primary command buffer is undefined after an execute secondary command buffer command is recorded. There is one exception to this rule - if the primary command buffer is inside a render pass instance, then the render pass and subpass state is not disturbed by executing secondary command buffers. Whenever the state of a command buffer is undefined, the application must set all relevant state on the command buffer before any state dependent commands such as draws and dispatches are recorded, otherwise the behavior of executing that command buffer is undefined.

Pipeline's are part of that state.

Share this post


Link to post
Share on other sites
3 minutes ago, Ryan_001 said:

 Its hard to say exactly what you 'should' and 'should not' do.  I'm hardly an expert, the spec is still rather new, drivers are still new, and there is quite a diverse amount of hardware out there.  That said I feel you are making the command buffers far too small.  One command buffer per object sounds like a sub-optimal approach.  I would personally attempt to place more objects in a command buffer; but I can't say for certain how/what you should exactly do, given how little I know about what you are attempting.

To answer your question binding a single pipeline to multiple command buffers isn't possible.  The only state that transfers between command buffers is from primary to secondary through VkCommandBufferInheritanceInfo.  So that list only includes (at this time) renderpass/subpass, framebuffer, query/pipeline stuff.

The spec states:

Pipeline's are part of that state.

I'm mostly asking about best practices. I know every application is unique but there's still stuff that's a good guideline.

Well in that case would it make sense for one secondary command buffer per graphics pipeline? I'd have to recreate it more often but it would be larger and therefore faster, I suppose. 

Thanks! 

Share this post


Link to post
Share on other sites

I don't know how fast/slow binding pipelines in, compared to drawing.  There's going to be some sweet spot obviously where you want at least X amount of GPU work per pipeline bind command, but I don't know what it would be.  Not only would it change for pretty much every single hardware/driver configuration.  The best bet it to pick something and try it.  Its not what I would want to hear (you don't want to change your rendering architecture 'after the fact'), but understand that any advice I give you at this point is just a guess and nothing more.

If I were making a game, say a 1st/3rd person shooter or MMO, where there were a few dozen characters/enemies on screen at once.  I'd probably put each character in a single secondary command buffer.  Since each character consists not only of the base model but multiple items of gear, weaponry, armor, etc... and would probably have unique textures (ie. their own descriptor set).  So in this scenario where each character is very different (even two of identical base models might have different skins/items) then each would get a secondary command buffer.

If I were making a game like an RTS, simulation game, where you have many objects but each one is near identical (with just minor variations of color/texture).  I'd have a few large command buffers, and focus more on using draw indirect or something similar.

The real problem I find, is how you plan on updating the buffer data.  The two main methods of transferring small amounts of data are push constants and VkCmdUpdateBuffer().  Since these are recorded into the command buffer, it almost necessitates a new command buffer be recorded every frame.  The other option, of course, is to use map/unmap with a staging buffer, but this still requires a command buffer to be created to copy the data from the staging buffer to its final buffer.  So either way you're creating a new command buffer (or 3) every frame.

In the end I don't think it makes much of a difference.  Command buffer creation in Vulkan is much faster than OpenGL (due to pipelines and descriptor sets) and easy to multithread.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Advertisement