# OpenGL Another multithreading problems with OpenGL

## Recommended Posts

##### Share on other sites
Are you calling glXMakeCurrent, aglSetCurrentContext or the Windows equivalent in a thread before you start issuing drawing commands? Also you can try having multiple contexts and sharing data, a good reference on this (if you're on Mac OS X) is this.

##### Share on other sites
Update:

Uhhh, alright... when reading, it seems that the answer is the call to the wglMakeCurrent. But there is still one thing that bothers me. wglMakeCurrent needs hdc, in which hdc means the handle to the device context. Isn't the hdc is only one: the current and the only window's handle that display my game screen? If I need to make a call of wglMakeCurrent in the new thread, which new "handle" I supposed to pass? Is it the old handle? Or I must create a new window and get it's display context? I don't really understand either how was the wglMakeCurrent related to the Multithreading by reading the MSDN documentation about wglMakeCurrent.

##### Share on other sites
@Abdulla:

I don't really sure what you mean. Are you talking about wglMakeCurrent (glXMakeCurrent in windows) in the Foreground thread or wglMakeCurrent in Background thread?

If you are talking about wglMakeCurrent in foreground thread, absolutely I've already called that. But if it's in background thread, I haven't yet. Because I think that once the context has been already set, all the gl and glu successive calls will used the current context, regardless which thread calls. Is it true, or not?

##### Share on other sites
Another update:

I've read more thoroughly that to use multithread with wglMakeCurrent, I *must* have a rendering context for each thread. But a new rendering context means a new device context, and a new device context means a new window, is it right? I don't really get it...

##### Share on other sites
The following is written w/o knowledge especially of WGL, so there might be something better out there.

The GL context stores the state of GL. Each thread can have its own GL context, allowing the use of GL also in multi-threaded environments.

Making a GL context current defines its use by the calling thread! AFAIK it should be possible to use the same GL context in several threads but it can be made current for at most one thread at a time. So if you want to "share" the context you have to ensure exclusive use, e.g. by protecting the context with a semaphore. This also requires the owning thread to release the context as soon as possible to make it available to other threads.

On invocations of wglMakeCurrent the device context and the render context need not always be the same. However, there are constraints like that the device context supports GL (of course) and has a matching pixel format.

Normally a context sharing is provided for display lists, textures, and buffer objects, but I don't found such a thing in WGL (what doesn't mean there isn't one).

##### Share on other sites
As previous posters said: the OpenGL context is only current for one thread at the time.

The most sensible solution to your problem (I think, since I'm using it [wink]) is to load and decode the texture in the resource thread. Then, give the render thread a signal that there is an image waiting to be uploaded to video memory. The render thread can then look at the list of waiting textures and upload them at the start of each frame.
That way you have the CPU and I/O-intensive stuff in a separate thread, and on-screen textures.

##### Share on other sites

@Haegarr:

but I'll try your valuable advice that stated that the previous thread must release the context before the new thread use it. I didn't know that!

@DaBono:

- If I must call wglMakeCurrent for every frame, doesn't it means that the animation will not run smoothly when the signal is set? because what I render in foreground is not merely a "loading animation", but a full game opening.

##### Share on other sites
In general, the device context defines where the output will be written to, e.g. which window will show the graphics. The render context is OpenGL's collection of all made textures, display lists, VBOs, and so on. It also stores the current depth comparison function, background clear color, whether or not you've currently invoked a glBegin but not a glEnd yet, and much more of those things. In short: It stores the OpenGL rendering state.

Each thread has the possibility to have at most 1 OpenGL context current. When a thread invokes wglMakeCurrent, it binds the overhanded rendering context to the device context, what means that output generated by using the rendering context has to go to the device context. Moreover, the context is set for the thread from which wglMakeCurrent was called. That means that exactly that thread is now using that rendering context. Until the thread releases the context no other thread is allowed to invoke wglMakeCurrent with just that context.

In fact, wglMakeCurrent binds 3 parts together: The device context, the rendering context, and the invoking thread. The latter dependency is of interest in multi-threaded environments only, and is hence often mentioned with less emphasis.

A thread can deal with multiple device contexts. It is also able to deal with several rendering contexts, but only 1 can be made current at a time. And that rendering context can only be current to 1 thread at a time.

EDIT: I bet that performance will suffer from often rebinding contexts. Since WGL seems to lack support of native context sharing, I think an approach as supposed by DaBono would be best if the desire is just to decouple loading and using of a texture, so at most the texture resource may be needed to be protected by a semaphore.

##### Share on other sites
Quote:
 Original post by MightyMartin@DaBono:- If I must call wglMakeCurrent for every frame, doesn't it means that the animation will not run smoothly when the signal is set? because what I render in foreground is not merely a "loading animation", but a full game opening.

You don't need to call wglMakeCurrent each frame, but just once. I'll try to make myself a bit clearer. Your resource thread in pseudo-code will do something like:
while( resourcesToLoad ) {   FileHandle fp = filesystem.open( textureName );   Image *image  = JPGLoader::load(fp);   textureQueue.push( image );}
createWindow();wglMakeCurrent( hwnd, ... );InitGL();while( gameRunning ) {   while( textureQueue.size() > 0 )      glTexImage2D( textureQueue.front(), .... );   renderFrame();}

So you see, only one call for wglMakeCurrent is needed.
Unfortunately, the code above is a bit too simple (e.g. you need to do proper locking around the queue), but I think you can get started with this.

##### Share on other sites
I'm just going to link to a thread from about a week ago where this issue came up:

here

##### Share on other sites
@Haegarr:

I understand now! It's really depicted something that I feared most, that I must re-make current the rendering context everytime the control changes from drawing next frame with loading resources. So there is no escape. This means that I must tricking by inserting the loading process to be happen while the screen is showing a more static screen than the opening screen (eg: the game logo). Thanks for your help! Your information about wglMakeCurrent actually binds 3 things really strikes the point!

@DaBono:

Hmmm... I think I understand the concept. So you mean to put only the "non-openGL image processing" parts in the thread, and when the image data is ready, the only process that matters is only to generate the mipmaps that shares the same thread process.

That's a brilliant idea, ummm... I don't know whether the build mipmap process is run fast enough or not to chase "a smooth framerate while loading", but it worth a try. Thanks. :)

actually... both of your ideas can be combined, Haegarr and DaBono... :)

##### Share on other sites
@Rick Appleton:

I have once again read thoroughly the links that you suggest, and found out that I still can done my previous way, but by using wglShareLists. Unfortunately I've neither ever using list nor learnt something about list. I always used the traditional method, by acquired new TextureID to a new variable using glGenTextures. Right now, I'm doing some research about the wgl list, but if someone willing to share a general or just a very basic starting information about how to using list in wgl, like what function is commonly used when working with wgl list, I will appreciate it. Thanks! :)

##### Share on other sites
wglShareList is a bit badly named. It's a holdover from the old days when there weren't any objects except for display lists.

Nowadays we have all kinds of objects in OpenGL (texture, VBO, GLSL shader, ASM shaders, etc). All of these are shared with wglShareList.

So if you call wglShareList at the correct time in the correct thread, you can just keep using glGenTextures and family and the texture will be shared between the different contexts.

##### Share on other sites
Quote:
 Original post by rick_appletonwglShareList is a bit badly named. It's a holdover from the old days when there weren't any objects except for display lists.Nowadays we have all kinds of objects in OpenGL (texture, VBO, GLSL shader, ASM shaders, etc). All of these are shared with wglShareList.

Ah, that's exactly what I had in mind at the bottom of my 1st reply. Good luck that there actually _is_ such context sharing also in WGL :)

##### Share on other sites
Quote:
 Original post by MightyMartinThat's a brilliant idea, ummm... I don't know whether the build mipmap process is run fast enough or not to chase "a smooth framerate while loading", but it worth a try. Thanks. :)actually... both of your ideas can be combined, Haegarr and DaBono... :)

This is also the way i do it. You will be pleased to know that by using this before glTexImage2D, you can let the gfx card build mipmaps for you. This is much much faster than using gluBuild2DMipMaps.

glTexParameteri(GL_TEXTURE_2D,GL_GENERATE_MIPMAP_SGIS,GL_TRUE);

##### Share on other sites
@Rick_appleton, Haegarr:

http://www.lighthouse3d.com/opengl/displaylists/

and I think I've gain an insight about the display list and wglShareLists. The display list itself is part of openGL programming. The only thing that really belongs to the wgl is the wglShareLists. But I have some common questions:

- from what I learnt, the display list is some kind of macro storing commands to be used later. Is it right?

- I don't really understood that the wglShareLists really "share" textures (and VBO, GLSL shader, ASM shaders, etc). Isn't that what wglShareLists really share is a list of ... command list? I mean, if you stated that wglShareLists share almost "anything", including textures, then I don't even need the use of display list -- I just called wglShareLists at the beginning of the thread call, and then, *poof*, all the successive openGL commands like glBindTexture, glGenTexture, and gluBuild2DMipMaps in the background loader thread will be valid. Is it right, or ... else?

- btw, I have read the zppz's tutorial, and searching again through the MSDN, and get conclusion that wglShareLists (hglrc1, hglrc2) must be called *before* the rendering context 2 (hglrc2) load any resources, such as textures. So, like you said, it's alright if the hglrc1 already has some resource loaded. That resource is also shared to hglrc2 when the wglSharelists is called. But from what I read, it's not right if the hglrc2 also has already some resource loaded too. So, in hglrc2, there must be no resource preloaded before the share attempt. I don't know what will happen if this is done. I tried to search from where I read this, but I can't found it again.

- and furthermore, by the existence of wglShareLists (which from what you both depicted, should be called wglShareResources... =] ), isn't this really a simple one-for-all solution to OpenGL Multithreading -- I mean, just call wglShareLists, and then all the multithreading concept that reside inside most of the newbies will be work? (oh! I forgot presence of the wglMakeCurrent! is it still have to be taken into account to?)

Thanks.

##### Share on other sites
Quote:
 Original post by MightyMartin- from what I learnt, the display list is some kind of macro storing commands to be used later. Is it right?

Yep. There is some kind of internal compilation that allows execution of GL routines (what you've named "commands") being more effective than passing each one for its own. Not all GL routines are allowed to be invoked in a display list, and some other caveats may appear, too.

Display lists are nice for things like bitmap based fonts (e.g. 1 display list for each glyph), macros for primitive shapes, and similar things.

Quote:
 Original post by MightyMartin- I don't really understood that the wglShareLists really "share" textures (and VBO, GLSL shader, ASM shaders, etc). Isn't that what wglShareLists really share is a list of ... command list? I mean, if you stated that wglShareLists share almost "anything", including textures, then I don't even need the use of display list -- I just called wglShareLists at the beginning of the thread call, and then, *poof*, all the successive openGL commands like glBindTexture, glGenTexture, and gluBuild2DMipMaps in the background loader thread will be valid. Is it right, or ... else?

Notice that a context share does not share everything. A GL context, as said somewhere above, contains "resources" like display lists, textures, VBOs, ... but also the "render state", like the clear color, whether depth comparison is on and which functions it uses, and bah, everything else. Context sharing means to share the "resources" but not the "render state"!

In the very early days there were no VBOs, no texture objects (i.e. only 1 texture at a time), but there were already display lists. The routine wglShareLists originates from that time. The shared resources got more and more since then, but the name of the routines was never changed. (Notice that I repeat rick_appleton's statement here.)

glBindTexture is executed in a thread and alters the "render state" but not yet the "resources", so it has no shared effect. _But_, if the thread executes a glGenTextures, then the texture object is allocated so that is available across the shared contexts. If then a thread executes glTexImage then the texture object is filled with data and hence pixel data becomes available across the shared contexts. That's the way it works.

Quote:
 Original post by MightyMartin- btw, I have read the zppz's tutorial, and searching again through the MSDN, and get conclusion that wglShareLists (hglrc1, hglrc2) must be called *before* the rendering context 2 (hglrc2) load any resources, such as textures. So, like you said, it's alright if the hglrc1 already has some resource loaded. That resource is also shared to hglrc2 when the wglSharelists is called. But from what I read, it's not right if the hglrc2 also has already some resource loaded too. So, in hglrc2, there must be no resource preloaded before the share attempt. I don't know what will happen if this is done. I tried to search from where I read this, but I can't found it again.

In all other windowing systems I know (X Window's GLX, MacOS X's AGL, and AFAIK PS/2's PGL), you must specify the shared context already when _creating_ another context. Only in WGL there is such a problem of "when to do the sharing". Well, I suggest you definitely to execute the sharing very close after creating the 2nd context! To make it clear: It better not to relate sharing to the beginning of the 2nd thread, but to the creation of the 2nd context.

Why to share _before_ allocating local resources: E.g. if both belonging contexts have already allocated a (different) texture by glGenTextures, how should they share them if both have the texture name 1? It couldn't work.

Quote:
 Original post by MightyMartin- and furthermore, by the existence of wglShareLists (which from what you both depicted, should be called wglShareResources... =] ), isn't this really a simple one-for-all solution to OpenGL Multithreading -- I mean, just call wglShareLists, and then all the multithreading concept that reside inside most of the newbies will be work?

Sorry, but I don't understand what you mean.

Quote:
 Original post by MightyMartin(oh! I forgot presence of the wglMakeCurrent! is it still have to be taken into account to?)

wglMakeCurrent must still be executed, right you are. Most GL functions does not work otherwise. However, you have to invoke it normally only once per thread.

##### Share on other sites
First a thanks to Haegarr for the explanations. They are more detailed than I could be bothered to do, and are pretty much spot on.

I'll quickly go through your list of questions.
Quote:
 Original post by MightyMartin- from what I learnt, the display list is some kind of macro storing commands to be used later. Is it right?

That's pretty much correct yes.

Quote:
 Original post by MightyMartin- I don't really understood that the wglShareLists really "share" textures (and VBO, GLSL shader, ASM shaders, etc). Isn't that what wglShareLists really share is a list of ... command list? I mean, if you stated that wglShareLists share almost "anything", including textures, then I don't even need the use of display list -- I just called wglShareLists at the beginning of the thread call, and then, *poof*, all the successive openGL commands like glBindTexture, glGenTexture, and gluBuild2DMipMaps in the background loader thread will be valid. Is it right, or ... else?

Like Haegarr said, resources will be shared. OpenGL has state, and that is not shared.

Quote:
 Original post by MightyMartin- btw, I have read the zppz's tutorial, and searching again through the MSDN, and get conclusion that wglShareLists (hglrc1, hglrc2) must be called *before* the rendering context 2 (hglrc2) load any resources, such as textures. So, like you said, it's alright if the hglrc1 already has some resource loaded. That resource is also shared to hglrc2 when the wglSharelists is called. But from what I read, it's not right if the hglrc2 also has already some resource loaded too. So, in hglrc2, there must be no resource preloaded before the share attempt. I don't know what will happen if this is done. I tried to search from where I read this, but I can't found it again.

This is indeed what most sources of information say. From my tests however, it appears that all resources loaded in either thread at any time are shared across all contexts. It is probably safest to not rely on this fact though, so you should just code as if only resources loaded after wglShareLists are shared. The issue mentioned by Haegarr could theoretically happen, but I suspect that the drivers aren't aware of this up to that point. I haven't tested this, but I wouldn't be surprised if you create two textures in two totally unrelated apps, you actually get texture IDs 1 and 2 for example, and not 1 and 1.

Quote:
 Original post by MightyMartin- and furthermore, by the existence of wglShareLists (which from what you both depicted, should be called wglShareResources... =] ), isn't this really a simple one-for-all solution to OpenGL Multithreading -- I mean, just call wglShareLists, and then all the multithreading concept that reside inside most of the newbies will be work?

It does indeed seem to work that way. Note that you still have to be careful that you don't use a texture at the same time you are uploading it's data in another thread. Something like that will likely lead to 'undefined' behaviour, which basically means that anything can happen.

Quote:
 Original post by MightyMartin(oh! I forgot presence of the wglMakeCurrent! is it still have to be taken into account to?)

As Haegarr already mentioned, you still have to call wglMakeCurrent once from inside each thread.

##### Share on other sites

can I do something like these:

In the global variable:
int protection = 0;

void mainloop (){  if (protection != 0) return;  // beginning entering mainloop, set the flag.  protection = 1;  wglMakeCurrent (hDC1, hglrc1);  // do the drawing things here;  ...  ...  wglMakeCurrent (NULL, NULL);  // release the protection  protection = 0;}

// this is used to check the availability to "make current"int protector (){  if (protection != 0) return 0;  protection = 2;  wglMakeCurrent (hDC1, hglrc1);  return 1;}void releaseprotection (){  protection = 0;  wglMakeCurrent (NULL, NULL);}void backgroundthread (){  // the background thread will stuck in here until foreground thread has  // already finished it's circle  while (!protector()) {}  LoadTexture1 ();  releaseprotection ();    // the background thread will stuck in here until foreground thread has  // already run once.  while (protection != 1) {}  while (!protector()) {}  LoadTexture2 ();  releaseprotection ();  while (protection != 1) {}  while (!protector()) {}  LoadTexture3 ();  releaseprotection ();  ...  ...  ...}

so this way, the foreground thread still has some time left to render next frame between each texture loading. but, raegarr, you said that this solution will suffer the performance because of the intensive use of wglMakeCurrent, right?

Quote:
 A thread can deal with multiple device contexts. It is also able to deal with several rendering contexts, but only 1 can be made current at a time. And that rendering context can only be current to 1 thread at a time.

by the way, from your sentence, is it possible to wglMakeCurrent (hDC1, hglrc1) in the first thread and wglMakeCurrent (hDC2, hglrc2) in the second thread at one simultaneous time? (where hDC1 != hDC2, and hglrc1 != hglrc2)

Quote:
 As Haegarr already mentioned, you still have to call wglMakeCurrent once from inside each thread.

only once inside each thread? do you mean only need for the beginning of the thread only? don't we need to call wglMakeCurrent each time we moved across the thread?

##### Share on other sites
Quote:
 Original post by MightyMartinAbout the usage of wglMakeCurrent:can I do something like these:code removed

First: I can't guarantee that the following is really true for the OS and development environment you use, but I think it is. However, even if it is false you should verify its falseness. Not considering the below aspect normally results in sporadic occurances of very strange behaviour, and hence is very hard to debug.

Quote:
Original post by MightyMartin
Quote:
 A thread can deal with multiple device contexts. It is also able to deal with several rendering contexts, but only 1 can be made current at a time. And that rendering context can only be current to 1 thread at a time.

by the way, from your sentence, is it possible to wglMakeCurrent (hDC1, hglrc1) in the first thread and wglMakeCurrent (hDC2, hglrc2) in the second thread at one simultaneous time? (where hDC1 != hDC2, and hglrc1 != hglrc2)

Absolutely. But you may need pay attention when accessing resources in the shared contexts, as rick_appleton has already mentioned somewhere earlier.

Quote:
Original post by MightyMartin
Quote:
 As Haegarr already mentioned, you still have to call wglMakeCurrent once from inside each thread.

only once inside each thread? do you mean only need for the beginning of the thread only? don't we need to call wglMakeCurrent each time we moved across the thread?

After successfully making a context current you can use it until the executed thread invokes wglMakeCurrent(NULL,NULL) or the application goes down. It is costly (and perhaps impossible?) to detect thread switching within the thread, and since releasing a render context means to force it to flush, it becomes impractical for your needs at all. That is why you should use thread synchronization (e.g. with a semaphore or the like) where needed. But, as said, using shared contextsis the better solution (what doesn't mean that you may have the need to synchronize the threads in the one or other way).

(EDIT: typo)

[Edited by - haegarr on November 28, 2006 4:42:14 AM]

##### Share on other sites
Haegarr has touched on all your issues already so I'll just leave you with a suggestion and a promise.

If you're not using Boost yet, I suggest you look into it. It has a large collection of useful modules, among which a Threads library which is supposed to be more or less portable to other OSs. I used that to implement my multithreaded app.

Second, when I have time at home again (probably not before Friday unfortunately) I'll have a look and see if I can find my simple testbed I used when starting to implement multi-threaded loading in OpenGL. If I can find it, I'll post it here.

##### Share on other sites
I don't think this came up on this thread, and I'm not aware of the state of current drivers from ATI or nVidia, but there was a problem of memory leaking when you used wglMakeCurrent "too much".
Almost looking like the drivers implemented a stack of contexts and wglMakeCurrent just pushed a context on to that stack. So always call wglMakeCurrent(0,0) before calling it with real context.

ch.

##### Share on other sites
Quote:
 Original post by christian hI don't think this came up on this thread, and I'm not aware of the state of current drivers from ATI or nVidia, but there was a problem of memory leaking when you used wglMakeCurrent "too much".Almost looking like the drivers implemented a stack of contexts and wglMakeCurrent just pushed a context on to that stack. So always call wglMakeCurrent(0,0) before calling it with real context.ch.

Well, the plan is to only call it once per thread, so this shouldn't really be a problem. Also, I think I remember someone saying this has finally been fixed.

##### Share on other sites
@christian h:

It's okay. I've managed to accostumed myself to always make the current context is not current before calling wglMakeCurrent. In fact, I just happen to know right now that calling to wglMakeCurrent when the current context is still current, IS possible. :) many thanks for the info.

@rick_appleton, haegarr:

Once again thanks for the thorough explanation. I and my programming team will try to work around the solution you both explained for a couple of days, to see if we can really implement it. -- because the deadline is coming closer. the game material itself is near to finish. the only critical problem is just the loading time is took to long (near 10 - 20 seconds on a high end computer -- we can't image if a low end computer run our game!). so if the we can make it in the time, then hurray! :)

by the way Rick, is that "boost" you tell me is from the www.boost.org library? if it is, then it's really a vast and huge library! unfortunately, it's written in C++ language. since I'm actually using Delphi (pascal) language, then the library only can be a resource. But it's more than enough for a reference.

and, with haegarr's infos, it's possible to make more than one context be current at one simultaneous time, given at these condition:
1. it's not in a same thread (absolutely!)
2. it's not from a same device context
3. it's not from a same rendering context

so, if I imagine it, I can give a pseudo code like this:

int foreground_thread_init = 0;void foreground_thread_mainloop(){  if (! foreground_thread_init)  {    // the first wglMakeCurrent    create compatible device context hDC1 from 1st window handle hWnd1;    create hglrc1 from hDC1;    wglMakeCurrent (hDC1, hglrc1);    foreground_thread_init = 1;    run background_thread_run_only_once() in separate thread process;  }  just do some drawing things on here based on what texture already loaded  successfully by background process;}void background_thread_run_only_once (){  // the second wglMakeCurrent  create compatible device context hDC2 from 2nd window handle hWnd2;  create hglrc2 from hDC2;  wglShareContext (hglrc1, hglrc2);  wglMakeCurrent (hDC2, hglrc2);  background_thread_init = 1;  // start to do the main process  load texture 1;  load texture 2;  load texture 3;  ...  ...}

the main point of the code up there is that I can call the second wglMakeCurrent in the background thread without needs to worrying about the first call of wglMakeCurrent, because it uses different hglrc, hDC, hWnd, and thread. All that I must worry about is the hglrc1 and hglrc2 must compatible each other so I can share the context, isn't it? -- I mean, this is almost looks identical to my original source code, except that I must add new initialization the hWnd, hDC, and hglrc on the background thread.

## Create an account

Register a new account

• ## Partner Spotlight

• ### Forum Statistics

• Total Topics
627638
• Total Posts
2978327
• ### Similar Content

• By xhcao
Before using void glBindImageTexture(    GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format), does need to make sure that texture is completeness.
• By cebugdev
hi guys,
are there any books, link online or any other resources that discusses on how to build special effects such as magic, lightning, etc. in OpenGL? i mean, yeah most of them are using particles but im looking for resources specifically on how to manipulate the particles to look like an effect that can be use for games,. i did fire particle before, and I want to learn how to do the other 'magic' as well.
Like are there one book or link(cant find in google) that atleast featured how to make different particle effects in OpenGL (or DirectX)? If there is no one stop shop for it, maybe ill just look for some tips on how to make a particle engine that is flexible enough to enable me to design different effects/magic
let me know if you guys have recommendations.
• By dud3
How do we rotate the camera around x axis 360 degrees, without having the strange effect as in my video below?
Mine behaves exactly the same way spherical coordinates would, I'm using euler angles.
Tried googling, but couldn't find a proper answer, guessing I don't know what exactly to google for, googled 'rotate 360 around x axis', got no proper answers.

References:
Code: https://pastebin.com/Hcshj3FQ
The video shows the difference between blender and my rotation:

• By Defend
I've had a Google around for this but haven't yet found some solid advice. There is a lot of "it depends", but I'm not sure on what.
My question is what's a good rule of thumb to follow when it comes to creating/using VBOs & VAOs? As in, when should I use multiple or when should I not? My understanding so far is that if I need a new VBO, then I need a new VAO. So when it comes to rendering multiple objects I can either:
* make lots of VAO/VBO pairs and flip through them to render different objects, or
* make one big VBO and jump around its memory to render different objects.
I also understand that if I need to render objects with different vertex attributes, then a new VAO is necessary in this case.
If that "it depends" really is quite variable, what's best for a beginner with OpenGL, assuming that better approaches can be learnt later with better understanding?

• Hello all,

On my Windows 7 x64 machine I wrote the code below on VS 2017 and ran it.
#include <glad/glad.h>  #include <GLFW/glfw3.h> #include <std_lib_facilities_4.h> using namespace std; void framebuffer_size_callback(GLFWwindow* window , int width, int height) {     glViewport(0, 0, width, height); } //****************************** void processInput(GLFWwindow* window) {     if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)         glfwSetWindowShouldClose(window, true); } //********************************* int main() {     glfwInit();     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);     //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);     GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", nullptr, nullptr);     if (window == nullptr)     {         cout << "Failed to create GLFW window" << endl;         glfwTerminate();         return -1;     }     glfwMakeContextCurrent(window);     if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))     {         cout << "Failed to initialize GLAD" << endl;         return -1;     }     glViewport(0, 0, 600, 480);     glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);     glClearColor(0.2f, 0.3f, 0.3f, 1.0f);     glClear(GL_COLOR_BUFFER_BIT);     while (!glfwWindowShouldClose(window))     {         processInput(window);         glfwSwapBuffers(window);         glfwPollEvents();     }     glfwTerminate();     return 0; }
The result should be a fixed dark green-blueish color as the end of here. But the color of my window turns from black to green-blueish repeatedly in high speed! I thought it might be a problem with my Graphics card driver but I've updated it and it's: NVIDIA GeForce GTX 750 Ti.
What is the problem and how to solve it please?

• 10
• 12
• 22
• 13
• 34