JOGL Double Buffering - java

What is eligible way to implement double buffering in JOGL (Java OpenGL)?
I am trying to do that by the following code:
...
/** Creating canvas. */
GLCapabilities capabilities = new GLCapabilities();
capabilities.setDoubleBuffered(true);
GLCanvas canvas = new GLCanvas(capabilities);
...
/** Function display(…), which draws a white Rectangle on a black background. */
public void display(GLAutoDrawable drawable) {
drawable.swapBuffers();
gl = drawable.getGL();
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl.glColor3f(1.0f, 1.0f, 1.0f);
gl.glBegin(GL.GL_POLYGON);
gl.glVertex2f(-0.5f, -0.5f);
gl.glVertex2f(-0.5f, 0.5f);
gl.glVertex2f(0.5f, 0.5f);
gl.glVertex2f(0.5f, -0.5f);
gl.glEnd();
}
...
/** Other functions are empty. */
Questions:
— When I'm resizing the window, I usually get flickering. As I see it, I have a mistake in my double buffering implementation.
— I have doubt, where I must place function swapBuffers — before or after (as many sources says) the drawing? As you noticed, I use function swapBuffers (drawable.swapBuffers()) before drawing a rectangle. Otherwise, I'm getting a noise after resize. So what is an appropriate way to do that?
Including or omitting the line capabilities.setDoubleBuffered(true) does not make any effect.

If you use a GLCanvas, autoSwapBuffer mode is set to true by default, you should not have to call swapBuffers() manually. Your flickering has nothing to do with double buffering, rather set sun.awt.noerasebackground to true.

If JOGL is like the C/C++ version:
RMorrisey and the sample code is incorrect in stating the use of glFlush.
The swapBuffers function must go at the end of the drawing.
To confirm this: have the shapes do animation very quickly and watch for tearing. If you get tearing then you are doing a single draw, if you don't then you are using double buffering.

Here's an example of double-buffered animation using JOGL:
http://www.java-tips.org/other-api-tips/jogl/how-to-implement-a-simple-double-buffered-animation-with-mouse-e.html
Try instead of calling swapBuffers(), at the end of display(...) call:
gl.glFlush();
It's been a while since I've done anything with JOGL; hope this helps.

Related

Drawing trigonometric graphs with OpenGL?

I am trying to draw a trigonometric graph with OpenGL. This is a part of my code:
double x = -1;
gl.glColor3d(0, 0, 0);
gl.glBegin(gl.GL_LINES);
gl.glVertex2d(x, Math.sin(Math.toRadians(x))*0.01);
gl.glVertex2d(x+0.01, Math.sin(Math.toRadians(x+0.01))*0.01);
gl.glEnd();
x += 0.01;
This part is repeated in my full code. When this is executed, I see nothing. Can anybody tell me why this might be happening?
I do not see any loop in your code
and also the scales are suspicious (without matrices hard to tell) try this instead:
double x;
gl.glColor3d(0.0, 0.0, 0.0);
gl.glBegin(gl.GL_LINE_STRIP);
for (x=-180.0;x<=180.0;x+=0.01)
gl.glVertex2d(x/180.0, Math.sin(Math.toRadians(x)));
gl.glEnd();
it uses LINE_STRIP instead of LINES and the graph is scaled to <-1,+1> which is most likely your viewing area...
settings
Also there might be other problems like the comments suggest. On top of them check the obvious:
gl.glDisable(gl.GL_DEPTH_TEST);
gl.glDisable(gl.GL_TEXTURE_2D);
in case they has been set from other part of your code...
wrong camera settings
I do not see any matrix code so I hope your camera is facing the correct direction and your graph is inside frustrum or whatever you use...
GL rendering
In case your GL code is missing or has wrong structure then it should look like this (puted together all the bullets):
// (double) buffering
gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT); // non eed for the depth although
// here set matrices in case they are not persistent
gl.glMatrixMode(gl.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glMatrixMode(gl.GL_PROJECTION);
gl.glLoadIdentity();
// here set/reset config the pipeline
gl.glDisable(gl.GL_DEPTH_TEST);
gl.glDisable(gl.GL_TEXTURE_2D);
gl.glLineWidth(1.0);
// here render
double x;
gl.glColor3d(0.0, 0.0, 0.0);
gl.glBegin(gl.GL_LINE_STRIP);
for (x=-180.0;x=<180.0;x+=0.01)
gl.glVertex2d(x/180.0, Math.sin(Math.toRadians(x)));
gl.glEnd();
// (double) buffering
gl.glFlush();
SwapBuffers(hdc);
I do not code in JAVA so instead of SwapBuffers(hdc); use whatever you got in JAVA for the same purpose. Hope I did not make any mistake while translating to JAVA.
For more info see:
simple complete GL+VAO/VBO+GLSL+shaders example in C++

Stereo rendering a sphere with cardboard

I'm making a 360 media player with Cardboard SDK in android (actually I'm using the new GoogleVR SDK, but it works pretty much alike). To do this I'm following this code:
Everything works great with a monocular vision and with a stereo one when not distorted (cardboardView.setDistortionCorrectionEnabled(false)). But when I try to use the distortion correction it draws this:
I've found this in the GVR API:
If distortion correction is enabled the GL context will be set to draw
into a framebuffer backed by a texture at the time of this call, so if
an implementor need to change the framebuffer for some rendering stage
then the implementor must reset the framebuffer to the one obtained
via glGetIntegerv(GL_FRAMEBUFFER_BINDING, ...) afterwards.
But I'm not sure if this is related.
This is my onDrawEye code:
/**
* Draws a frame for an eye.
*
* #param eye The eye to render. Includes all required transformations.
*/
#Override
public void onDrawEye(Eye eye) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
Matrix.multiplyMM(mView, 0, eye.getEyeView(), 0, mCamera, 0);
Matrix.multiplyMM(mViewProjectionMatrix, 0, mProjectionMatrix, 0, mView, 0);
mSphere.draw(mViewProjectionMatrix);
checkGLError("onDrawEye");
}
Any ideas how to solve this? Thanks so much
(By the way, if I draw a cube instead of a sphere everything works well)
Alright, almost 2 months later I finally solved my problem. If someone wants to know how, it was not a problem of gvr but how I was initializing my scene. Basically i moved every work in the Sphere constructor to the draw method but the shaders initiallization.

can't render shape in openGL

I was trying to follow example codes to simply display a rectangle on a black background, but it didn't seem to be displaying. What I did was
private static void initGL(){
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,Display.getWidth(),0,Display.getHeight(),-1,1);
glMatrixMode(GL_MODELVIEW);
glDisable(GL_DEPTH_TEST); //2D mode
glColor3f(0.5f, 0.0f, 1.0f);
glBegin(GL_QUADS);
glVertex2f(-0.75, 0.75);
glVertex2f(-0.75, -0.75);
glVertex2f(0.75, -0.75);
glVertex2f(0.75, 0.75);
glEnd();
}
It doesn't display anything on the screen except for a black background. Does anyone know what I might have done wrong? I'm using lwjgl in eclipse.
First things first: You only have to run the whole
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,Display.getWidth(),0,Display.getHeight(),-1,1);
glMatrixMode(GL_MODELVIEW);
thing once during your program, probably shortly after you run Display.create().
Also, you're tessellating using the wrong vertices. You wrote
glVertex2f(-0.75, 0.75);
glVertex2f(-0.75, -0.75);
glVertex2f(0.75, -0.75);
glVertex2f(0.75, 0.75);
which means draw a rectangle from (-0.75, -0.75) pixels to (0.75, 0.75) pixels. This is too small to be noticed. My guess is you assumed glVertex2f deals with fractions of the display width. It does not. glVertex2f deals with actual coordinates, it just allows fractional pixels, unlike glVertex2i (this is useful believe it or not, it helps with smoother animations). Something like
glVertex2f(100F, 100F);
places a vertex at (100, 100), and is effectively equivalent to
glVertex2i(100, 100);
Also, remember that negative pixels will be rendered off the screen, because OpenGL's origin of the coordinate system, (0, 0), is in the lower left and behaves like the first quadrant from the coordinate system in math class, not like the traditional computer coordinate system with (0, 0) in the upper left.
As for the the black background, LWJGL's Display has a black background by default, so it's recommended to draw a quad with your background color that covers the entire display width and height. One quad won't really affect your performance.
glVertex2f uses same size units as your glOrtho so unless your display width and height are in units of ones, like 10 or less, you may not see anything!

Trying to create spinning propeller. Keeps spinning around origin, not itself

I'm trying to create a spinning airplane propeller in Java 3D. At the moment, it is rotating around the origin. However, I need it to rotate around itself. I haven't done much 3D graphics in Java, so I'm pretty much stumped.
TransformGroup rotateTheBlades = new TransformGroup();
rotateTheBlades.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
Alpha rotationAlpha = new Alpha(-1,5000);
RotationInterpolator rotator = new RotationInterpolator(
rotationAlpha,rotateTheBlades);
Transform3D abc = new Transform3D();
abc.rotZ(Math.PI/2);
rotator.setTransformAxis(abc);
rotator.setSchedulingBounds(new BoundingSphere());
rotateTheBlades.addChild(rotator);
rotateTheBlades.addChild(propeller);
sceneBG.addChild(rotateTheBlades);
Any help would be greatly appreciated. PS: I tried to translate it to the origin before and after but it doesn't seem to do anything whatsoever.
Without knowing enough Java to give a complete answer; the correct solution in maths terms is as you suspect: translate centre of the object to origin, rotate, then translate it back to its original position.
However, it's likely (ie, I'm guessing) that when you combine transformations, they're post-multiplied to give the effect that transformations happen in model space. What you probably want is pre-multiplication, to give the effect that transformations occur in world space.
Consider the sails of a windmill. In code you'd want to be able to translate to the top of the windmill, then call the routine that draws the sails. That routine might apply a rotation and then draw. But in terms of transformations, you actually you want to rotate the sails while at the origin so that they rotate around their centre, then move them out. So the transformations are applied in the opposite order to the order in which you request them.
What that means is, you want to apply the transformations as:
move away from the origin
rotate
move to the origin
For example, if you were in OpenGL (which is also a post-multiplier, and easy enough to follow in this example even if you don't actually know it) you might do:
glTranslatef(centreOfBody.x, centreOfBody.y, 0.0f);
glRotatef(angle, 0.0f, 0.0f, 1.0f);
glTranslatef(-centreOfBody.x, -centreOfBody.y, 0.0f);
The approach suggested by #Tommy is correct. Like GL, transformations of the Java graphics context are concatenated "in the most commonly useful way," which I think of as last-in, first-out. A typical paintComponent() method is shown below and in this complete example.
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.translate(this.getWidth() / 2, this.getHeight() / 2);
g2d.rotate(theta);
g2d.translate(-image.getWidth(null) / 2, -image.getHeight(null) / 2);
g2d.drawImage(image, 0, 0, null);
}

OpenGL - Unable to render colors other than white after texture mapping

I'm trying to render a colored cube after rendering other cubes that have textures. I have multiple "Drawer" objects that conform to the Drawer interface, and I pass each a reference to the GL object to the draw( final GL gl ) method of each individual implementing class. However, no matter what I do, I seem unable to render a colored cube.
Code sample:
gl.glDisable(GL.GL_TEXTURE_2D);
gl.glColor3f( 1f, 0f, 0f );
gl.glBegin(GL.GL_QUADS);
// Front Face
Point3f point = player.getPosition();
gl.glNormal3f(0.0f, 0.0f, 1.0f);
//gl.glTexCoord2f(0.0f, 0.0f);
gl.glVertex3f(-point.x - 1.0f, -1.0f, -point.z + 1.0f);
//gl.glTexCoord2f(1.0f, 0.0f);
gl.glVertex3f(-point.x + 1.0f, -1.0f, -point.z + 1.0f);
//continue rendering rest of cube. ...
gl.glEnd();
gl.glEnable(GL.GL_TEXTURE_2D);
I've also tried throwing the glColor3f calls before each vertex call, but that still gives me a white cube. What's up?
There are a few things you need to make sure you do.
First off:
gl.glEnable(gl.GL_COLOR_MATERIAL);
This will let you apply colors to your vertices. (Do this before your calls to glColor3f.)
If this still does not resolve the problem, ensure that you are using blending properly (if you're using blending at all.)
For most applications, you'll probably want to use
gl.glEnable(gl.GL_BLEND);
gl.glBlendFunc(gl.GL_SRC_ALPHA,gl.GL_ONE_MINUS_SRC_ALPHA);
If neither of these things solve your problem, you might have to give us some more information about what you're doing/setting up prior to this section of your code.
If lighting is enabled, color comes from the material, not the glColor vertex colors. If your draw function that you mentioned is setting a material for the textured objects (and a white material under the texture would be common) then the rest of the cubes would be white. Using GL_COLOR_MATERIAL sets up OpenGL to take the glColor commands and update the material instead of just the vertex color, so that should work.
So, simply put, if you have lighting enabled, try GL_COLOR_MATERIAL.
One thing you might want to try is: glBindTexture(GL_TEXTURE_2D, 0); to bind the texture to nil.
Some things to check:
Is there a shader active?
Any gl-errors?
What other states did you change? For example GL_COLOR_MATERIAL, blending or lighting will change the appearance of your geometry.
Does it work if you draw the non-textured cube first? And if it does try to figure out at which point it turns white. It's also possible that the cube will only show up in the correct color in the first frame, then there's definitely a GL state involved.
Placing glPushAttrib/glPopAttrib at the beginning/end of your drawing methods might help, but it's better to figure out what caused the problem in the first place.

Categories

Resources