redimension window without resizing objects in opengl and c++ - c++

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.

Related

How can I fix window size problem on Mac OS X OpenGL/glut?

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.

How do I flip upside down fonts in FTGL

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..

Object without deformations - OpenGL

Anybody knows how to keep a triangle without deformations and always at the middle of the windows whatever is his size?
I know I have to do one callback with reshape function and then define it, but I'm not sure what is going inside resize function:
void resize(int width, int height) {
viewport(0,0,width,height);
...?
}
I have this main help. glutInitWindowSize(600, 600);
Since the GL calls use normalised vertex coordinates ranging from -1 to +1, it is possible to keep any object in the center of the screen by using the right coordinates independent of the screen pixel sizes.
However, the same independency also brings in the behaviour that, depending on the screen aspect ratio (or window aspect ratio, as the case may be) the object will also change, unless explicitly accounted for. See the discussions in How can i convert an oval to circle openGL ES2.0 Android
Here's a important hint: Don't use the resize callback to do anything with OpenGL.
I know I have to do one callback with reshape function and then define it, but I'm not sure what is going inside resize function:
Then you knew wrong.
It leads to a lot of confusion. OpenGL is a state based drawing API and like all state machines it should be reset into a well known state before you use it. That includes projection and viewport. With that in mind your problem becomes trivial
void display()
{
/* draw some stuff */
glViewport(...);
setup_projection();
setup_modelview();
draw_stuff();
/* draw some other stuff with different projection and modelview */
glViewport(...);
setup_other_projection();
setup_other_modelview();
draw_other_stuff();
/* ... */
swapBuffers();
}
If you're using GLUT you can use glutGet(GLUT_WINDOW_WIDTH) and glutGet(GLUT_WINDOW_HEIGHT) to retrieve the window's size for the viewport calls.
So in your case you'd use a glViewport that covers your whole window and a projection that always maps a certain view space into that viewport. For example
void display()
{
int const win_width = glutGet(GLUT_WINDOW_WIDTH);
int const win_height = glutGet(GLUT_WINDOW_HEIGHT);
float const win_aspect = (float)win_width / (float) win_height;
glViewport(0, 0, win_width, win_height);
/* Using fixed function pipeline for brevity */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
/* map the vertical range -1…1 to the window height and
a symmetric range -aspect … 0 … +aspect to the viewport */
glOrtho(-win_aspect, win_aspect, -1, 1, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
draw_triangle();
/* ... */
glutSwapBuffers();
}

Qt OpenGL Rendering text issue QGLWidget

I'm using QGLWidget and this code to draw a text on the screen but the rendering is catastrophic if the string's length is too high :
Here's my code :
glPushMatrix();
glRotatef(90, 0, 0, 1);
QString qStr = QString("Here's a very long string which doesn't mean anything at all but had some rendering problems");
renderText(0.0, 0.0, 0.0, qStr);
glPopMatrix();
I had the exact same problem when using Helvetica. Changing the font to Arial solved it.
I did a small wrapper around it to make things easier:
void _draw_text(double x, double y, double z, QString txt)
{
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
qglColor(Qt::white);
renderText(x, y, z, txt, QFont("Arial", 12, QFont::Bold, false) );
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
}
From the documentation:
This function can only be used inside a QPainter::beginNativePainting()/QPainter::endNativePainting() block if the default OpenGL paint engine is QPaintEngine::OpenGL. To make QPaintEngine::OpenGL the default GL engine, call QGL::setPreferredPaintEngine(QPaintEngine::OpenGL) before the QApplication constructor.
Hence, have you tried to use QPainter::beginNativePainting() just before the call, and QPainter::endNativePainting() just after?
Also, note that the text is rendered in window coordinate, not taking into account at all your current OpenGL matrix state (in short, your glRotatef(90, 0, 0, 1) call has no effect). You can see in the implementation here that they save your current OpenGL state by calling qt_save_gl_state(), then create their brand new matrices with:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, width, height);
glOrtho(0, width, height, 0, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Then draw the text, and finally restore your previous OpenGL state with qt_restore_gl_state()

OpenGL Orthographic Projection Clipping

Assuming I use Orhographic Projection, and have a reshape function like this:
void reshape(f32 width, f32 height){
aspect = width/height;
glViewport(0, 0, width, height);
// guaranted 960x640 HUD canvas
if(640*aspect>=960){
ortho.x = 640*aspect;
ortho.y = 640;
}else{
ortho.x = 960;
ortho.y = 960/aspect;
}
glOrtho(0, ortho.x, ortho.y, 0, -1.0f, 1.0f);
}
How can I make sure, that all vertices >ortho.x or >ortho.y (normally offscreen) are didn't drawn?
Because if I scale the windows to something with a bigger aspect ratio than 1.5f (960/640) I see the objects, that schouldn't be full visible (because the viewport is so big like the window).
Is there something like a clipping pane in orthographic projection?
What you want is to use [glScissor][1] to ensure that the rendered area never goes beyond a certain size. glScissor takes a rectangle in window coordinates (remember: window coordinates have the origin at the bottom-left). The scissor test prevents the generation of fragments outside of this area.
To activate the scissor test, you must use glEnable(GL_SCISSOR). Unless you do that, the above call won't actually do anything.
Use constant values for the limit parameters of glOrtho, but use glViewport and glScissor (enable with glEnable(GL_SCISSOR_TEST)) to limit rendering to a sub-portion of your window.
BTW: You should set the projection and viewport in the rendering function. Doing it in the reshape handler makes not much sense. In any serious OpenGL application you'll switch projection modes several times during a full render, so just do it that way from the very beginning.