I'm trying to invert an image for a project, which should be as simple as scaling the projection matrix by (1, -1, 1). However, the screen is drawn inside an API that I have no access to and no documentation on (this project is VERY old). So performing that scaling essentially does nothing (I assume because the projection matrix is reset inside the API's call).
Do I still have access to the drawing information after a draw call, or is it cleared? If the information still exists, how do I obtain it?
P.S. - I'm using openGL 1.1
From the programmer's point of view OpenGL is the worst kind of short term amnesiac imaginable. Once a drawing call returns from the programmer's perspective OpenGL already did turn everything into coloured pixels and completely forgot about what it just did.
So…
Do I still have access to the drawing information after a draw call, or is it cleared?
No, you don't have access to it after drawing and for all practical means it is cleared.
However you mentioned that the legacy code is old. So there's a good chance that it doesn't know about shaders, i.e. will not disable or load its custom shader. So what I'd try is loading a shader with one of the older GLSL version profiles, that still have the built-in variables mapping to the old fixed function pipeline stuff and write the shader so that it does match the legacy code's needs.
Related
I want to simulate shadows casted by complex and composite transparent objects.
This shadows must be mathematically correct for particular light source (at least for point light). I think this is true for any graphical library, is it?
Than, there must NOT be any refraction at all.
This image is not what I actually want to get of course.
Does OpenGL can do this? If it can not then what should I use instead?
UPD. So I need some path tracer. Is there some wich I could use programmatically: give it file of 3d-scene with objects and get the result of tracing?
This shadows must be mathematically correct
There's no such thing as a mathematically correct or wrong illumination. What you mean is physically correct.
Images like you want to create them rely on light propagation. The only way to properly simulate light propagation is to shoot virtual photons into a scene and follow their path. This is called path tracing.
Does OpenGL can do this?
OpenGL just draws points, lines and triangles… one at a time, without any concept of a scene or models.
Old, fixed function pipeline OpenGL had a simple Blinn illumination model built in, but this did just calculate a "light" value per vertex based on surface orientation (normal) and position relative to a light source.
Modern OpenGL does not even do that. Instead it relies on the programmer to provide programs that are executed for every vertex to decide where in the picture it goes and for every fragment (roughly a pixel) drawn to determine which color to give it.
In this programs, called shaders you can do just about anything. So if you want to implement a path tracer using OpenGL shaders, you can most certainly do this. But this path tracer will not interact with the points, lines and triangles you draw. Instead these will just serve to define the boundaries within which the shaders do their computations.
If it can not then what should I use instead?
It's not so much a question of if it is possible, but how easy it is to implement. In your case OpenGL is certainly not the right programming environment, because you'd be essentially starting from scratch. Instead you should use one of the existing path tracers around. There are also some, that are GPU accelerated.
I'm developing an application for a virtual reality environment using OGRE, Bullet and Equalizer. My rendering function looks like this:
root->_fireFrameStarted();
root->_fireFrameRenderingQueued();
root->_fireFrameEnded();
_window->update(false);
The window does not do the buffer swap, because Equalizer does that. This function works fine, we can even use particle systems and all the other fancy stuff OGRE offers.
However, since the projection area in our lab is curved, we have a GLSL module (let's call it Warp) we use in all our applications to distort the rendering output so that it fits our projection wall. We accomplish this by creating a texture, copying the contents of the back buffer to it and applying our warping shader when rendering the distorted texture covering the entire window.
You can find the source code here: pastebin . com/ TjNJuHtC
We call this module in eq::Window::frameDrawFinish() and it works well with pure OpenGL applications but not with OGRE.
This is the output without the module and its shader:
http://s1.directupload.net/images/130620/amr5qh3x.png
If I enable the module, this is the rather strange output:
http://s14.directupload.net/images/130620/74qiwgyd.png
And if I disable the two calls to glBindTexture, the texture used by the sun particle effect (flare.png) is rendered onto the screen (I would show it to you but I can only use two links).
Every GL state variable I consider relevant have the same values in our other applications.
I checked GL_READ_BUFFER, GL_DRAW_BUFFER, GL_RENDER_MODE, GL_CULL_FACE_MODE and GL_DOUBLEBUFFER.
This raises some questions: Why does my call to glTexCopySubImage2D() seem to have no effect at all? And why does my shader not do anything even if I tell it to just make every fragment red?
Supplemental: Putting the entire shader into a material script and letting OGRE handle it is not an option.
Solved the problem: I created my shaders before Ogre::Root created my windows. I have changed the order and now it works.
My question concerns the most efficient way of performing geometric image transformations on the GPU. The goal is essentially to remove lens distortion from aquired images in real time. I can think of several ways to do it, e.g. as a CUDA kernel (which would be preferable) doing an inverse transform lookup + interpolation, or the same in an OpenGL shader, or rendering a forward transformed mesh with the image texture mapped to it. It seems to me the last option could be the fastest because the mesh can be subsampled, i.e. not every pixel offset needs to be stored but can be interpolated in the vertex shader. Also the graphics pipeline really should be optimized for this. However, the rest of the image processing is probably going to be done with CUDA. If I want to use the OpenGL pipeline, do I need to start an OpenGL context and bring up a window to do the rendering, or can this be achieved anyway through the CUDA/OpenGL interop somehow? The aim is not to display the image, the processing will take place on a server, potentially with no display attached. I've heard this could crash OpenGL if bringing up a window.
I'm quite new to GPU programming, any insights would be much appreciated.
Using the forward transformed mesh method is the more flexible and easier one to implement. However performance wise there's no big difference, as the effective limit you're running into is memory bandwidth, and the amount of memory bandwidth consumed does only depend on the size of your input image. If it's a fragment shader, fed by vertices or a CUDA texture access that's causing the transfer doesn't matter.
If I want to use the OpenGL pipeline, do I need to start an OpenGL context and bring up a window to do the rendering,
On Windows: Yes, but the window can be an invisible one.
On GLX/X11 you need an X server running, but you can use a PBuffer instead of a window to get a OpenGL context.
In either case use a Framebuffer Object as the actual drawing destination. PBuffers may corrupt their primary framebuffer contents at any time. A Framebuffer Object is safe.
or can this be achieved anyway through the CUDA/OpenGL interop somehow?
No, because CUDA/OpenGL interop is for making OpenGL and CUDA interoperate, not make OpenGL work from CUDA. CUDA/OpenGL Interop helps you with the part you mentioned here:
However, the rest of the image processing is probably going to be done with CUDA.
BTW; maybe OpenGL Compute Shaders (available since OpenGL-4.3) would work for you as well.
I've heard this could crash OpenGL if bringing up a window.
OpenGL actually has no say in those things. It's just a API for drawing stuff on a canvas (canvas = window or PBuffer or Framebuffer Object), but it doesn't deal with actually getting a canvas on the scaffolding, so to speak.
Technically OpenGL doesn't care if there's a window or not. It's the graphics system on which the OpenGL context is created. And unfortunately none of the currently existing GPU graphics systems supports true headless operation. NVidia's latest Linux drivers may allow for some crude hacks to setup a truly headless system, but I never tried that, so far.
My background: I first started experimenting with OpenGL some months ago, for no particular purpose, just fun. I started reading the OpenGL redbook, and got as far as making a planetary system with a lot of different lighting. That lasted for a month, and my interest for openGL went away. It awoke again a week or so ago, and as I gathered from some SO posts, the redbook is outdated and the OpenGL Superbible is a better source for learning. So I started reading it. I like the concept of shaders but there's a real mess going on in my brain because of transition from my old memories of the fixed pipeline and the new concept of shaders.
Question: I would like to write some statements which I think are true and I am asking OpenGL experts to verify them (i.e. whether I am understanding correctly, not quite correctly or absolutely incorrectly). So...
1) If we don't use any shader program, nothing changes. We have current color, current normal, current transformation matrix, current everything, and as soon as we call glVertex**(...) these current values are taken and the vertex is fed to ... I don't know what. The fact is that it's transformed with the current matrix, the current color and normal are applied to it etc.
2) As soon as we use a shader program, all the above stops working. That is, glColor, glRotate etc. make no sense (Do they?). I mean, glColor still does set the current color, glRotate still multiplies the current matrix by the rotation matrix, but these aren't used at all. Instead, we feed vertex attributes by glVertexAttrib. Which attribute means what is totally dependent on our vertex shader and the in variable binding. We also find ans set the values of the uniforms and then call glVertex and the shader is executed ( I don't know immediately or after glEnd() is called). The actual vertex and fragment processing is done entirely manually in the shader program.
3) Shaders don't add anything to depth testing. That is, I don't need to take care of it in a shader. I just call glEnable(GL_DEPTH_TEST). Neither is face culling affected.
4) Alpha blending and antialiasing need not be taken care of in shaders. glEnable calls will suffice.
5) Is it a good idea to use gluPerspective, glRotate, glPushMatrix and other matrix functions, and then retrieve the current matrix and feed it as a uniform to a shader? Thus there won't be any need in using a 3rd party matrix library.
It depends on what version of OpenGL you're talking about. Up through OpenGL 3.0, all the fixed functionality is still present, so yes, if you decide to just use fixed functionality it continues to work like it always did. Starting from 3.0, quite a bit of the fixed pipeline was deprecated, and as of 3.1 it disappears completely. Using these, you no longer really have the option to just use the fixed pipeline.
Again, it depends. For example, up through OpenGL 3.0, glColor is still supported, even when you use a shader. The difference is that instead of automatically being applied to what gets drawn, it's supplied to your shader, which can use it unchanged, modify it as it sees fit, or ignore it completely. So, your fragment shader receives gl_FrontColor and gl_BackColor, and writes the actual fragment color to gl_FragColor. If you're using OpenGL 3.1 or newer, however, glColor (for example) just no longer exists -- a color will be just another value you supply to your shader like you could/would anything else.
That's correct, at least up to OpenGL 3.1. As of 4.0, there's a new compute shader that (I believe) can get involved in things like depth testing (but I haven't used it, so I'm a bit uncertain about that).
Yes, you can still use built-in alpha blending. Depending on your hardware, you may also want to consider using the gl_ARB_draw_buffers_blend extension (which is mandatory as of OpenGL 4, if I recall correctly).
Yet again, it depends on the version of OpenGL you're talking about. Current OpenGL completely eliminates all support for matrices so you have no choice but to use some other matrix library. Older versions supplied things like gl_ModelViewMatrix and gl_NormalMatrix to your shader as a uniform so you could go that route if you chose.
2) In modern OpenGL, there is no glColor, glBegin, glVertex, glRotate etc. so they don't make sense.
5) In modern OpenGL there are no built-in matrices, so you have to use a 3rd party library or write your own. So to answer your question, no, it's not a good idea.
I'm just starting OpenGL programming in Win32 C++ so don't be too hard on me :) I've been wandering along the NeHe tutorials and 'the red book' a bit now, but I'm confused. So far I've been able to set up an OpenGL window, draw some triangles etc, no problem. But now I want to build a model and view it from different angles. So do we:
Load a model into memory (saving triangles/quads coordinates in structs on the heap) and in each scene render we draw all stuff we have to the screen using glVertex3f and so on.
Load/draw the model once using glVertex3f etc and we can just change the viewing position in each scene.
Other...?
It seems to me option 1 is most plausible from all I read so far, however it seems a bit ehh.. dumb! Do we have to decide which objects are visible, and only draw those. Isn't that very slow? Option 2 might seem more attractive :)
EDIT: Thanks for all the help, I've decided to do: read my model from file, then load it into the GPU memory using glBufferData and then feed that data to the render function using glVertexPointer and glDrawArrays.
First you need to understand, that OpenGL actually doesn't understand the term "model", all what OpenGL sees is a stream of vertices coming in and depending on the current mode it uses those streams of vertices to draw triangles to the screen.
Every frame drawing iteration follows some outline like this:
clear all buffers
for each window element (main scene, HUD, minimap, etc.):
set scissor and viewport
conditionally clear depth and/or stencil
set projection matrix
set modelview matrix for initial view
for each model
apply model transformation onto matrix stack
bind model data (textures, vertices, etc.)
issue model drawing commands
swap buffers
OpenGL does not remember what's happening up there. There was (is) some facility, called Display Lists but they are not able to store all kinds of commands – also they got deprecated and removed from recent OpenGL versions. The immediate mode commands glBegin, glEnd, glVertex, glNormal and glTexCoord have been removed as well.
So the idea is to upload some data (textures, vertex arrays, etc.) into OpenGL buffer objects. However only textures are directly understood by OpenGL as what they are (images). All other kinds of buffers require you telling OpenGL how to deal with them. This is done by calls to gl{Vertex,Color,TexCoord,Normal,Attrib}Pointer to set data access parameters and glDraw{Arrays,Elements} to trigger OpenGL fetching a stream of vertices to be fed to the rasterizer.
You should upload the data to the GPU memory once, and then draw each frame using as few commands as possible.
Previously, this was done using display lists. Nowadays, it's all about vertex buffer objects (a.k.a. VBOs), so look into those.
Here's a tutorial about VBOs, written before they were only an extension, and not a core part of OpenGL.