I'm working on a painting application using the LibGDX framework, and I am using their FrameBuffer class to merge what the user draws onto a solid texture, which is what they see as their drawing. That aspect is working just fine, however, the area the user can draw on isn't always going to be the same size, and I am having trouble getting it to display properly on resolutions other than that of the entire window.
I have tested this very extensively, and what seems to be happening is the FrameBuffer is creating the texture at the same resolution as the window itself, and then simply stretching or shrinking it to fit the actual area it is meant to be in, which is a very unpleasant effect for any drawing larger or smaller than the window.
I have verified, at every single step of my process, that I am never doing any of this stretching myself, and that everything is being drawn how and where it should, with the right dimensions and locations. I've also looked into the FrameBuffer class itself to try and find the answer, but strangely found nothing in there either, but, given all of the testing I've done, it seems to be the only possible place for this issue to be created somehow.
I am simply completely out of ideas, having spent a considerable amount of time trying to troubleshoot this problem.
Thank you so much Synthetik for finding the core issue. Here is the proper way to fix this situation that you elude to. (I think!)
The way to make frame buffer produce a correct ratio and scale texture regardless of actual device window size is to set the projection matrix to the size required like so :
SpriteBatch batch = new SpriteBatch();
Matrix4 matrix = new Matrix4();
matrix.setToOrtho2D(0, 0, 480,800); // here is the actual size you want
batch.setProjectionMatrix(matrix);
I believe I've solved my problem, and I will give a very brief overview of what the problem is.
Basically, the cause of this issue lies within the SpriteBatch class. Specifically, assuming I am not using an outdated version of the class, the problem lies on line 181, where the projection matrix is set. The line :
projectionMatrix.setToOrtho2D(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
This is causing everything that is drawn to, essentially, be drawn at the scale of the window/screen and then stretched to fit where it needs to afterwards. I am not sure if there is a more "proper" way to handle this, but I simply created another method within the SpriteBatch class that allows me to call this method again with my own dimensions, and call that when necessary. Note that it isn't required on every draw or anything like that, only once, or any time the dimensions may change.
Related
To make things short, a GL texture is allocated and created prior to my code running (I cannot prevent the first texture from being created, but I know the GL id that it is attached to). I need to redefine that existing texture using a buffered image that is twice the size of the old image. Does anybody know how to approach doing something like this? Based on some Google searches, it would look like I need to use glTexSubImage2D, but I'm not sure how.
Any help on the matter would be useful, Thanks
In my understanding you cannot replace in-place the texture, you have to allocate a new texture and on the next rendering, you will have to remap the texture index when you do the rendering.
The OpenGL is to high level to have access to previous textures memory and edit it.
There is a tutorial to change on the same shape a specific texture:
http://nehe.gamedev.net/tutorial/playing_avi_files_in_opengl/23001/
I was searching for an anti-aliasing algorithm for my OpenGL program (so I searched for a good shader). The thing is, all shaders want to do something with the textures, but I dont use textures, only colors. I looked at FXAA most of the time, so is there a anti-aliasing algorithm that just works with colors? My game, what this is for looks blocky like minecraft, but only works with colors and cubes of different size.
I hope someone can help me.
Greetings
Anti-aliasing has nothing specifically to do with either textures or colors.
Proper anti-aliasing is about sample rate, which while highly technical can be thought of as doing extra work to make a better educated guess at some value that cannot be directly looked up (e.g. a pixel that is only partially covered by a triangle).
Multisample Anti-Aliasing (MSAA) will work nicely for you, it will only anti-alias polygon edges and does nothing for texture aliasing on the interior of a polygon. Since you are not using textures you do not need to worry about aliasing inside a polygon.
Incidentally, FXAA is not proper anti-aliasing. FXAA is basically a shader-based edge detection and blur image processing filter. FXAA will blur any part of the scene with sharp edges, whether it is a polygon edge or an edge due to a mapped texture. It indiscriminately blurs anything it thinks is an aliased edge and gets this wrong often, resulting in blurry textures.
To use MSAA, you need:
A framebuffer with at least 2 samples
Enable multisample rasterization
Satisfying (1) is going to depend on what you used to create your window (in this case LWJGL). Most frameworks let you select the sample count as one of the parameters at the time of creation.
Framebuffer Objects can also be used to do this without messing with your window's parameters, but they are more complicated than need be for this discussion.
(2) is as simple as calling glEnable (GL_MULTISAMPLE).
I have been trying to "cut" an image for some time now, I ll explain why and what I tried.
So I wanted to create an hp "bar" except it's not a bar but a heart and so I though it would be easy all I had to do is have two pictures draw them on top of each other and then just cut one to make it appear as in hp was being lost, but I was not able to find a way to cut the image.
Setting the height just resizes the image as you might have guessed
I tried using textureRegion to kind of hack it but it didn't go so well
I found a method called clip begin which also uses scissors but for some reason that just doesn't seem to be working.
I might be using the clip begin wrong but I can't really find any real documentation on it, all I'm doing is:
image.clipBegin(x,y,height,weight);
image.clipEnd();
I almost forgot, I'm using a scene2d Image, might be a better way to go around it but not sure what that would be.
I would appreciate any ideas on how to do this, thank you.
You want to use the OpenGL Scissor support that Libgdx exposes. See the Libgdx Clipping wiki
and the Libgdx ScissorStack documentation.
The API isn't particularly friendly (its designed to support dynamically pushing multiple constraining rectangles, which as far as I've seen, isn't used very often).
The important point to remember with the scissor stack is that it only applies to actual draw commands that get issued. Since most APIs try to batch up draw commands, this means actual drawing might not happen when it looks like it should happen. To ensure clipping is happening you must flush any buffered draws before pushing the scissor (otherwise the wrong thing might get clipped) and you must flush any draw calls before popping the scissor (otherwise things you want clipped might avoid the scissors).
See libgdx ScissorStack not working as expected or libGDX - How to clip or How to draw on just a portion of the screen with SpriteBatch in libgdx? or Making a Group hide Actors outside of its bounds.
I'm trying to put textures into my Java OpenGL scene but when I do the colours of other things get skewed, as if it is blending the colours incorrectly. I am using LWJGL for OpenGL and Slick for loading the textures. When I leave the GL11.glEnable(GL11.GL_TEXTURE_2D); call uncommented the colours are darkened, but when I comment that one line the colours are correct, however I obviously have no textures.
I have put my code here http://codepaste.net/26bguu
The line in question is line 63
One work around I have found is enabling textures just before I draw the textures, then disabling again immediately after. However I feel this should be unnecessary. Below are some screenshots showing what I mean. The only difference being that one line commented vs uncommented.
You do actually need to enable and disable GL_TEXTURE_2D as required.
If GL_TEXTURE_2D is enabled, the GL will (normally) ignore the vertex colors you supply, and instead map the given texture coordinates to the given texture to get the color for each fragment/pixel. If you don't pass it texture coordinates, anything could happen - like, say, the second screenshot you have posted.
It's not uncommon to have to make 20+ opengl calls to prepare for drawing each "object". This is why OpenGL programmers spend large amounts of time combining large numbers of triangles into single buffers to be drawn at once with a single draw call - it greatly improves performance.
As part of a larger project I'm trying to implement a facility using JOGL that will export 3D renderings to bitmap formats. We do this by creating a GLJPanel and drawing the scene we want to it, then extracting the bitmap. This all works fine as long as the system has at least one visible window on the screen - not necessarily the window containing the panel we are drawing to.
But if we try to do this without making any window visible the GLJPanel won't draw. Stepping through the JOGL source I find that it won't draw unless it has a valid peer - essentially unless addNotify() has been called on it. The documentation says that addNotify() is only called when the panel is made part of a visible window heirarchy. Changing to a GLCanvas doesn't make much difference - the failure mode is different. WindowsOnscreenGLDrawable.realized is not set, and this means lockSurface returns LOCK_SURFACE_NOT_READY, causing makeCurrent() to fail.
Any help would be welcome on how to create a Java app that can create and export 3D scenes without having to make it's window visible.
Not sure if I should be answering my own question, but here goes with what I found seems to work now.
The key is GLPbuffer, which is an offscreen GLAutoDrawable and can be created without a visible component heirarchy.
This article was helpful in getting it to work. I'll leave off accepting this answer until I've confirmed it's fully functional.
I should also say that the answer came from this forum, not my own meagre brain.
You should look into method: glReadPixels() more info here. Basically it works more or less like this:
Init(); //doing some initializations in your JOGL app
glDrawBuffer(GL_BACK);
DrawGLScene(); //doing drawing here
glReadBuffer(GL_BACK);
//Copy the image to the array imageData
glReadPixels(0, 0, WIDTH, HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, imageData);