I have a list of vertices that I plan to mutate and was hoping to get a little clarification on the differences among a VBO, display list, & VA -- I am trying to speed up the rendering within my application. Are VBOs and Display lists not options because I am not rendering static geometry?
Well, using anything other than VBOs (i.e., client-side memory pointers and/or display lists) isn't an option in Core contexts.
For dynamic data you can specify GL_STREAM_DRAW/GL_DYNAMIC_DRAW in your glBufferData() call's usage parameter and hope your GL implementation gets the hint.
Related
I have several questions about the Display Lists in OpenGL SC 1.0.1:
if I understand well, a display list saves a sequence of OpenGL primitives commands, to be reused after at runtime.
Now, let's say that I also include in this Display List an assignment that changes the value of a parameter that was declared out of the static sequence.
-> Would this parameter be updated, during the generation of the Display List, or when this Display List will be called at runtime ?
I use to generate all my Display Lists at initialization of the OpenGL context only.
But, in my application, for several reasons, I do glClear at each cycle at runtime.
-> After a glClear command, do you think that all my Display Lists are deleted ?
Because, by doing so, I notice that my graphical components that are generated through Display Lists are never drawn.
Display lists are created once, at exactly the point when you call glNewList. That list is then repeated verbatim when you call glCallList. I'm not sure what you mean by parameter exactly, but if you mean:
a) a C++ variable, then this will have no effect. The OpenGL calls in a display list are recorded as is. What loop variables etc used to get to that call are not recorded.
b) an OpenGL state variable (for example, a call to enable GL_LIGHTING). This will be recorded (since the display list will capture the call to glEnable).
glClear has no effect on display lists. glClear simply clears the back buffer to black (or colour you set via glClearColor). Obviously once you've cleared all the pixel data, you'll need to redraw it again, so you'll need to set the projection matrix, set the correct transform matrix for your geometry in the display list, and call glCallList again to repeat the list of actions within that list.
Having said all of that, I'd strongly advise steering well clear of display lists, and move to something nicer (e.g. VBO + VAO + GLSL Shaders, or VBO + Fixed Function Pipeline). Display lists have a large number of problems, including:
They are a nightmare for driver maintainers. As a result, graphics card support for them is a little bit of a mixed bag.
Not all GL API methods are valid to be called within a display list. Some methods (such as those that modify the client state - e.g. vertex array bindings) simply do not work in display lists. Others don't work simply because the driver implementors decided to not add support (e.g. NVidia will allow some GL3+ methods to be called within a display list, AMD only allows methods from OpenGL 1.5).
Updating a display list is painfully slow.
Is there any proper way to access the low level OpenGL objects of VTK in order to modify them from a CUDA/OpenCL kernel using the openGL-CUDA/OpenCL interoperability feature?
Specifically, I would want to get the GLuint (or unsigned int) member from vtkOpenGLGPUVolumeRayCastMapper that points to the Opengl 3D Texture object where the dataset is stored, in order to bind it to a CUDA Surface to be able to access and modify its values from a CUDA kernel implemented by me.
For further information, the process that I need to follow is explained here:
http://rauwendaal.net/2011/12/02/writing-to-3d-opengl-textures-in-cuda-4-1-with-3d-surface-writes/
where the texID object used there (in Steps 1 and 2) is the equivalent to what I want to retrieve from VTK.
At a first look at the vtkOpenGLGPUVolumeRayCastMapper functions, I don't find an easy way to do this, rather than maybe creating a vtkGPUVolumeRayCastMapper subclass, but even in that case I am not sure what should I modify exactly, since I guess that some other members depend on the 3D Texture values, and should be also updated after modifying it.
So, do you know some way to do this?
Lots of thanks.
Subclassing might work, but you could probably avoid it if you wanted. The important thing is that you get the order of the GL/CUDA API calls in the right order.
First, you have to register the texture with CUDA. This is done using:
cudaGraphicsGLRegisterImage(&cuda_graphics_resource, texture_handle,
GL_TEXTURE_3D, cudaGraphicsRegisterFlagsSurfaceLoadStore);
with the stipulation that texture_handle is a GLuint written to by a call to glGenTextures(...)
Once you have registered the texture with CUDA, you can create the surface which can be read or written to in your kernel.
The only thing you have to worry about from here is that vtk does not use the texture in between a call to cudaGraphicsMapResources(...) and cudaGraphicsUnmapResources(...). Everything else should just be standard CUDA.
Also once you map the texture to CUDA and write to it within a kernel, there is no additional work besides unmapping the texture. GL will get the modified texture the next time it is used.
I'm writing an application that is composed of multiple (16-32) plots that are updated several times a second and are drawn using openGL. Until now I've down most of the prototyping of the plots with GLUT. However I'd like to adopt a full fledge framework like QT and I'm getting ready to write a test QGLWidget.
Before I get started I'd like to figure out if its possible for multiple QGLWidgets to share a single openGL context? If so is there anything specifics I need to keep track of when sharing an openGL context between widgets?
if its possible for multiple QGLWidgets to share a single openGL context?
Now this is not possible to answer in general, because it depends on the platform in question: On X11/GLX it is indeed possible to use an indirect context on multiple drawables, however the context can be active on only one drawable at a time.
However:
It is also possible (and it is the recommended way to do this) to have multiple contexts share their data. In the very first versions of OpenGL this was only display lists, hence this still called list sharing. But with current versions of OpenGL this also includes textures, Pixel Buffer Objects and Vertex Buffer Objects. Frame Buffer Objects however can not be shared, but since textures can be used as FBO attachments that's no big deal.
QGLWidget provides a straigtforward API to share context data between QGLWidgests' contexts.
Yes, it is possible to share an opengl context by using this constructor.
If so is there anything specifics I need to keep track of when sharing
an openGL context between widgets?
I am not sure, but I don't think there is anything special you need to take care of.
Is it possible to create a display list for Tesselated objects? If so would it be more efficient?
Thanks
Yes -- after tessellation you just have a bunch of triangles, which you can put in a display list about like anything else. Efficiency will depend; on nVidia display lists work quite well, but on ATI a display list is little different from multiple calls to glVertex.
If you want to assure efficiency across both, consider using a vertex buffer object instead of a display list. This is also supported by the newer versions of OpenGL (display lists are deprecated).
Yes. Efficient but deprecated.
I am working on a simple CAD program which uses OpenGL to handle on-screen rendering. Every shape drawn on the screen is constructed entirely out of simple line segments, so even a simple drawing ends up processing thousands of individual lines.
What is the best way to communicate changes in this collection of lines between my application and OpenGL? Is there a way to update only a certain subset of the lines in the OpenGL buffers?
I'm looking for a conceptual answer here. No need to get into the actual source code, just some recommendations on data structure and communication.
You can use a simple approach such as using a display list (glNewList/glEndList)
The other option, which is slightly more complicated, is to use Vertex Buffer Objects (VBOs - GL_ARB_vertex_buffer_object). They have the advantage that they can be changed dynamically whereas a display list can not.
These basically batch all your data/transformations up and them execute on the GPU (assuming you are using hardware acceleration) resulting in higher performance.
Vertex Buffer Objects are probably what you want. Once you load the original data set in, you can make modifications to existing chunks with glBufferSubData().
If you add extra line segments and overflow the size of your buffer, you'll of course have to make a new buffer, but this is no different than having to allocate a new, larger memory chunk in C when something grows.
EDIT: A couple of notes on display lists, and why not to use them:
In OpenGL 3.0, display lists are deprecated, so using them isn't forward-compatible past 3.0 (2.1 implementations will be around for a while, of course, so depending on your target audience this might not be a problem)
Whenever you change anything, you have to rebuild the entire display list, which defeats the entire purpose of display lists if things are changed often.
Not sure if you're already doing this, but it's worth mentioning you should try to use GL_LINE_STRIP instead of individual GL_LINES if possible to reduce the amount of vertex data being sent to the card.
My suggestion is to try using a scene graph, some kind of hierarchical data structure for the lines/curves. If you have huge models, performance will be affected if you have plain list of lines. With a graph/tree structure you can check easily which items are visible and which are not by using bounding volumes. Also with a scenegraph you can apply transformation easily and reuse geometries.