I'm trying to get my depth buffer working for a 3D game engine written with LIBGDX, so that I don't have to sort my objects by their Z every frame. I believe I'm missing a critical step in setting the depth of my shapes. In my render function, I have this code:
Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
Gdx.gl.glDepthFunc(GL20.GL_LESS);
Gdx.gl.glDepthRangef(0, 2000);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
And in my draw function for all of my different shapes I'm using setColor like this:
GDX.renderer.setColor(r, g, b, depth);
My efforts are having no effect on the order that anything is rendered. Am I setting the depth wrong? Is there more setup I need to do?
Related
So, ive currently made an LWJGL project and refactored most things the way I want, however now I am looking to move an object the way it should be done. So far the code I have creates a red square to the screen, but its a lot of code just for a square and im looking to do something like, square.moveRight(float x) or something like that, how would i go about this? Here is the code.
// Poll for MyWindow events. The key callback above will only be
// invoked during this call.
glfwPollEvents();
glBegin(GL_QUADS);
glColor4f(1,0,0,0);
glVertex2f(-0.5f,0.5f);
glVertex2f(0.5f,0.5f);
glVertex2f(0.5f,-0.5f);
glVertex2f(-0.5f,-0.5f);
glEnd();
myWindow.swapBuffers();
Take a look at model matrices: http://wiki.lwjgl.org/wiki/The_Quad_with_Projection,_View_and_Model_matrices.html below "Moving, rotating and scaling our object". Basically you create a new 4x4 identity matrix, multiply it by a translation matrix and pass it to LWJGL.
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.
I wrote some code to load a .obj file one triangle at a time in 3d. Each of these triangles are placed in the correct location, and are given a random color. When the full shape is loaded some triangles, even though they are placed in front of the others, go to the back and are not seen.
http://postimg.org/image/ln31rhabd/
The website above shows how the triangles Behind the cone are showing up OVER the ones in-front. the cone is being looked at from a top-front angle.
What do I have to do to make the ones on top actually show up on top? Do they stack in the order that each triangle was created?
At the outset, i believe the problem is related to Depth Buffering.
Try enabling z-buffering in by calling the following functions:
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
And also, do check if you are clearing the z-buffers along with the color buffers.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
This is a continuation of my previous problem and post, seen here. Thanks to the answer I received there I feel I was able to get a little closer to my goal, as well as further my learning of OpenGL, but shortly after figuring out the basics of working with stencil buffers, I've run into a problem.
It seems that when I draw a sprite to the stencil buffer, it draws the entire square area, rather than just the pixels that aren't fully transparent as I had ignorantly hoped. I vaguely understand why it happens that way, but I am not sure where the solution lies. I have experimented with the stencil itself quite a bit, and I have modified the shaders that the spritebatch uses to discard low-alpha fragments, but I seem to be failing to see the bigger picture.
As a visual example of the problem, I will continue with the examples I used in the previous question. Right now, trying to draw two circles over each other (So they blend perfectly, no overlapping), I am getting this :
So, basically, is there a way for me to utilize stencil buffers using the Sprite and SpriteBatch functionality of LibGDX on complex shapes (Circles are only being used as an example), or do I need to look for an alternative route?
EDIT ::
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
Gdx.gl.glEnable(GL20.GL_BLEND);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
Gdx.gl.glDepthMask(true);
batch.begin();
sprite.draw(batch);
sprite2.draw(batch);
batch.end();
Gdx.gl.glDisable(GL20.GL_DEPTH_TEST);
Stencil writing/testing happens at the fragment level. When you draw a circle, you are actually drawing a quad of fragments where each fragment may or may not be textured. The issue of the matter is that the GPU doesn't care what color you write into the fragment when it does the stencil test for the fragment. Therefore, you need to discard fragments to stop the stencil writes for the parts of the quad where you don't want to write stencil values.
TL;DR Use "if(gl_FragColor.a < 0.01) discard;" in the fragment shader to make sure a circle of fragments (and stencil values) are generated.
Mby this helps.
I solve same problem with blending and depth test.
First you need clear depth and color bit.
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
Then you need enable some gl features:
Gdx.gl.glEnable(GL20.GL_BLEND);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glEnable(GL10.GL_DEPTH_TEST);
Gdx.gl.glDepthMask(true);
After that you can draw your objects. In my project smtng like this:
shapeRenderer.setColor(c.getR(), c.getG(), c.getB(), FIELD_ALPHA);
shapeRenderer.filledCircle(p.getPos().x + s.getOffset().x, ApplicationEnv.SCREEN_HEIGHT - p.getPos().y + s.getOffset().x, b.getRadius());
Important! After drawing you call end() for your spriteBatch (or something else) and disable depth_test feature:
Gdx.gl.glDisable(GL10.GL_DEPTH_TEST);
Result:
Before
After
In the two attached pictures, the desktop screenshot of libgdx functions as expected. The screenshot from my Galaxy Nexus is unfortunately not as expected. I am attempting to create a simple motion blur or trail effect.
Rendering as I expected on my desktop.
Not rendering as I expected on my Galaxy nexus.
The circle textures are drawn in a for loop during rendering and the effect is achieved with a pixmap using the RGBA of 0, 0, 0, 0.1f that is drawn before the circles.
screenClearSprite creation
Pixmap screenClearPixmap = new Pixmap(256, 256, Format.RGBA8888);
screenClearPixmap.setColor(Color.rgba8888(0, 0, 0, 0.1f));
screenClearPixmap.fillRectangle(0, 0, 256, 256);
screenClearTexture = new Texture(screenClearPixmap);
screenClearSprite = new Sprite(screenClearTexture);
screenClearSprite.setSize(screenWidth, screenHeight);
screenClearPixmap.dispose();
Render
batch.begin();
font.draw(batch, "fps:" + Gdx.graphics.getFramesPerSecond(), 0, 20);
screenClearSprite.draw(batch);
for (int i = 0; i < circleBodies.size(); i++) {
tempPos = circleBodies.get(i).getPosition();
batch.draw(circleTexture, (tempPos.x * SCALE) + screenWidthHalf
- circleSizeHalf, (tempPos.y * SCALE) + screenHeightHalf
- circleSizeHalf);
}
batch.end();
So, what did I do wrong? Perhaps there is a better way to get the 'motion blur' effect of movement?
Here is a different approach, where you clear your screen each time with solid color and no alpha.
This means that you will have to modify your code some. The good thing about this, is that the way you are doing it has some flaws: It will blur everything in motion, not just the balls. And can quickly produce ugly results/artefacts unless you are careful.
Do the same as you are doing now, but instead of drawing the balls to the batch, draw them onto a texture/bitmap/whatever. Then each frame add an alpha-blended image over the balls-image, and then draw the balls in their current position on top of that. Then add that image to your screen. Very much like you are doing now, except you draw to something else and keep it. This way you don't have to rely on the viewport you are drawing onto, and can keep everything separated.
This method is similar to drawing to an accumulation buffer.
Instead of doing it the way you are doing, you can keep track of the n latest positions of each ball. And then draw all of them each frame, with different alpha. This is very easy to implement. Can result in many drawing calls if you have many balls or a large n, but if it's not too much it shouldn't limit your fps and gives nice control.
Perhaps there is a better way to get the 'motion blur' effect of
movement?
in order to make motion blur in my game i use another approch "The particle effect" it works realy fine with me and i didn't have Android/Desktop problems or with different android devices
all you have to do is to use "Particle Effect Editor" of Libgdx and make your effect then load it in your project finally draw it at the same position you draw your object (and alos draw your object)
Tips to make the right effect file with Paticle Editor :
set (use) the same image of the object that you want to blur it motion in the particle effect
try to limit the count : the max number of particle allowed
Disable the "velocity" and "Angle"
parameter
Particle effect help to do motion effect
Hope this will help someone !