I would like to draw some overlay on my image viewer : a dashed rectangle around the image, indicating the bounding box.
Here 's what I do in the paintEvent function:
void ViewerGL::paintEvent(QPaintEvent* event){
makeCurrent();
QPainter p(this);
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT); // << If I don't do this it clears out my viewer white
// and I want it black
p.setBackgroundMode(Qt::TransparentMode); // < was a test, doesn't seem to do anything
p.setBackground(QColor(0,0,0,0));
//loading the appropriate shader before texture mapping
if(rgbMode() && _shaderLoaded){
shaderRGB->bind();
}else if(!rgbMode() && _shaderLoaded){
shaderLC->bind();
}
paintGL(); // render function (texture mapping)
//drawing a rect around the texture on the viewer
QPen pen(Qt::DashLine);
pen.setColor(QColor(233,233,233));
p.setPen(pen);
QPoint btmRight=mousePosFromOpenGL(dataWindow().w(),dataWindow().h() +transY*2 + ( zoomY-dataWindow().h()/2)*2);
QPoint btmLeft=mousePosFromOpenGL(0,dataWindow().h() +transY*2 + ( zoomY-dataWindow().h()/2)*2);
QPoint topLeft=mousePosFromOpenGL(0,0 +transY*2 + ( zoomY-dataWindow().h()/2)*2);
QPoint topRight=mousePosFromOpenGL(dataWindow().w(), 0+ +transY*2 + ( zoomY-dataWindow().h()/2)*2);
p.drawLine(topLeft,topRight);
p.drawLine(topRight,btmRight);
p.drawLine(btmRight,btmLeft);
p.drawLine(btmLeft,topLeft);
QPoint pos = mousePosFromOpenGL( (dataWindow().w()) + 10 ,
(dataWindow().h()) +transY*2 + ( zoomY-dataWindow().h()/2)*2 +10); // bottom right of the texture +10
p.drawText(pos, _resolutionOverlay);
p.end();
}
And here is what I do in the paintGL function:
glPushAttrib(GL_ALL_ATTRIB_BITS);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
... my drawing code
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glPopAttrib();
And the initializeGL function :
initAndCheckGlExtensions();
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glGenTextures (1, texId);
glGenTextures (1, texBlack);
glGenBuffersARB(1, &texBuffer);
shaderBlack=new QGLShaderProgram(context());
shaderBlack=new QGLShaderProgram(context());
if(!shaderBlack->addShaderFromSourceCode(QGLShader::Vertex,vertRGB))
cout << shaderBlack->log().toStdString().c_str() << endl;
if(!shaderBlack->addShaderFromSourceCode(QGLShader::Fragment,blackFrag))
cout << shaderBlack->log().toStdString().c_str() << endl;
if(!shaderBlack->link()){
cout << shaderBlack->log().toStdString().c_str() << endl;
}
So far it works, I have what I want, but my program is flooding stderr on exit with :
'QGLContext::makeCurrent: Cannot make invalid context current'.
I know this is coming from the QPainter and not from something else in my program.
I tried to move the code in the paintGL function to another function that is not virtual but that did not change anything.
You should first perform OpenGL calls, clear your OpenGL state, then wrap ALL QPainter draw calls between QPainter::begin(QGLWidget *) and QPainter::end(QGLWidget *).
Your program is most likely causing a problem because you interleave QPainter and OpenGL drawing calls. When you instantiate the QPainter object with QPainter(QPaintDevice *) you tell the QPainter to use the native drawing facilities of the QGLWidget to perform QPainter operations. So... QPainter uses OpenGL fixed-function calls to perform 2D drawing and it may interfere with your OpenGL rendering calls when your state has not been cleared.
I suggest following this guide:
https://doc.qt.io/archives/qt-4.8/qt-opengl-overpainting-example.html
Related
I am currently having a conflict between my paintGL() and my QPaintEvent function. I am trying to render a line that acts as a measuring tool to use on objects drawn in the paintGL(), however my current implementation renders a blank screen and I can't seem to figure out the problem. I've also tried placing the code from inside the paintEvent into the paintGL, this renders the objects inisde the paintGL but the line to be drawn from the QPainter does not work.
This is my paintEvent()
void Widget::paintEvent(QPaintEvent* e)
{
if (drawLine) {
QPainter painter(this);
QPen paintpen(Qt::red);
paintpen.setWidth(4);
QPen linepen(Qt::black);
linepen.setWidth(4);
QPoint p1;
p1.setX(xAtPress);
p1.setY(yAtPress);
painter.setPen(paintpen);
painter.drawPoint(p1);
QPoint p2;
p2.setX(xAtRelease);
p2.setY(yAtRelease);
painter.setPen(paintpen);
painter.drawPoint(p2);
painter.setPen(linepen);
painter.drawLine(p1, p2);
}
}
This is my paintGL()
void Widget::paintGL()
{
// Clear the color and depth buffer with specified clear colour.
// This will replace everything that was in the previous frame with the clear colour.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
test0->draw();
test1->draw();
test2->draw();
}
}
I apologize if this isn't exact. I'm doing the best I can to copy code by hand from one computer to another, and the destination computer doesn't have a compiler (don't ask).
Header file
#ifndef MYOPENGLWIDGET_H
#define MYOPENGLWIDGET_H
#include <qopenglwidget.h>
class MyOpenGlWidget : public QOpenGLWidget
{
Q_OBJECT
public:
explicit MyOpenGlWidget(QWidget *parent = 0, Qt::WindowFlags f = Qt::WindowFlags());
virtual ~MyOpenGlWidget();
protected:
// these are supposed to be overridden, so use the "override" keyword to compiler check yourself
virtual void initializeGL() override;
virtual void resizeGL(int w, int h) override;
virtual void paintGL() override;
private:
QPixmap *_foregroundPixmap;
}
#endif
Source file
QOpenGLFunctions_2_1 *f = 0;
MyOpenGlWidget::MyOpenGlWidget(QWidget *parent, Qt::WindowFlags f) :
QOpenGLWidget(parent, f)
{
_foregroundPixmap = 0;
QPixmap *p = new QPixmap("beveled_texture.tiff");
if (!p->isNull())
{
_foregroundPixmap = p;
}
}
MyOpenGlWidget::~MyOpenGlWidget()
{
delete _foregroundPixmap;
}
void MyOpenGlWidget::initializeGL()
{
// getting a deprecated set of functions because such is my work environment
// Note: Also, QOpenGLWidget doesn't support these natively.
f = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_2_1>();
f->glClearColor(0.0f, 1.0f, 0.0f, 1.0f); // clearing to green
f->glEnable(GL_DEPTH_TEST);
f->glEnable(GL_CULL_FACE); // implicitly culling front face
f->glEnable(GL_SCISSOR_TEST);
// it is either copy the matrix and viewport code from resizeGL or just call the method
this->resizeGL(this->width(), this->height());
}
void MyOpenGlWidget::resizeGL(int w, int h)
{
// make the viewport square
int sideLen = qMin(w, h);
int x = (w - side) / 2;
int y = (h - side) / 2;
// the widget is 400x400, so this random demonstration square will show up inside it
f->glViewport(50, 50, 100, 100);
f->glMatrixMode(GL_PROJECTION);
f->glLoadIdentity();
f->glOrtho(-2.0f, +2.0f, -2.0f, +2.0f, 1.0f, 15.0f); // magic numbers left over from a demo
f->glMatrixMode(GL_MODELVIEW);
// queue up a paint event
// Note: QGLWidget used updateGL(), but QOpenGLWidget uses update().
this->update();
}
void MyOpenGlWidget::paintGL()
{
f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// I want to draw a texture with beveled edges the size of this widget, so I can't
// have the background clearing all the way to the edges
f->glScissor(50, 50, 200, 200); // more magic numbers just for demonstration
// clears to green in just scissored area (unless QPainter is created)
f->glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
// loading identity matrix, doing f->glTranslatef(...) and f->glRotatef(...)
// pixmap loaded earlier in another function
if (_foregroundPixmap != 0)
{
// QPixmap apparently draws such that culling the back face will cull the entire
// pixmap, so have to switch culling for duration of pixmap drawing
f->glCullFace(GL_FRONT);
QPainter(this);
painter.drawPixmap(0, 0, _foregroundPixmap->scaled(this->size()));
// done, so switch back to culling the front face
f->glCullFace(GL_BACK);
}
QOpenGLFunctions_2_1 *f = 0;
void MyOpenGlWidget::initializeGL()
{
// getting a deprecated set of functions because such is my work environment
// Note: Also, QOpenGLWidget doesn't support these natively.
f = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_2_1>();
f->glClearColor(0.0f, 1.0f, 0.0f, 1.0f); // clearing to green
f->glEnable(GL_DEPTH_TEST);
f->glEnable(GL_CULL_FACE); // implicitly culling front face
f->glEnable(GL_SCISSOR_TEST);
// it is either copy the matrix and viewport code from resizeGL or just call it directly
this->resizeGL(this->width(), this->height());
}
void MyOpenGlWidget::resizeGL(int w, int h)
{
// make the viewport square
int sideLen = qMin(w, h);
int x = (w - side) / 2;
int y = (h - side) / 2;
// the widget is 400x400, so this random demonstration square will show up inside it
f->glViewport(50, 50, 100, 100);
f->glMatrixMode(GL_PROJECTION);
f->glLoadIdentity();
f->glOrtho(-2.0f, +2.0f, -2.0f, +2.0f, 1.0f, 15.0f); // magic numbers left over from a demo
f->glMatrixMode(GL_MODELVIEW);
// queue up a paint event
// Note: QGLWidget used updateGL(), but QOpenGLWidget uses update().
this->update();
}
void MyOpenGlWidget::paintGL()
{
f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// I want to draw a texture with beveled edges the size of this widget, so I can't
// have the background clearing all the way to the edges
f->glScissor(50, 50, 200, 200); // more magic numbers just for demonstration
// clears to green in just scissored area (unless QPainter is created)
f->glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
// loading identity matrix, doing f->glTranslatef(...) and f->glRotatef(...), drawing triangles
// done drawing, so now draw the beveled foreground
if (_foregroundPixmap != 0)
{
// QPixmap apparently draws such that culling the back face will cull the entire
// pixmap, so have to switch culling for duration of pixmap drawing
f->glCullFace(GL_FRONT);
QPainter(this);
painter.drawPixmap(0, 0, _foregroundPixmap->scaled(this->size()));
// done, so switch back to culling the front face
f->glCullFace(GL_BACK);
}
}
The problem is this code from paintGL():
QPainter(this);
As soon as a QPainter object is created, the glScissor(...) call that I made earlier in the function is overrun and some kind of glClearColor(...) call is made (possibly from QPainter's constructor) that clears the entire viewport to the background color that I set just after glScissor(...). Then the pixmap draws my beveled texture just fine.
I don't want QPainter to overrun my scissoring.
The closest I got to an explanation was two QPainter methods, beginNativePainting() and endNativePainting(). According to the documentation, scissor testing is disabled between these two, but in their example they re-enable it. I tried using this "native painting" code, but I couldn't stop QPainter's mere existence from ignoring GL's scissoring and clearing my entire viewport.
Why is this happening and how do I stop this?
Note: This work computer has network policies to prevent me from going to entertainment sites like imgur to upload "what I want" and "what I get" pictures, so I have to make due with text.
Why is this happening
The OpenGL context is a shared resource and you have to share it with other players.
and how do I stop this?
You can't. Just do the proper thing and set viewport, scissor rectangle and all the other drawing related state at the right moment: Right before you are going to draw something that relies on these settings. Don't set them aeons (in computer terms) before, somewhere in some "initialization" or a reshape handler. And be expected that in drawing code any function you call that makes use of OpenGL will leave some garbage behind.
I have some issues with my QOpenGLWidget resizing functionality. Obviously, I am aiming for a new viewport with the correct amount of pixels and a scene centered in the actual center of my window. But these two things are off somehow.
Here are some images:
Initial one:
Scaled in Y:
Scaled in X:
The result is pixelated and translated. For me it looks like the GL viewport has the correct amount of pixels, but is scaled to the top and to the right (if the (0,0) is defined as the bottom left corner).
Here is my code:
void GLWidget::initializeGL() {
QOpenGLFunctions::initializeOpenGLFunctions();
glClearColor(0.7f, 0.75f, 0.8f, 1.0f);
glEnable(GL_MULTISAMPLE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
void GLWidget::resizeGL(int w, int h) {
qreal aspect = qreal(w) / qreal(h ? h : 1);
const qreal zNear = 3, zFar = 7, fov = 3.14/6;
//I will leave this at it is. This cannot cause the viewport translation
mGraphics->setProjectionPers(fov, aspect, zNear, zFar);
}
void GLWidget::paintGL() {
glClear(GL_COLOR_BUFFER_BIT);
glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
//actual Drawing
//...
}
The resizeGL is called with the correct values. What am I doing wrong for having a pixelated and translated image when I run this piece of code?
For whatever reason this was in the header file of my QOpenGLWidget decendant:
void resizeEvent(QResizeEvent* ev) {
resizeGL(width(), height());
}
This pretty much skips all the resize logic of the QOpenGLWidget class.
I am preparing a desktop application to draw some 2D plots. I am using C++: Qt 5 and visual studio 2013. I created a simple GUI and put myQOpenGLWidget in it. I am already drawing the plots, axes and ticks using my own openGl shaders. Everything works fine and now I want to add the description to my axes and ticks to make the graph possible to analysis. As in OpenGL itself there is no dedicated functions to render text, I came up with using QPainter object just to add the desired description to already created plot. And here are problems starting...
Here is my functions of my QopenGLWidget implementation:
void GLWidget::initializeGL() {
initializeOpenGLFunctions();
glEnable(GL_POINT_SPRITE);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
vertexShad = new QOpenGLShader(QOpenGLShader::Vertex);
fragmentShad = new QOpenGLShader(QOpenGLShader::Fragment);
bool flag = vertexShad->compileSourceFile(QString("vs.glsl"));
if (flag) printf("compiled vertex Shader\n");
flag = fragmentShad->compileSourceFile(QString("fs.glsl"));
if (flag) printf("compiled fragment Shader\n");
flag = program.addShader(vertexShad);
if (flag) printf("linked vertex Shader\n");
flag = false;
flag =program.addShader(fragmentShad);
if (flag) printf("linked fragment Shader\n");
program.link();
program.bind();
}
paintGL:
void GLWidget::paintGL() {
painter = new QPainter(this);
painter->beginNativePainting();
glViewport(0, 0, this->width(), this->height());
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
drawAxes();
glViewport(MARGIN, MARGIN, this->width() - MARGIN * 2, this->height() - MARGIN * 2);
glScissor(MARGIN, MARGIN, this->width() - MARGIN * 2, this->height() - MARGIN * 2);
glEnable(GL_SCISSOR_TEST);
// here are the functions which use native openGL code
// ...
// disabling openGL settings
glDisable(GL_SCISSOR_TEST);
glDisable(GL_POINT_SPRITE);
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
glDisable(GL_BLEND);
painter->endNativePainting();
drawTicksValues(); // function that uses QPainter
painter->end();
}
drawTicksValues:
void GLWidget::drawTicksValues() {
char * maxText = new char[4];
sprintf(maxText, "%d", maxY);
char * minText = new char[4];
sprintf(minText, "%d", minY);
painter->drawText(0, MARGIN, QString(maxText));
painter->drawText(0, height() - MARGIN, QString(minText));
painter->drawText(MARGIN, height() - MARGIN + 20, QString("0"));
painter->drawText(width() - MARGIN, height() - MARGIN + 20, QString(100));
}
main:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QSurfaceFormat format;
format.setSamples(4);
format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
QSurfaceFormat::setDefaultFormat(format);
SymmGaitModels w;
w.show();
return a.exec();
}
Unfortunately, when I run the code, with uncommented QPainter part, the axis and plots are cleared, only the numbers I paint with QPainter are shown. But if I comment the QPainter part, the plots and axes are drawed normally. Any suggestions how I can add the text with QPainter to my plot instead of clearing it?
I finally managed to get things work.
First of all, I had to change and set the format (you have to change it before widget is shown), for example in main function , before my app was shown
main:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
SymmGaitModels w;
// GLWidget is my implemantation of QOpenGLWidget
GLWidget* gl = w.findChild<GLWidget*>("OpenGLWidget");
QSurfaceFormat format;
//format.setSamples(4);
//format.setDepthBufferSize(24);
//format.setStencilBufferSize(8);
format.setProfile(QSurfaceFormat::OpenGLContextProfile::CompatibilityProfile);
QSurfaceFormat::setDefaultFormat(format);
gl->setFormat(format);
w.show();
return a.exec();
}
Moreover, I had to move all (even enabling and disabling things like blend, point_sprite etc, which caused my problems) of my openGL functions between
QPainter-> beginNativePainting()
...
QPainter->endNativePainting();
And I had to implement paintEvent function. I just put paintGL() expression there.
Now my functions look like that:
void GLWidget::initializeGL() {
printf("autoFILL: %d\n",this->autoFillBackground());
initializeOpenGLFunctions(); // this function has to stay in initializeGL
// commented functions below has to be removed and put after beginNativePainting
//glEnable(GL_POINT_SPRITE);
//glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
//glEnable(GL_BLEND);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// shaders may be compiled and added here, but program has to be linked and built after beginNativePainting()
vertexShad = new QOpenGLShader(QOpenGLShader::Vertex);
fragmentShad = new QOpenGLShader(QOpenGLShader::Fragment);
bool flag = vertexShad->compileSourceFile(QString("vs.glsl"));
//bool flag = vertexShad->compileSourceCode(vertexShadSrc);
if (flag) printf("compiled vertex Shader\n");
flag = fragmentShad->compileSourceFile(QString("fs.glsl"));
//flag = fragmentShad->compileSourceCode(fragmentShadSrc);
if (flag) printf("compiled fragment Shader\n");
flag = program.addShader(vertexShad);
if (flag) printf("linked vertex Shader\n");
flag = false;
flag =program.addShader(fragmentShad);
if (flag) printf("linked fragment Shader\n");
}
void GLWidget::paintEvent(QPaintEvent *e) {
paintGL(); // still this, widget has to be now refreshed by widget->update()
}
void GLWidget::paintGL() {
painter = new QPainter(this);
painter->beginNativePainting();
//
glEnable(GL_POINT_SPRITE);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
program.link();
program.bind();
//
glViewport(0, 0, this->width(), this->height());
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
drawAxes();
glViewport(MARGIN, MARGIN, this->width() - MARGIN * 2, this->height() - MARGIN * 2);
glScissor(MARGIN, MARGIN, this->width() - MARGIN * 2, this->height() - MARGIN * 2);
glEnable(GL_SCISSOR_TEST);
// methods using native openGL functions here
glDisable(GL_SCISSOR_TEST);
glDisable(GL_POINT_SPRITE);
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
glDisable(GL_BLEND);
program.disconnect();
painter->endNativePainting();
drawTicksValues();
painter->end();
}
After adding paintEvent implementation, the openGL widget has to be now refreshed using widget->update().
Hope it will be helpful for other people who are struggling with using both QPainter and native openGL functions, as Qt doc seems to be a little shallow on this topic.
Thanks!
Adam
I would like to know how to draw the length of a line with respect to the the dimensions of the enclosing window. Note that I am using the combination of GLUT and OpenGL.
For example, say I wanted to draw a line from the bottom center of the screen (I assume this would be at coordinate (WINDOW_LENGTH/2, 0) to the center of the window (WINDOW_LENGTH/2, WINDOW_HEIGHT/2)
How do I do this in OpenGL? Right now I have the following:
//Initializes 3D rendering
void initRendering() {
//Makes 3D drawing work when something is in front of something else
glEnable(GL_DEPTH_TEST);
}
//Called when the window is resized
void handleResize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION); //Switch to setting the camera perspective
//Set the camera perspective
glLoadIdentity(); //
gluPerspective(45.0, (double)w / (double)h, 1.0, 200.0);
}
//Draws the 3D scene
void drawScene() {
//Clear information from last draw
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
glLoadIdentity(); //Reset the drawing perspective
glTranslatef(0, 0, -1);
glBegin(GL_LINES);
//lines
glVertex2f(0, 0);
glVertex2f(0, .25);
glEnd();
glutSwapBuffers(); //Send the 3D scene to the screen
}
int main(int argc, char** argv) {
//Initialize GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 400); //Set the window size
//Create the window
glutCreateWindow("Basic Shapes - videotutorialsrock.com");
initRendering(); //Initialize rendering
//Set handler functions for drawing, keypresses, and window resizes
glutDisplayFunc(drawScene);
//glutKeyboardFunc(handleKeypress);
glutReshapeFunc(handleResize);
cout << "GLUT_WINDOW_X: " << GLUT_WINDOW_X << endl;
cout << "GlUT_WINDOW_Y: " << GLUT_WINDOW_Y << endl;
glutMainLoop(); //Start the main loop. glutMainLoop doesn't return.
return 0; //This line is never reached
}
This gives me the following result:
What does not make sense to me is that my window has dimension 400 X 400 but the coordinates: glVertex2f(0, 0) and glVertex2f(0, .25). draw a line from about the center of the window to about 80% of the height of the window. I have a few speculations:
I know that my call to glTranslatef(0, 0, -1); sets the origin to the global coordinate (0, 0, -1) What is puzzling to me:
How does the -1 correspond to moving the image that far over?
Does the .25 in the second coordinate correspond to 25% of the height?
What would the code look like to draw a line from (WINDOW_LENGTH/2, 0) to (WINDOW_LENGTH/2, WINDOW_HEIGHT/2) That is the line from the bottom center of the window to the center of the window.
If you need more information let me know.
Let me try answer your questions:
You are working in a model-view (world to view) system. So you start modelling in world coordinates and transform it to the view coordinates. Therefore, glTranslatef is moving your world 1 coordinates points away from de camera.
What you do in openGL is weakly related to your windows coordinates. So, 0.25 really means 0.25 to openGL and nothing more. This means that you can stablish any semantics to points, like meters, kilometres, milimeters and so on. The correlation between openGL buffer and windows coordinates is stablished in the function gluPerspective, in which it says, basically, the region of your world that must be mapped to your windows coordinate system. The second function, glViewport only says how this map will be translated to you windows coordinates. In your case, you are telling to use all the windows.
As I said before, you need to manipulate your gluPerspective to control how much the openGL world will be mapped to your windows coordinates. To do that, you change the angle of the perspective. Greater angles, more openGL regions will be mapped, and you get an effect of zoom out. Lesser angles, less openGL regions will be mapped, and you get an effect of zoom in