GPU Usage in a non-GLSL OpenGL Application - opengl

I read from the OpenGL Wiki that current Modern GPUs are only programmable using shaders.
Modern GPUs no longer support fixed
function. Everything is done with
shaders. In order to preserve
compatibility, the GL driver generates
a shader that simulates the fixed
function. It is recommended that all
new modern programs use shaders. New
users need not learn fixed function
related operations of GL such as
glLight, glMaterial, glTexEnv and many
others.
Is that mean that if we are not implementing shader/GLSL in OpenGL, we actually don't access the GPU at all and only do the computation using the CPU?

No. It means that all fixed function stuff is automatically converted to shaders by the drivers.

Everything is done with shaders. In
order to preserve compatibility, the
GL driver generates a shader that
simulates the fixed function.
These shaders still run on the GPU (as all shaders do). They are just automatically made for you.

Related

Using Legacy OpenGL and Modern OpenGL in same application

I have a work laptop that only supports OpenGL 2.1 and i have desktop in my home with OpenGL 4.4. I'm working on a project in my Desktop. So i make my program that compatible with Modern OpenGL. But i want to develop this project in my work laptop. My question is can i make this project compatible with both Legacy and Modern OpenGL?
Like this.
#ifdef MODERN_OPENGL
some code..
glBegin(GL_TRIANGLES);
...
glEnd();
#else
glGenBuffers(&vbo);
...
#endif
What you suggest is perfectly possible, however if you do it through preprocessor macros you're going to end up in conditional compilation hell. The best bet for your approach is to compile into shared libraries, one compiled for legacy and one for modern and load the right variant on demand. However when approaching it from that direction you can just as well ditch the preprocessor juggling and simply move render path variants into their own compilation units.
Another approach is to decide on what render path to use at runtime. This is my preferred approach and I usually implement it through a function pointer table (vtable). For example the volume rasterizer library I offer has full support for OpenGL-2.x and modern core profiles and will dynamically adjust its code paths and the shaders' GLSL code to match the capabilities of the OpenGL context it's being used in.
If you're worried about performance, keep in mind that literally every runtime environment that allows for polymorphic function overwriting has to go through that bottleneck. Yes, it does amount to some cost, but OTOH it's so common that modern CPUs' instruction prefetch and indirect jump circuitry has been optimized to deal with that.
EDIT: Important note about what "legacy" OpenGL is and what not
So here is something very important I forgot to write in the first place: Legacy OpenGL is not glBegin/glEnd. It's about having a fixed function pipeline by default and vertex arrays being client side.
Let me reiterate that: Legacy OpenGL-1.1 and later does have vertex arrays! What this effectively means is, that large amounts of code that are concerned with the layout and filling the content of vertex arrays will work for all of OpenGL. The differences are in how vertex array data is actually submitted to OpenGL.
In legacy, fixed function pipeline OpenGL you have a number of predefined attributes and function which you use to point OpenGL toward the memory regions holding the data for these attributes before making the glDraw… call.
When shaders were introduced (OpenGL-2.x, or via ARB extension earlier) they came along with the very same glVertexAttribPointer functions that are still in use with modern OpenGL. And in fact in OpenGL-2 you can still point them toward client side buffers.
OpenGL-3.3 core made the use of buffer objects mandatory. However buffer objects are also available for older OpenGL versions (core in OpenGL-1.5) or through an ARB extension; you can even use them for the non-programmable GPUs (which means effectively first generation Nvidia GeForce) of the past century.
The bottom line is: You can perfectly fine write code for OpenGL that's compatible with a huge range for version profiles and require only very little version specific code to manage the legacy/modern transistion.
I would start by writing your application using the "new" OpenGL 3/4 Core API, but restrict yourself to the subset that is supported in OpenGL 2.1. As datenwolf points out above, you have vertex attribute pointers and buffers even in 2.1
So no glBegin/End blocks, but also no matrix pushing/popping/loading, no pushing/popping attrib state, no lighting. Do everything in vertex and fragment shaders with uniforms.
Restricting yourself to 2.1 will be a bit more painful than using the cool new stuff in OpenGL 4, but not by much. In my experience switching away from the matrix stack and built-in lighting is the hardest part regardless of which version of OpenGL, and it's work you were going to have to do anyway.
At the end you'll have a single code version, and it will be easier to update if/when you decide to drop 2.1 support.
Depending on which utility library / extension loader you're using, you can check at runtime which version is supported by current context by checking GLAD_GL_VERSION_X_X, glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR/MINOR) etc., and create appropriate renderer.

Is it ok to use OpenGL 1.1?

It is ok to use functions from OpenGL 1.1 in code, for render quads with textures (for buttons) or lines (for pathes)? Functions like: glBegin, glVertex or glEnd?
P.S. For 3D models I use VBO from newer version of OpenGL.
Supporting compatibility profiles in OpenGL-3.3 and later is optional, so don't expect legacy functions to be available if your program also makes use of modern features. In general you should not use glBegin/glVertex/glEnd in new code. Even for pathologically simple shapes using modern OpenGL primitives will be simpler and easier to read. The only "downside" is, that you also have to specify a shader and shader setup may be a bit tedious if you're not abstracting it away.

Implement OpenCL on OpenGL

I have seen OpenCL is widely supported by CPU implementation as well as some GPU implementations.
For the cases there is a GPU, but no GPU implementation available, would it be feasable to implement OpenCL using OpenGL?
Maybe most operations would map quite well to GLSL fragment shader or even compute shaders.
If this is feasable, where to begin? Is there any 'minimal' CPU OpenCL implementation, that one could start off?
For the cases there is a GPU, but no GPU implementation available, would it be feasable to implement OpenCL using OpenGL?
Possible: Yes, certainly. Every Turing complete machine can emulate any other Turing complete machine.
Feasible: OpenGL implementations' GLSL compilers are already primadonnas, each implementation's compiler behaving a little different. OpenGL itself has tons of heuristics in it to select the codepath. Shoehorning a makeshift OpenCL on top of OpenGL + GLSL will be an exercise in lots of pain.
Required: Absolutely not: For every GPU which has the required capabilities to actually support OpenCL the drivers do support OpenCL anyway, so this is a moot non-issue.
OpenCL has certain very explicit requirements on the precision of floating-point operations. GLSL's requirements are far more lax. So even if you implemented the OpenCL API on top of OpenGL, you would never be able to get the same behavior.
Oh and in case you start thinking otherwise, Vulkan is no better in this regard.

Fixing GLSL shaders for Nvidia and AMD

I am having problems getting my GLSL shaders to work on both AMD and Nvidia hardware.
I am not looking for help fixing a particular shader, but how to generally avoid getting these problems. Is it possible to check if a shader will compile on AMD/Nvidia drivers without running the application on a machine with the respective hardware and actually trying it?
I know, in the end, testing is the only way to be sure, but during development I would like to at least avoid the obvious problems.
Everyone using GLSL must have these problems, so why can't I find a good way to fix them?
Is it possible to check if a shader will compile on AMD/Nvidia drivers without running the application on a machine with the respective hardware and actually trying it?
No. If you are going to be serious about developing applications, testing on a variety of hardware is the only reliable way to go about it. And if you're not going to be serious, then who cares.
Generally speaking, the easiest way to handle this for a small team is to avoid the problem altogether. Most driver incompatibilities come from attempting to do something unorthodox: passing arrays as output/input varying variables, passing matrices as attributes, using more recent driver features, etc. So... don't do that. Use only solid, safe stuff that's been around in GLSL and has been almost certainly used in real-world OpenGL applications.
using NVidias's NVEmulate and AMD's GPU ShaderAnalyzer could be an option.
AMD's GPU ShaderAnalyzer is a stand-alone GLSL/HLSL compiler. NVidias's NVEmulate is a tool to emulate the features of different (better) NVidia graphic cards in software. So if you have an NVidia card, you can simply run your program to test it (possibly emulating another NVidia card with the NVEmulate) and use the ShaderAnalyser to see if your shader compile on AMD cards.
If your shader runs on AMD, it will most probably run on NVidia. You can still test this with cgc (NVidias stand-alone Cg compiller, part of the Cg Toolkit) it compiles GLSL and Cg code to binary or cross-compile it to HLSL. This is the compiler which NVidia drivers use for GLSL anyway.
The bonus is that you can also see the binary/assembly code of your shader, which is very helpful for low-level optimizations.
What no tool can tell you is, if the shader works (as expected) on different hardware.. I recently found out that some new AMD driver don't handle default uniform values properly... without a warning or error message... but this is a different story.
So at some point you have to test your code on the target hardware.

What Are The Changes To OpenGL From 1.x, 2.x, 3.x And 4.x?

What have changed that makes OpenGL different? I heard of people not liking OpenGL since OpenGL 3.x, but what happend? I want to learn OpenGL but I don't know which one. I want great graphics with the newer versions, but what's so bad?
Generally, every major version of OpenGL is roughly equivalent to a hardware generation. Which means that generally if you can run OpenGL 3.0 card, you can also run OpenGL 3.3 (if you have a sufficiently new driver).
OpenGL 2.x is the DX9-capable generation of hardware, OpenGL 3.x is the DX10, and OpenGL 4.x the DX11 generation of hardware. There is no 100% exact overlap, but this is the general thing.
OpenGL 1.x revolves around immediate mode, which is conceptually very easy to use, and a strictly fixed function pipeline. The entry barrier is very low, because there is hardly anything you have to learn, and hardly anything you can do wrong.
The downside is that you have considerably more library calls, and CPU-GPU parallelism is not optimal in this model. This does not matter so much on old hardware, but becomes more and more important to get the best performance out of newer hardware.
Beginning with OpenGL 1.5, and gradually more and more in 2.x, there is slight paradigm shift away from immediate mode towards retained mode, i.e. using buffer objects, and a somewhat programmable pipeline. Vertex and fragment shaders are available, with varying feature sets and programmability.
Much of the functionality in these versions was implemented via (often vendor-specific) extensions, and sometimes only half-way or in several distinct steps, and not few features had non-obvious restrictions or pitfalls for the casual programmer (e.g. register combiners, lack of branching, limits on instructions and dependent texture fetches, vtf support supporting zero fetches).
With OpenGL 3.0, fixed function was deprecated but still supported as a backwards-compatibility feature. Almost all of "modern OpenGL" is implemented as core functionality as of OpenGL 3.x, with clear requirements and guarantees, and with an (almost) fully programmable pipeline. The programming model is based entirely on using retained mode and shaders. Geometry shaders are available in addition to vertex and fragment shaders.
Version 3 has received a lot of negative critique, but in my opinion this is not entirely fair. The birth process was admittedly a PR fiasco, but what came out is not all bad. Compared with previous versions, OpenGL 3.x is bliss.
OpenGL 4.x has an additional tesselation shader stage which requires hardware features not present in OpenGL 3.x compatible hardware (although I daresay that's rather a marketing reason, not a technical one). There is support for a new texture compression format that older hardware cannot handle as well.
Lastly, OpenGL 4.x introduces some API improvements that are irrespective of the underlying hardware. Those are also available under OpenGL 3.x as 100% identical core extensions.
All in all, my recommendation for everyone beginning to learn OpenGL is to start with version 3.3 right away (or 3.2 if you use Apple).
OpenGL 3.x compatible hardware is nearly omni-present nowadays. There is no sane reason to assume anything older, and you save yourself a lot of pain. From an economic point of view, it does not make sense to support anything older. Entry level GL4 cards are currently at around $30. Therefore, someone who cannot afford a GL3 card will not be able to pay for your software either (it is twice as much work to maintain 2 code paths, though).
Also, you will eventually have no other choice but to use modern OpenGL, so if you start with 1.x/2.x you will have to unlearn and learn anew later.
On the other hand, diving right into version 4.x is possible, but I advise against it for the time being. Whatever is not dependent on hardware in the API is also available in 3.x, and tesselation (or compute shader) is something that is usually not strictly necessary at once, and something you can always add on later.
For an exact list of changes I suggest you download the specification documents of the latest of each OpenGL major version. At the end of each of these there are several appendices documenting the changes between versions in detail.
The many laptops with Intel integrated graphics designed before approx a year ago do not do OpenGL 3. That includes some expensive business machines, e.g., $1600 Thinkpad x201, still for sale on Amazon as of today (4/3/13) (although Lenovo has stopped making them),
OpenGL 3.1 removed the "fixed function pipeline". That means that writing vertex and fragment shaders is no longer optional: If you want to display anything, you must write them. This makes it harder for the beginner to write "hello world" in OpenGL.
The OpenGL Superbible Rev 5 does a good job of teaching you to use modern OpenGL without falling back on the fixed function pipeline. That's where I would start if I were learning OpenGL from scratch.
Their rev 4 still covers the fixed function pipeline if you want to start with a more "historical" approach.