I just use FTGL to use it in my app. I want to use the version FTBufferFont to render font but it renders in the wrong way. The font(texture?buffer?) is flipped in the wrong axis.
I want to use this kind of orthographic settings:
void enable2D(int w, int h)
{
winWidth = w;
winHeight = h;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//I don't even want to swap the 3rd and 4th param
//because I like to retain the top-left as the origin
glOrtho(0, w, h, 0, 0, +1);
glMatrixMode(GL_MODELVIEW);
}
And I want the window origin to be top-left
I render the font like this:
//No pushing and popping of matrices
//No translation
font.Render("Hello World!", -1, position, spacing, FTGL::RenderMode::RENDER_FRONT);
On the other forums, they said, just scaled it down to -1, but it wont work in mine
I can't see relevant problem like in mine in google so I decide to ask this here again.
Update:
How can I flip its axis in a proper way. I can think of like editing the source code and flip the texture coordinates but its not good.
I really need a quick fix..
Related
I printed 4 dots using following code on renderScene:
glColor3f(0, 0, 0);
glPointSize(4.0f);
glBegin(GL_POINTS);
glVertex2f(0.9, 0.9);
glVertex2f(0.9, -0.9);
glVertex2f(-0.9, 0.9);
glVertex2f(-0.9, -0.9);
glEnd();
and this shows up:
four dots show up at corner
and if I try to draw triangles, 3/4 of it does not show on screen
like this:
3/4 of screen not shown
how can I fix this problem? thanks.
You have to adjust the viewport to the size of the default framebuffer. See glViewport:
glViewport(0, 0, width, height);
To clarify: width and height are the size of the framebuffer. This does not necessarily have to be the size of the window. When the display is scaled, the size of the framebuffer and the size of the window are different. You can get the size with glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT) (see glutGet). Please note that glut is an old library introduced before scalable displays even existed and the terminology WINDOW is misleading here:
int width = glutGet(GLUT_WINDOW_WIDTH);
int height = glutGet(GLUT_WINDOW_HEIGHT);
glViewport(0, 0, width, height);
try downloading this fix. http://iihm.imag.fr/blanch/software/glut-macosx/.
Finally add this line to your code:
#ifdef __APPLE__
glutInitDisplayString("rgba double depth hidpi");
#endif
This should fix your problem, it worked for me.
I am new to openGL and wondering how to redimension a window in opengl without resizing objects in it (for example a quad drawn in opengl). I currently have a simple C++ function such as :
void ProjectionOrtho::redimensionWindow(int width, int height)
{
glViewport(0, 0, width, height);
}
Here is a simple image to illustrate the problem:
Note : I have tried glViewPort(0,0, 665, 365) which are the initial height and weight of myBlueQuad, but that is not what i want since i want to be able to see the rest of the 3d universe to the right (for instance if i translate the quad to the right, i want to be able to see it)
Based on this thread: the difference between glOrtho and glViewPort in openGL I am pretty sure I need to use glOrtho but not sure how.. ive tried the following as #tkausl suggested:
glViewport(0, 0, width, height);
glOrtho(0, width, height, 0, -1.0, 1.0); //width and height of window panel
But unfortunately, i get the same result as before. It seems that glOrtho is never applied, i've also tried calling glLoadIdentity() before my glOrtho call, it has no effect on the end result.
The below code works perfectly fine with no fatal error but, when i use arguments "w","h" in "gluortho2d" as gluortho2d(0,w,h,0) in reshape function I get text on screen whereas if I put these arguments "0,0" as gluortho2d(0,0,0,0) I get shape of box.
How can I get both of them(box and text) simultaneously on screen?
#include"glut.h"
void drawBitmapText(char *string, float x, float y, float z);
void reshape(int w, int h);
void display(void);
void drawBitmapText(char *string, float x, float y, float z)
{
char *c;
glRasterPos3f(x, y, z);//define position on the screen where to draw text.
for (c = string; *c != '\0'; c++)
{
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, *c);
}
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();//Resets to identity Matrix.
gluOrtho2D(0, w, h, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void display(void)
{
glBegin(GL_POLYGON);//1
glVertex2f(-0.2, 0.6 - 0.3);
glVertex2f(-0.1, 0.6 - 0.3);
glVertex2f(-0.1, 0.5 - 0.3);
glVertex2f(-0.2, 0.5 - 0.3);
glEnd();
glColor3f(0, 1, 0);
drawBitmapText("Usama Ishfaq", 200, 400, 0);//drawBitmapText("Usama Ishfaq", x(how much right), y(how much down), z);
glutSwapBuffers();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("Usama OGL Window");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
By not following bad tutorials and placing calls to glViewport and projection matrix setup at the only place valid: The display function. Setting the viewport and projection matrix in the reshape handler is an anti-pattern. Don't do it.
Do this
void display(void)
{
int const w = glutGet(GLUT_WINDOW_WIDTH);
int const h = glutGet(GLUT_WINDOW_HEIGHT);
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();//Resets to identity Matrix.
gluOrtho2D(-1, 1, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBegin(GL_POLYGON);//1
glVertex2f(-0.2, 0.6 - 0.3);
glVertex2f(-0.1, 0.6 - 0.3);
glVertex2f(-0.1, 0.5 - 0.3);
glVertex2f(-0.2, 0.5 - 0.3);
glEnd();
/* viewport doesn't change in this
* application, but it's perfectly
* valid to set a different
* glViewport(...) here */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();//Resets to identity Matrix.
gluOrtho2D(0, w, h, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor3f(0, 1, 0);
drawBitmapText("Usama Ishfaq", 200, 400, 0);//drawBitmapText("Usama Ishfaq", x(how much right), y(how much down), z);
glutSwapBuffers();
}
Update (due to request in coments):
Why is it wrong to set the viewport and projection parameters in the reshape handler? Well, you just experienced the reason yourself: They are not "one size fits all" state and throughout rendering slightly more complex frames that go beyond just a mesh drawn, you're going to want to mix and match different viewports and projections throughout rendering. Here's a (incomplete) list of things that require to have different viewports and projections while rendering a single frame:
render-to-texture (FBO) – needs viewport withing the bounds of the texture, and usually also a different projection (important for shadow mapping, dynamic cubemaps and lots of other advanced, multipass rendering techniques)
minimaps / overview frames or similar in the corner (viewport covering just the corner)
text annotation overlays (different projection; usually a plain identity transform so to draw text rectangles directly in NDC space)
"magnifying glass" overlay
Since changing viewport and projection state happens multiple times in only slightly more complex OpenGL drawing, it makes
a) zero sense to set it in the reshape handler: whatever the handler sets will be set only at the beginning of the drawing of the first frame and thereafter the frame drawing code itself would have to reset to what the reshape handler sets. So why even bother doing it in the reshape handler at all?
b) placing viewport and projection setup code in the reshape handler a burden in the long run, because it might cause other parts of the program getting dependent on that. And if that happens, once you realize your mistake and try to move that viewport and projection setup code to where it belongs other parts of the program that relied on it being called from the reshape handler break and you have to fix those, too.
All in all, there are no reasons to place any drawing related calls (and glViewport and projection setup definitely are drawing related) in the reshape handler. Of course "one time" initialization is perfectly fine there, i.e. if you want to adjust the size of FBO render targets to match the window, or if you want to prepare an overlay image that later on gets applied repeatedly.
You can make this much simpler. For what you're doing, there's no need to bother with setting transformations at all.
It looks like, for the box, you're trying to use coordinates in the range [-1.0, 1.0] for both coordinate directions. This corresponds to the OpenGL NDC (Normalized Device Coordinates) coordinate system, which is the coordinate space vertices are in after both the modelview and projection transformations are applied. If you keep these at their default identity matrix, you can specify coordinates directly in NDC space. In other words, to use coordinates in the range [-1.0, 1.0], do... nothing at all, and just keep everything at its default.
The reason the box rendering works for you when you call:
gluOrtho2D(0.0, 0.0, 0.0, 0.0);
is that this call will result in an error, as documented on the man page:
GL_INVALID_VALUE is generated if left = right, or bottom = top, or near = far.
and will therefore keep the defaults untouched, which is exactly what you need.
Now, for the text, it looks like you want to specify the position in units of pixels. The problem you're having is that glRasterPos*() runs the specified coordinates through the transformation pipeline, meaning that, with the default identity modelview and projection transformations, it expects the input coordinates to be in the range [-1.0, 1.0] just like the coordinates you pass to glVertex2f().
Fortunately, there's a very easy way to avoid that. There's a very similar glWindowPos*() call, with the only difference that the coordinates passed to it are in window coordinates, which are in units of pixels.
So in summary:
Remove all glMatrixMode() calls.
Remove all glLoadIdentity() calls.
Remove all gluOrtho2D() calls.
In drawBitmapText(), replace the glRasterPos3f() call by:
glWindowPos2f(x, y);
The only thing to watch out for is that the origin of window coordinates is in the bottom left corner. So if your text position is given relative to the top left corner, you'll need something like:
glWindowPos2f(x, windowHeight - y);
To address some misleading information in another answer: It's perfectly fine to call glViewport() in the reshape() function, as long as you use the same viewport for all your rendering. In more complex applications, you will often need different viewports for different parts of the rendering (e.g. when you render to FBOs, or to only part of the window), so you will need to call glViewport() at the proper places during rendering. But for a simple example, where you do all your rendering to the entire window, there's nothing wrong with calling it in reshape().
When I do this:
SpriteBatch spriteBatch = new SpriteBatch();
spriteBatch.setProjectionMatrix(new Matrix4().setToOrtho(0, 320, 0, 240, -1, 1));
spriteBatch.begin();
spriteBatch.draw(textureRegion, 0, 0);
spriteBatch.end();
SpriteBatch will draw the textureRegion onto the coordinate system 320-240 that I have specified to the whole screen. Say I want to draw with the same coordinate system 320 240 but only on the left half of the screen (which means everything will be scaled down horizontally in the left side, leaving the right half of the screen black), how can I do?
You're going to want to use the ScissorStack. Effectively, you define a rectangle that you want to draw in. All drawing will be in the rectangle that you defined.
Rectangle scissors = new Rectangle();
Rectangle clipBounds = new Rectangle(x,y,w,h);
ScissorStack.calculateScissors(camera, spriteBatch.getTransformMatrix(), clipBounds, scissors);
ScissorStack.pushScissors(scissors);
spriteBatch.draw(...);
spriteBatch.flush();
ScissorStack.popScissors();
This will limit rendering to within the bounds of the rectangle "clipBounds".
It is also possible push multiple rectangles. Only the pixels of the sprites that are within all of the rectangles will be rendered.
From http://code.google.com/p/libgdx/wiki/GraphicsScissors
Before rendering the batch, you can set the viewport to draw on a specific screen area. The important line is:
Gdx.gl.glViewport(x, y, w, h);
The viewport usually starts at x = 0 and y = 0 and extends to the full width and height of the screen. If we want to see only a part of that original viewport, we need to change both the size and the starting position. To draw only on the left half of the screen, use:
x = 0;
y = 0;
w = Gdx.graphics.getWidth()/2;
h = Gdx.graphics.getWidth();
I found the solution here and originally answered this question to a slightly more complicated problem, but the technique is the same.
To focus on any different portion of the viewport, simply choose x, y, w, and h accordingly. If you're going to do any more rendering in the normal fashion, make sure to reset the viewport with the original x, y, w, and h values.
Perhaps I am misunderstanding the question, but could you not just double the viewport width, setting it to 640 instead of 320?
SpriteBatch spriteBatch = new SpriteBatch;
spriteBatch.setProjectionMatrix(new Matrix4().setToOrtho(0, 640, 0, 240, -1, 1));
spriteBatch.begin();
spriteBatch.draw(textureRegion, 0, 0);
spriteBatch.end();
You could either
double the viewport width of the SpriteBatch
use a Sprite and set its width scale to 0.5f (be careful about the origin) and use its draw(SpriteBatch) method to draw it.
I am using gluLookAt() to set the "camera" position and orientation
GLU.gluLookAt(xPosition, yPosition, zPosition,
xPosition + lx, yPosition, zPosition + lz
0, 1, 0);
my lz and lx variables represent my forward vector
lz = Math.cos(angle);
lx = -Math.sin(angle);
When turn around in the 3D world, it appears that I am rotating around an axis that is always infront of me
I know this because my xPosition and yPosition variables stay the same, but I appear to spin around an object when im close to it and I turn.
I know there is not a problem with the maths that I have used here, because I have tried using code from past projects that have worked properly but the problem still remains.
This is what I am doing in the rendering loop
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//draw scene from user perspective
glLoadIdentity();
GLU.gluLookAt(camera.getxPos(), camera.getyPos(), camera.getzPos(),
camera.getxPos()+camera.getLx(), camera.getyPos(), camera.getzPos()+p1.getLz(),
0, 1, 0);
glBegin(GL_QUADS);
glVertex3f(-dim, dim, 0);
glVertex3f(dim, dim, 0);
glVertex3f(dim, 0, 0);
glVertex3f(-dim, 0, 0);
glEnd();
pollInput();
camera.update();
I have tried rendering a box where the player coordinates are and I got this result. The camera appears to be looking from behind the player coordinates. To use an analogy right now its like a 3rd Person game and It should look like a first person game
The small box here is rendered in the camera coordinates, to give some perspective the bigger box is infront.
Solved!
The problem was that I was initially calling gluLookAt() while the matrix mode was set to GL_PROJECTION.
I removed that line and moved it to just after I had set the matrix mode to GL_MODELVIEW and that solved the problem.