I want to design & implement a simple windowing & widget for OpenGL running on top of SDL, much like Agar or GiGi, only much closer tied to SDL & OpenGL.
My general problem is this: what is the best design for a windowing system within an OpenGL context??
I want to have windows just for controls, and, if even possible, threaded windows with their own OpenGL contexts. The only way I've though about it even being possible is rendering to textures, and them adding window decoration around those...
I want to expose the workings to other programmers, but which way would be best. I am more of a C++ programmer and so inheritance was the first way I thought of. Make basic classes which I expose in a shared header file, the programmer then derives their own window object from that, overriding the Init() or Run() methods to implement what they need. The problem with this approach would be keeping the programmers in check, there would be no real way to 'keep' them from simply drawing wherever they want in the OpenGL screen.
Another possible way would be functors, passing the functors the programmer wants to use into the library which then calls it once it's finished rendering it's GUI components and what-not.
What is the best way of approaching any of this??
windows with their own OpenGL contexts
That's going to require hacking SDL, since it only provides one context per process. Unless you're thinking of doing a single GL context with multiple independent sub-viewports rendered in sequence.
Related
I recently read an OOP book (Robert Martin I think) that emphasized using a core object that calls interfaces of the things it uses. The point here is that the peripheral objects depend on the core rather than the other way around. This allows better modularity, flexibility, distribution of binaries, build time, etc. Supposedly you can also allow your program to be independent of any particular framework, eg GUI, database, etc. But I'm having a hard time separating the framework from the core.
For example the Qt framework provides class QTreeView; some functions take instances of QAbstractItemModel.
It's conceivable I find or write a different model/view I want to use that is not part of the Qt world, or use some immediate-mode api for the graphics part, etc.
So how do I write my core to be agnostic of Qt entirely?
Do I make up an ITreeView with similar functions as QTreeView, with similar-sounding non-Qt arguments and then delegate to a real QTreeView instance after converting all arguments to real Qt types? It seems silly to recreate so much of the framework just to make it generic.
Or in the real world are people fully absorbed into Qt and it's not realistic to keep it separated?
I am relatively new to graphic programming so I wanted to start from the very basic. I see there is library like PyOpenGl which provides binding to the opengl api itself. Now, I really want to create things like PyOpenGl on my own so I can understand how everything work in the process.
Is it possible for me to creates library like PyOpenGl or GLFW? If so please give me some general tips of what should I do.
If not please explain to me why I can't create my own binding and I do apologize if my question above sounds absurd.
PyOpenGL is a fairly thin wrapper that, for the most part, simply turns Python function calls into calls of native machine code functions of the same name. There are a few little details like calling conventions in the mix, but these are actually boring stuff. The fact is that (as far as OpenGL is concerned) the source code you write in Python with PyOpenGL looks almost identical to the source code you'd write in C. There are a few "smart" things PyOpenGL does, like providing means to interface NumPy arrays to OpenGL calls that take a data pointer parameter, but that's just house keeping.
And when you do OpenGL calls in C or – even more extreme – assembly language (perfectly possible) that's the lowest level you can go (with OpenGL), short of writing your own GPU device driver. And writing a GPU device driver is super hard work; it takes literally millions of lines of C code (NVidia's OpenGL implementation is said to consist of about ~40M LoC, there are open source drivers for AMD and Intel GPUs, and each of them have MLoC, too).
If you're interested in some middle ground, have a look at the Vulkan API. If writing higher level wrappers for graphics is your thing I'd suggest you implement some higher level API / renderer for Vulkan and interface it to Python. This is likely to be much more rewarding, as a learning experience (IMHO).
The OpenGL API lives in the driver for the graphics card. All OpenGL functions are there. You only need to know how to get them. As Spektre said, the proccess is:
Create an OpenGL context. This is a job for the OS. Each OS has its
way and its issues. Read https://www.khronos.org/opengl/wiki/Load_OpenGL_Functions
Define function pointers as glext.h does and then extract them from
the driver. Apart from standard OpenGL funcs, vendors add their own
ones, called "extensions". You can see how GLEW does this job. If you want to set all functions and extensions then make a script that uses glext.h because there are about one thousand of them.
You can download glext.h from https://www.opengl.org/registry/
Doing something like GLFW requires, added to the previous two points, knowing how to create a window and handle its messages for keyboard and mouse. Again this is OS dependant. On Windows there is a way. On Linux it depends on the window manager used, GTK+ for example. Or X11 directly. Or...
Anyhow my best advise is that you can read how GLEW and GLFW did, looking into their code. BUT don't lose much time on it. Prefer getting experience on OpenGL and let those "diggins" for later time.
After coding for some time in Java and using Graphics2d, I thought of using what I've learned in other languages, for example C++. I usually use SFML, and have a Render class so as to reduce dependency of other classes on SFML (as in, if I must switch libraries I would not need to switch much code in unrelated classes). I was wondering if I should have this Render class inherit RenderWindow, or simply have it as a member.
A currently often suggested idiom is 'composition over inheritance'. From your vague description of what you're doing, it's actually impossible to give precise answer. I'm assuming you're talking about a simple interface between your framework and any graphics library.
In that case the answer is quite simple, because inheritance would automatically change the API of the render and it would change for every single graphics library you'd use and thus defeat the whole purpose of it. So if you use it as a member variable, you can craft a stable API for your framework and do all the adaption for different libraries within the scope of the render class.
I'm currently in the process of writing a game engine which is about to go through a major rewrite. First off, I'm considering what library to use in conjunction with the engine. Obviously, I'm going with OpenGL here and am going to do what I can to make it forward as well as backward compatible.
The main issue, though, is that from most of my research, I've found that great libraries like SDL (except for 1.3 - which, I don't believe is stable? I may be wrong about this) only support up to OpenGL 3 and not 4.2. FreeGlut, however, does support the latest and greatest, and seems like a good way to go for the basics of an engine.
The only thing, however, is setting up something such as Keyboard I/O and sound input audio, along with other things. Thus, I'm considering to see whether or not it's possible to use glut to initialize opengl and use opengl with it, and then have SDL do window management along with keyboard I/O, sound, etc.
Of course, there's always the option of using Qt with OpenGL, but I'd like to definitely have control over my main loop if possible (is this possible with Qt and OpenGL?).
I've heard of SFML, too, but ultimately I'd like to stick with libraries written in C as I plan to write a C library to take care of most of the primitive rendering (for the sake of pure speed and memory management, procedurally).
Thus, I'm at a loss as what to do here. IS Qt a good choice for this, or is there another C-like alternative (such as FreeGlut) which allows main-loop control (like SDL) and offers the necessary customization I'm looking for?
The main issue, though, is that from most of my research, I've found that great libraries like SDL (except for 1.3 - which, I don't believe is stable? I may be wrong about this) only support up to OpenGL 3 and not 4.2. FreeGlut, however, does support the latest and greatest, and seems like a good way to go for the basics of an engine.
Your research is lacking.
First, FreeGLUT should never be used for anything that you would call an "engine". Whatever you mean by that, FreeGLUT is not the tool for the job. It's designed for creating demos, which is why it owns the main loop. I understand that FreeGLUT does have a way to allow you some control over the main loop, but the standard way to use FreeGLUT doesn't do that.
Second, you are correct that SDL 1.2 is not capable of creating an OpenGL 3.2+ core context. However, you don't have to be able to create a core context to use GL 3.2+; compatibility contexts work just fine at those versions. The only platform that has no compatibility context is MacOSX's 3.2 support. So I wouldn't worry about it.
You could try GLFW. It's sort of like FreeGLUT only more game-centric. It gives you control of the render loop and so forth. It provides better input handling than FreeGLUT, as well as some light image loading functions (only TGA files). It even has a threading API (though I wouldn't suggest using these functions. GLFW 2.0 will drop them since both C++11 and C11 have native thread APIs).
However, it has no systems in place for audio.
I've heard of SFML, too, but ultimately I'd like to stick with libraries written in C as I plan to write a C library to take care of most of the primitive rendering (for the sake of pure speed and memory management, procedurally).
I'm going to ignore the fallacy about C++ not having the "pure speed and memory management;" that's a common canard that I'll ignore. The important point is this: SFML, as far as your rendering code is concerned, exists solely to create and manage the window. Your rendering code doesn't even have to talk to it. You call some SFML functions, create a couple of SFML objects, and your "C library" OpenGL code won't even have to know those C++ objects are there.
However, if you absolutely cannot work in C++ at all, you can always use Allegro version 5. It has a C API, and it provides support for OpenGL core contexts, input, audio, and most of what SFML does. It also has pretty decent documentation, and is modular (though in a different way from SFML).
I have some fundamental points/questions about OpenGL, not all involving code but concepts as well. I would be grateful if you could answer, affirm or expand on any of them. I warn you, some might be naive, so please bear with me.
I understand that OpenGL is just a standard, as opposed to a piece of software. For example, 'getting' OpenGL actually involves getting a third-party implementation which doesn't necessarily have to be endorsed by Khronos.
OpenGL usually refers to the combination of the GL utilities (GLU) and the GL utilities toolkit (GLUT). They have methods beginning with glu and glut, resp. and the 'basic' OpenGL methods, that begin with simply gl, are implemented by those that make graphics drivers, i.e. NVIDIA?
I assume that glut methods are OS-specific helpers, for example glutKeyboardFunc() has to be, to interpret the keyboard. So if I wanted a more powerful alternative way to interpret keyboard input, I would just use the OS API. OpenGL itself is purely about graphics, but glut has this sort of thing since graphics is not much without real-time human control.
It seems to me that glu methods may be identical to calling a series of lower-level gl methods. One example I would like to quote is glOrtho() and gluPerspective(). They seem to me to have similar ways of working, but calculating perspective may be more complex, so gluPerspective() is for convenience, but might just resolve to some gl methods.
I have studied basic OpenGL using freeglut at university, and I keep having this vision of a 'hardcore' way of using OpenGL, using only low-level methods. I don't know if this is a totally naive thought, but is there a 'professional' way of writing OpenGL, to get out its maximum functionality? Like, presumably, game developers wouldn't use glutPostRedisplay() for example, right? It seems too easy and convenient, like it hides a lot of what is going on. I suspect this is also true for C++ since GLUT callbacks aren't friendly with methods in namespaces (as I've seen in other questions).
\ 1. I understand that OpenGL is just a standard, as opposed to a piece of software. For example, 'getting' OpenGL actually involves getting a
third-party implementation which doesn't necessarily have to be
endorsed by Khronos.
Indeed.
\ 2. OpenGL usually refers to the combination of the GL utilities (GLU) and the GL utilities toolkit (GLUT). They have methods beginning with
glu and glut, resp. and the 'basic' OpenGL methods, that begin
with simply gl, are implemented by those that make graphics drivers,
i.e. NVIDIA?
No. OpenGL is just the functions beginning with gl…. Everything else (GLU, GLUT) are third party libraries, not covered by OpenGL.
\ 3. I assume that glut methods are OS-specific helpers, for example glutKeyboardFunc() has to be, to interpret the keyboard. So if I
wanted a more powerful alternative way to interpret keyboard input, I
would just use the OS API. OpenGL itself is purely about graphics, but
glut has this sort of thing since graphics is not much without
real-time human control.
Correct. GLUT is a very minimal framework, so using something else is strongly recommended.
\ 4. It seems to me that glu methods may be identical to calling a series of lower-level gl methods. One example I would like to quote
is glOrtho() and gluPerspective().
I think you refer to gluOrtho2D but yes, you're correct. glOrtho is a true OpenGL-1 function. In some way, gluOrtho2D is one of the most useless functions ever:
void gluOrtho2D(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top)
{
glOrtho(left, right, bottom, top, -1, 1);
}
They seem to me to have similar
ways of working, but calculating perspective may be more complex, so
gluPerspective() is for convenience, but might just resolve to some
gl methods.
Right again, but it's actually quite simple:
gluPrespective(GLfloat fov, GLfloat aspect, GLfloat near, GLfloat far)
{
GLfloat a = 0.5 * atan(fov);
glFrustum(-a*near, a*near, -a*near/aspect, a*near/aspect, near, far);
}
Starting with OpenGL-3 core, the whole matrix manipulation stuff has been removed. In any serious application it's of little use, since you'll manage the matrices yourself anyway.
\ 5. I have studied basic OpenGL using freeglut at university, and I keep having this vision of a 'hardcore' way of using OpenGL, using
only low-level methods. I don't know if this is a totally naive
thought, but is there a 'professional' way of writing OpenGL, to get
out its maximum functionality? Like, presumably, game developers
wouldn't use glutPostRedisplay() for example, right?
Yes this is possible and most game engines indeed do all the grunt work themself.
There is libSDL, which also covers OpenGL. Personally I prefer GLFW or doing the stuff myself, indeed. However this does not change the way one uses OpenGL itself. But this is just infrastructure, and it's mostly just writing boilerplate code. As a beginner you gain only very little by not using an established framework. If your program makes heavy use of GUI widgets, then using Qt or GTK, with its embedded OpenGL widget is a reasonable choice.
However some projects are very hardcore, and implement the whole GUI with OpenGL, too. Blender is the most extreme example, and I love it.
It seems too easy and convenient, like it hides a lot of what is going on. I
suspect this is also true for C++ since GLUT callbacks aren't friendly
with methods in namespaces (as I've seen in other questions).
GLUT callbacks are okay with namespaces (a namespace is just a C++ compilation time thing). But what's not possible is passing class instance methods as GLUT/C callbacks.
You seem to have a pretty good notion of OpenGL and the tookit. Not sure what's more to tell.
I guess (5) is really where one can comment on.
Depending what type of application you are building you are right in thinking that some will choose to build their application only using the native GL calls.
For example, if you build a single document app under windows that has an OpenGl view but also the standard menus and toolbars, there is a strong chance you will want to go straight for c++ and what you call "low level" api.
However, if you build a low paced game in full screen mode, there is no real reason why you should not use Glut or any other toolkit for that matter if it ease the development of your app.
The fact you use GLut or low level calls directly alone doesn't make the app better or worst :)
hope it help