I'm drawing a background behind my 3D scene which works as expected (code below). I'm also anti-aliasing the scene using the accumulation buffer (chapter 10 of the red book).
...loop several times (say, n) through code that jitters and draws the image (jittering is moving the image to a slightly different position), accumulating the data with
glAccum(GL_ACCUM, 1.0/n)
and finally calling
glAccum(GL_RETURN, 1.0)
However, I do not want to anti-alias the background. The problem is that calling glAccum with GL_RETURN copies (overwrites) the values in the color buffer (rather than using the depth test and blend functions, etc) to mask the values being written to the color buffer.
How can I draw the background before or after anti-aliasing the 3D scene so that the background looks just like it does when I draw the 3D scene without anti-aliasing?
// Draw the background.
glMatrixMode GL.GL_PROJECTION
glLoadIdentity
glMatrixMode GL.GL_MODELVIEW
glLoadIdentity
glPolygonMode GL_FRONT_AND_BACK, GL_FILL
glDisable glcDepthTest
glBegin bmQuads
// Call glColor and glVertex here.
glEnd
glEnable glcDepthTest
If you're just after the appearance, and not looking for a rendering acceleration, don't jitter the background. Your loop would draw the background, apply the jitter, then draw the foreground. Since the background never moves, the accumulated background would be aliased.
Related
In my program, I am trying to use an image and draw it as a stationary background. The foreground does have some models loaded inside a camera and runnig fine.
However, when I apply a background image, the whole model and other objects don't appear and I can only see the background image appearing over the screen.
I did the disable the Depth_Test before drawing the background and then re-enabled it before drawing the model.
glDisbale(GL_DEPTH_TEST);
bgImage.draw(0,0); //draw the background image. Width and height parameters previously while initializing image
glEnable(GL_DEPTH_TEST);
cam.begin();
//stuff drawn inside
cam.end();
Also tried clearing the Depth Buffer/Depth Color bit after the bgImage.draw but nothing changes.
You need to disable depth writes so that the background doesn't hogs the depth buffer.
glDepthMask(GL_FALSE);
background();
glDepthMask(GL_TRUE);
Or you simply clear only the depth buffer after drawing the background:
glDisable(GL_DEPTH_TEST);
background(); // instead of clearing the color
glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
I draw a tile map on screen and each tile light(grayscale) in a FBO. All are quads.
I store the view in a Rect. To move I change de Rect, then I do this...
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(getViewRect().left,
getViewRect().left + getViewRect().width,
getViewRect().top + getViewRect().height,
getViewRect().top,
-1,
1);
glMatrixMode(GL_MODELVIEW);
I only draw the tiles inside the Rect.
The problem is the FBO. I have to draw the same tiles( the lights of the tiles), that are visible.
I want to know if there is a better way than, drawing the same tiles to the fbo with the offset of the tiles, drawing a smaller quad on the borders when is not completly visible, and changing texcoord, because when I draw outside the FBO, it draw on the opposite side.
I use FBO, because I apply shader to the lights.
It works perfect if I dont move the view, but if I move I dont know how to draw on the FBO.
You ought to be able to use glScissor to restrict all drawing within the FBO. Perform this operation after calling glBindBuffer(...) each time you bind it.
Hope this helps!
I have a problem when rendering cubes in OpenGL.I am drawing two cubes, one is a wire cube and is centered around the origin, while the other is offset from the origin and is solid. I have mapped some keys to rotate the objects by some degrees wrt to the origin, so the whole scene can rotate around the origin.
The problem is, when I render the scene, when the wire cube is supposed to be infront of the other solid cube, it does not display itself correctly.
In the image above, the colored cube is supposed to be behind the wire cube. i.e. the green wire cube should be on top.
Also the cube is not behaving properly.
After I rotate it a little bit around the x axis (current horizontal line).
The cube has missing faces and is not rendering correctly.
What am I doing wrong?
I have coded the following
Note that rotateX,rotateY,rotateZ are mapped to keys, and are my global rotation variables.
//The Initialize function, called once:
void Init(){
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Depth Buffer Setup // Enables Depth Testing
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
glEnable(GL_LIGHTING);
}
void draw(){
//The main draw function
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity ();
gluPerspective(45, 640/480.0, .5, 100);
glMatrixMode(GL_MODELVIEW); //select the modelview matrix.
glLoadIdentity ();
gluLookAt(0,0,5,
0,0,0,
0,1,0);
glRotatef(rotateX,1,0,0);
glRotatef(rotateY,0,1,0);
glRotatef(rotateZ,0,0,1);
drawScene(); // this just draws the main axis lines,
glutWireCube(1);
glPopMatrix();
glPushMatrix();
glTranslatef(-2,1,0);
drawNiceCube();
glPopMatrix();
glutSwapBuffers();
}
The code for the drawNiceCube() is just using GL_QUADS, while the drawWireCube is built in in GLUT.
EDIT:
I have posted the full code at http://pastebin.com/p1kwPjEM, sorry if it is not well documented.
Did you also request a window with a depth buffer?
glutInitDisplayMode( ... | GLUT_DEPTH | ...);
Update:
Did you somewhere enable face culling?
glEnable(GL_CULL_FACE);
This is may be cause of clockwise
10.090 How does face culling work? Why doesn't it use the surface normal?
OpenGL face culling calculates the signed area of the filled primitive in window coordinate space. The signed area is positive when the window coordinates are in a counter-clockwise order and negative when clockwise. An app can use glFrontFace() to specify the ordering, counter-clockwise or clockwise, to be interpreted as a front-facing or back-facing primitive. An application can specify culling either front or back faces by calling glCullFace(). Finally, face culling must be enabled with a call to glEnable(GL_CULL_FACE); .
OpenGL uses your primitive's window space projection to determine face culling for two reasons. To create interesting lighting effects, it's often desirable to specify normals that aren't orthogonal to the surface being approximated. If these normals were used for face culling, it might cause some primitives to be culled erroneously. Also, a dot-product culling scheme could require a matrix inversion, which isn't always possible (i.e., in the case where the matrix is singular), whereas the signed area in DC space is always defined.
However, some OpenGL implementations support the GL_EXT_ cull_vertex extension. If this extension is present, an application may specify a homogeneous eye position in object space. Vertices are flagged as culled, based on the dot product of the current normal with a vector from the vertex to the eye. If all vertices of a primitive are culled, the primitive isn't rendered. In many circumstances, using this extension
from here
Also you can read here
datenwolf solved my problem. I quote him:
"#JonathanSimbahan: Parts of your code are redundant, but something is missing: You forgot to call Init(); after creating your GLUT window, hence depth testing and all the other state never get enabled. I for one suggest you don't use Init at all and move it's code into the drawing code, where it actually belongs."
I need to know how can I make the skybox appears as it's in the infinity??
I know that it's something related to depth, but I don't know the exact thing to disable or to enable??
First, turn off depth writes/testing (you don't need to bother with turning off depth testing if you draw the skybox first and clear your depth buffer):
glDisable(GL_DEPTH_TEST);
glDepthMask(false);
Then, move the camera to the origin and rotate it the inverse of the modelview matrix:
// assume we're working with the modelview
glPushMatrix();
// inverseModelView is a 4x4 matrix with no translation and a transposed
// upper 3x3 portion from the regular modelview
glLoadMatrix(&inverseModelView);
Now, draw your sky box and turn depth writes back on:
DrawSkybox();
glPopMatrix();
glDepthMask(true);
glEnable(GL_DEPTH_TEST);
You'll probably want to use glPush/PopAttrib() to ensure your other states get correctly set after you draw the skybox too (make sure to turn off things like lighting or blending if necessary).
You should do this before drawing anything so all color buffer writes happen on top of your sky box.
First, Clear the buffer.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Then, save your current modelview matrix and load the identity.
glPushMatrix();
glLoadIdentity();
Then render your skybox.
Skybox.render();
Then, clear the depth buffer and continue normally with rendering
glClear(GL_DEPTH_BUFFER_BIT);
OtherStuff.render();
glutSwapBuffers();
The only problem with drawing the sky box is first is that your pixel shader will execute for every pixel in the sky box. Just to be overwritten by other object in your world later on. Your best bet is to render all opaque object first then render your sky box. That way the pixel shader for the sky box only gets executed for the pixel who pass the z buffer test.
There is no infinity. A skybox is just a textured box, with normaly 0,0,0 in the middle.
Here is a short tut: link text
The best approach I can think of is to draw it on a first pass(or layer), then clear only the depth buffer. After that just draw the rest of the scene in another pass. This way the skybox will always remain "behind" the scene. Just remember to use the same camera for both passes and somehow snap the skybox to the camera.
I am trying to create a simple ray tracer. I have a perspective view which shows the rays visibly for debugging purposes.
In my example screenshot below I have a single white sphere to be raytraced and a green sphere representing the eye.
Rays are drawn as lines with
glLineWidth(10.0f)
If a ray misses the sphere it is given color glColor4ub(100,100,100,100);
in my initialization code I have the following:
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.0f);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_SRC_ALPHA);
You can see in the screen shot that for some reason, the rays passing between the perspective view point and the sphere are being color blended with the axis line behind the sphere, rather than with the sphere itself.
Here is a screenshot:
Can anyone explain what I am doing wrong here?
Thanks!!
Is it a possibility you cast those rays before you draw the sphere?
Then if Z-buffer is enabled, the sphere's fragments simply won't be rendered, as those parts of rays are closer. When you are drawing something semi-transparent (using blending), you should watch the order you draw things carefully.
In fact I think you cannot use Z-buffer in any sensible way together with ray-tracing process. You'll have to track Z-order manually. While we are at it OpenGL might not be the best API to visualize ray-tracing process. (It will do so possibly much slower than pure software ray-tracer)
You dont need the glAlphaFunc, disable it.
Light rays should be blended by adding to the buffer: glBlendFunc(GL_ONE, GL_ONE) (for premultiplied alpha, which you chose.
Turn off depth buffer writing (not testing) when rendering the rays: glDepthMask(GL_FALSE)
Render the rays last.
AlphaTest is only for discarding fragments - not for blending them. Check the spec
By using it, you are telling OpenGL that you want it to throw away the pixels instead of drawing them, so you won't can any transparent blending. The most common blending function is
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); You can also check out the OpenGL Transparency FAQ.