OpenGL perspective projection and camera location - opengl

I am rendering a scene with some map image in OpenGL and using lat, lon of the map as coordinates directly. So my scene does not start at 0,0 and goes up to width, height. Although I can see my polygon (very small), I can't zoom by changing the z-value of the eye in the gluLookAt().
/*
* My boundary for map quad with texture
*/
#define TOP 41.9061
#define BOTTOM 41.8546
#define LEFT -87.7012
#define RIGHT -87.6054
/*
* window size
*/
const unsigned int window_width = 1024;
const unsigned int window_height = 739;
/*
* drawing a polygon with texture
*/
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, mainMapTextureId);
glBegin( GL_POLYGON );
//bottom left
glTexCoord2f( 0.0f, 1.0f );
glVertex3f(LEFT, BOTTOM, 0.0);
//bottom right
glTexCoord2f( 1.0f, 1.0f );
glVertex3f(RIGHT, BOTTOM, 0.0);
//top right
glTexCoord2f( 1.0f, 0.0f );
glVertex3f(RIGHT, TOP, 0.0);
//top left
glTexCoord2f( 0.0f, 0.0f );
glVertex3f(LEFT, TOP, 0.0);
glEnd();
/*
* Setting up the camera
*/
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLfloat)window_width/(GLfloat)window_height, 0.0, 10.0);
gluLookAt( (float)(LEFT+RIGHT)/2.0, (float)(TOP+BOTTOM)/2.0, 1.0,
(float)(LEFT+RIGHT)/2.0, (float)(TOP+BOTTOM)/2.0, 0.0,
0.0f, 1.0f, 0.0f);

It is not legal to have a value of 0.0 for the near plane of gluPerspective. Try replacing it with a nominal small value (0.1f).
Also always put a glGetError call in your code at the end, it will alert you to problems.

Related

opengl glDepthRange object disappearing on Z depth

Lines are dissapearing when z depth increases while rotating the object around x axis by 10 degrees. I edited the glDepthRange value to -100,100 or higher but nothing changes. How can i solve this?
void render()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
if( gRenderQuad )
{
glBegin( GL_LINE_LOOP );
glVertex3f(0.3f, 0.5f, 0.4f );
glVertex2f( -0.5f, -0.9f );
glVertex2f( 0.5f, -0.5f );
glVertex2f( 0.5f, 0.5f );
glVertex2f( -0.5f, 0.5f );
glEnd();
}
glDepthRange(-100,100);
glEnable(GL_DEPTH_TEST);
}
I edited the glDepthRange value to -100, 100
This is not possible. The values for the depth range must be in [0.0, 1.0]. You can just set a sub range of the range [0.0, 1.0]. See glDepthRange.
If you want to increase the viewing volume, you need to use a projection matrix. An Orthographic projection can be set with glOrtho:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, -100.0, 100.0);
glMatrixMode(GL_MODELVIEW);

OpenGL far clipping when using frustum

I'm using GLFW + OpenGL to try to make the "rotating cube". Although most of it is working, I have clipping in the far plane. I've tried changing values for frustum to very large numbers but it seems to have no effect.
int main(void) {
if (!glfwInit()) exit(EXIT_FAILURE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
GLFWwindow* window = glfwCreateWindow(640, 360, "3dTest", NULL, NULL);
if (!window) {
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glClearColor(0.5f, 0.5f, 0.5f, 1.0f); // Grey Background
float rotqube = 0;
while (!glfwWindowShouldClose(window)) {
// clear color and depth buffer for new frame
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// set up camera
glViewport(0, 0, 640, 360);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-100.0, 100.0, -100.0, 100.0, 100.0, -100.0);
// position camera
glTranslatef(0.0f, 0.0f, -2.0f); // Translate Into The Screen 2.0 Units
glRotatef(rotqube, 0.0f, 1.0f, 0.0f); // Rotate The cube around the Y axis
glRotatef(rotqube, 1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS); // Draw The Cube Using quads
glColor3f(0.0f, 1.0f, 0.0f); // Color Blue
glVertex3f(1.0f, 1.0f, -1.0f); // Top Right Of The Quad (Top)
glVertex3f(-1.0f, 1.0f, -1.0f); // Top Left Of The Quad (Top)
glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Quad (Top)
glVertex3f(1.0f, 1.0f, 1.0f); // Bottom Right Of The Quad (Top)
...
glColor3f(1.0f, 0.0f, 1.0f); // Color Violet
glVertex3f(1.0f, 1.0f, -1.0f); // Top Right Of The Quad (Right)
glVertex3f(1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Right)
glVertex3f(1.0f, -1.0f, 1.0f); // Bottom Left Of The Quad (Right)
glVertex3f(1.0f, -1.0f, -1.0f); // Bottom Right Of The Quad (Right)
glEnd(); // End Drawing The Cube
rotqube += 0.3f;
//Swap buffer and check for events
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate;
exit(EXIT_SUCCESS);
return 0;
}
This is what it looks like:
You are not using a perspective projection at all. Your call
glFrustum(-100.0, 100.0, -100.0, 100.0, 100.0, -100.0);
has no effect whatsever, besides setting the GL_INVALID_VALUE error state.
As stated in the OpenGL 2.0 specification, section 2.11 "Coordinate Transformations":
For
void Frustum( double l, double r, double b, double t, double n, double f );
the coordinates (l, b, −n)^T and (r, t, −n)^T
specify the points on the near clipping
plane that are mapped to the lower left and upper right corners of the window,
respectively (assuming that the eye is located at (0, 0, 0)^T). f gives the distance
from the eye to the far clipping plane. If either n or f is less than or equal to zero,
l is equal to r, b is equal to t, or n is equal to f, the error INVALID_VALUE results.
Trying to set a projection where one of the near or far planes lies behind the camera does not make the slightest sense, and would result in a lot of mathematical oddities during rendering (i.e division by zero for vertices lying on the camera plane), hence it is not allowed.
Since this function fails with an error, you are using the identity matrix as the projection matrix, and do end up with a orthographic projection.
Now having written all that, I must make you aware that all of this is completely outdated. The fixed function pipeline and the GL matrix stack, including functions like glFrustum, glLoadIdendity, glRotate, and immediate mode rendering using glBegin/glEnd are deprecated and have been removed form core profiles of OpenGL almost a decade ago. It is a really bad idea to try to learn this stuff in 2018, and I strongly advice you to learn modern OpenGL instead.
glFrustum(-100.0, 100.0, -100.0, 100.0, 100.0, -100.0);
^ wat
glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearVal, GLdouble farVal):
Parameters:
left, right:
Specify the coordinates for the left and right vertical clipping planes.
bottom, top:
Specify the coordinates for the bottom and top horizontal clipping planes.
nearVal, farVal:
Specify the distances to the near and far depth clipping planes.
Both distances must be positive.
Try something like 0.1 to 100.0:
glFrustum(-100.0, 100.0, -100.0, 100.0, 0.1, 100.0);

opengl draw in 2D coordinates instead of vertex coordinate system

how can i draw in 2D coordinates instead of vertex coordinate system, as this =>
drawPoint(50 , 100 , 0.01f);
this is my code , a background texture and a point
static void Draw(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
double w = glutGet( GLUT_WINDOW_WIDTH ) / 300.0;
double h = glutGet( GLUT_WINDOW_HEIGHT ) / 300.0;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glOrtho( -1 * w/2, 1 * w/2, -1 * h/2, 1 * h/2, w/2, -h/2);
glBegin(GL_POLYGON);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-w/2.f, -h/2.f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( w/2.f, -h/2.f, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( w/2.f, h/2.f, 0.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-w/2.f, h/2.f, 0.0f);
glEnd();
drawPoint(50 , 100 , 0.01f);
glutSwapBuffers();
}
the function DrawPoint => draws circles
void drawPoint(GLfloat x, GLfloat y, GLfloat radius){
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
int i;
int triangleAmount = 20; //# of triangles used to draw circle
//GLfloat radius = 0.8f; //radius
GLfloat twicePi = 2.0f * 3.1415;
glBegin(GL_TRIANGLE_FAN);
glColor3f(1.0, 0.0, 0.0);
glVertex2f(x, y); // center of circle
for(i = 0; i <= triangleAmount;i++) {
glVertex2f(
x + (radius * cos(i * twicePi / triangleAmount)),
y + (radius * sin(i * twicePi / triangleAmount))
);
}
glEnd();
glEnable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
}
So I don't know if I have to change the DrawPoint function.
UPDATE : this is my main source
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInit(&argc, argv);
glutInitWindowSize(widthX, heightY);
glutCreateWindow("prg");
glutReshapeFunc(resize);
glutDisplayFunc(Draw);
glutKeyboardFunc(keyPressed);
glutKeyboardUpFunc(keyUp);
texture[0] = SOIL_load_OGL_texture
(
"img.jpg",
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glEnable(GL_TEXTURE_2D);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glEnable(GL_POINT_SMOOTH);
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glutMainLoop();
UPDATE 2 :
if in this way is impossible, is there a method that transform an x and y into a vector ?, so for example :
DrawPoint(VectConvert(50),VectConvert(100),0.01f);
I am not sure if this is right answer. I edited your code, try this:
static void Draw(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// You divided your window width and height by 300 which seems to be wrong
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Create ortho 2d
// The last two parameters are near and far planes
// Since you are using only 2D you should keep them at 0.0 and 1.0
glOrtho( -1 * w/2.0, 1 * w/2.0, -1 * h/2.0, 1 * h/2.0, 0.0f, 1.0f);
// Mirror Y axis
glScalef(1, -1, 1);
// Now your coordinate system starts at center of your window
// You need to move it to the left top corner
glTranslatef(-(w/2.0f), -(h/2.0f), 0.0f);
texture[0] = SOIL_load_OGL_texture // load an image file directly as a new OpenGL texture
(
"img.jpg",
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_POLYGON);
// You need also to mirror your Y coordinates for texture
glTexCoord2f(0.0f, 1.0f); glVertex3f(0.0f , 0.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(w , 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(w , h , 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(0.0f , h , 0.0f);
glEnd();
drawPoint(50 , 100 , 0.01f);
glutSwapBuffers();
}
Also, do not load your texture from file every frame. It is overkill for your GPU.
Just set an ortogonal projection as you need it:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho( 0, w, h, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Please note a few things here:
This assumes that w and h are actually the width and height of your viewport.
I put this into the GL_PROJECTION matrix. That is where this stuff belongs. (Although it might not be critical in your use case).
I set the near and far planes to -1 and 1 respectively. I don't know what you actually will need, but your values didn't make any sense.
That will set up a coordinate system where the pixel centers are actually exactly between two integer values, and integer values denote the middle between two adjacent pixels, so (0,0) will be the top left corner of the top left pixel, and (w,h) the bottom right corner of the bottom left pixel.
You also could set up a mapping that maps the integers to the pixel centers, like glOrtho(-0.5, w-0.5, h-0.5, -0.5, -1, 1). Now (0,0) is the center of the top left pixel, and (w,h) is outside the screen, (w-1,h-1) is the center of the bottom right pixel.

Text color is not correct

void text(string str)
{
for (int i = 0; i < str.length(); i++)
{
glColor3f(0.0f, 0.0f, 0.0f);
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, str[i]);
}
}
void render(void)
{
int width = glutGet(GLUT_WINDOW_WIDTH);
int height = glutGet(GLUT_WINDOW_HEIGHT);
if (height == 0) height = 1;
GLfloat aspect = (GLfloat)width / (GLfloat)height;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_SCISSOR_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, aspect, 0.1f, 100.0f);
// Top view - top left
glViewport(0, 0, width/2, height/2);
glScissor(0, 0, width/2, height/2);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
PilotView(0.0f, 0.0f, -5.0f, 0.0f, 0.0f, 0.0f, 1.0f);
glRasterPos3f(-0.1f, -0.1f, 4.0f);
text("Front");
diode();
// Corner view - top right
glViewport(width/2, 0, width/2, height/2);
glScissor(width/2, 0, width/2, height/2);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
PilotView(0.0f, 0.0f, -5.0f, 0.0f, -90.0f, 0.0f, 1.0f);
glRasterPos3f(4.0f, -0.1f, 0.1f);
text("Right");
diode();
// Front view - bottom left
glViewport(0, height/2, width/2, height/2);
glScissor(0, height/2, width/2, height/2);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
PilotView(0.0f, 0.0f, -5.0f, 90.0f, 0.0f, 0.0f, 1.0f);
glRasterPos3f(-0.1f, 4.0f, 0.0f);
text("Top");
diode();
// Right view - bottom right
glViewport(width/2, height/2, width/2, height/2);
glScissor(width/2, height/2, width/2, height/2);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
PilotView(0.0f, 0.0f, -5.0f, 20.0f, 0.0f, 0.0f, 1.0f);
glRasterPos3f(-0.1f, 4.0f, 0.0f);
text("Fro4nt");
diode();
glDisable(GL_SCISSOR_TEST);
glutSwapBuffers();
}
I'm not sure where the white "Front" and the yellow "Top"/"Right" is coming from (in terms of color). They all should be black. Does anyone know what the issue is?
Here is what the output looks like:
As suspected, this may come as a shock but glRasterPos (...) actually tracks the "current" color when you call that function. That is, whatever color was set before glRasterPos (...) was called, applies as the "current color" for drawing operations at that position. Think of it almost as the rasterizer's analog to glVertex (...), as I will explain below.
You need to set the current color before you call glRasterPos (...), to that end you should remove the glColor3f (...) call completely from your text (...) function, or perhaps modify that function to do both - set the color and then the raster pos, then draw the text.
glRasterPos — specify the raster position for pixel operations:
The current raster position consists of three window coordinates (x, y, z), a clip coordinate value (w), an eye coordinate distance, a valid bit, and associated color data and texture coordinates.

Understanding GL coordinates - setting perspective and using gluLookAt

I'm using QGlWidget to draw a couple of points. The problems I'm having is that I seem to fail to set up the perspective properly and establish correct view on the points. I must be misunderstanding the coordinates somewhere or doing something else stupid, but after reading a bunch of guides and tutotrials I'm still stuck. The screen is black, no points. Here's the code:
void CGLWidget::initializeGL()
{
glEnable(GL_DEPTH_TEST);
glDisable(GL_ALPHA_TEST);
glDisable(GL_BLEND);
glEnable(GL_POINT_SPRITE);
glClearColor(0, 0, 0, 1);
assert (glGetError() == GL_NO_ERROR);
}
void CGLWidget::resizeGL(int w, int h)
{
glViewport(-w/2, -h/2, w/2, h <= 0 ? 1 : h/2);
glMatrixMode(GL_PROJECTION); //Switch to setting the camera perspective
//Set the camera perspective
glLoadIdentity(); //Reset the camera
gluPerspective(80.0, //The camera FoV
w/(double)h, //The width-to-height ratio
1, //The near z clipping coordinate
100); //The far z clipping coordinate
}
void CGLWidget::paintGL()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0);
glLoadIdentity();
glColor3i(255, 255, 255);
glBegin(GL_POINTS);
glVertex3d(0,0, -2);
glVertex3d(0,0, -3);
glVertex3d(0,0, +3);
glVertex3d(0,0, 0);
glVertex3f(-0.75f, -0.25f, -5.0f);
glEnd();
assert (glGetError() == GL_NO_ERROR);
}
I've tried manipulating z coordinate of the "eye" in gluLookAt to no avail, so I must be getting something else wrong.
To develop a more clear understanding of how gluPerspective() and gluLookAt() works, I recommend playing with the tutorials from Nate Robins, more specifically the projection demo.
Trust me, this is the droid you are looking for!
Anyway, a few days ago I wrote a spiced up version of Nehe lesson 5 (3D Shapes) in Qt:
GLWidget.cpp:
#include "GLWidget.h"
#include <iostream>
#include <QKeyEvent>
#include <QTimer>
GLWidget::GLWidget(QWidget *parent)
: QGLWidget(parent)
{
angle_tri = 0.f;
angle_quad = 0.f;
_eye_x = 0.f;
_eye_y = 0.f;
_mouse_is_moving = false;
_width = 0;
_height = 0;
}
GLWidget::~GLWidget()
{
}
void GLWidget::_tick()
{
update(); // triggers paintGL()
QTimer::singleShot(33, this, SLOT(_tick()));
}
void GLWidget::initializeGL()
{
// glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Black Background
// glClearDepth(1.0f); // Depth Buffer Setup
// glEnable(GL_DEPTH_TEST); // Enables Depth Testing
// glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
// glEnable ( GL_COLOR_MATERIAL );
// glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
_tick();
}
void GLWidget::paintGL()
{
if (_mouse_is_moving)
{
glMatrixMode ( GL_PROJECTION ); // Select The Projection Matrix
glLoadIdentity ( ); // Reset The Projection Matrix
gluPerspective ( 60, ( float ) _width / ( float ) _height, 1.0, 50.0 );
gluLookAt(0.0, 0.0, 2.0, // eye
_eye_x, _eye_y, 0.0, // center
0.0, 1.0, 0.0); // up
std::cout << "paintGL: eye " << _eye_x << "," << _eye_y << std::endl;
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glMatrixMode ( GL_MODELVIEW ); // Select The Model View Matrix
glLoadIdentity(); // Reset The Current Modelview Matrix
glPushMatrix();
glTranslatef(-1.5f,0.0f,-6.0f); // Move Left 1.5 Units And Into The Screen 6.0
glRotatef(angle_tri,0.0f,1.0f,0.0f); // Rotate The Triangle On The Y axis
glBegin(GL_TRIANGLES); // Drawing Using Triangles
glColor3f(1.0f,0.0f,0.0f); // Red
glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Front)
glColor3f(0.0f,1.0f,0.0f); // Green
glVertex3f(-1.0f,-1.0f, 1.0f); // Left Of Triangle (Front)
glColor3f(0.0f,0.0f,1.0f); // Blue
glVertex3f( 1.0f,-1.0f, 1.0f); // Right Of Triangle (Front)
glColor3f(1.0f,0.0f,0.0f); // Red
glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Right)
glColor3f(0.0f,0.0f,1.0f); // Blue
glVertex3f( 1.0f,-1.0f, 1.0f); // Left Of Triangle (Right)
glColor3f(0.0f,1.0f,0.0f); // Green
glVertex3f( 1.0f,-1.0f, -1.0f); // Right Of Triangle (Right)
glColor3f(1.0f,0.0f,0.0f); // Red
glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Back)
glColor3f(0.0f,1.0f,0.0f); // Green
glVertex3f( 1.0f,-1.0f, -1.0f); // Left Of Triangle (Back)
glColor3f(0.0f,0.0f,1.0f); // Blue
glVertex3f(-1.0f,-1.0f, -1.0f); // Right Of Triangle (Back)
glColor3f(1.0f,0.0f,0.0f); // Red
glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Left)
glColor3f(0.0f,0.0f,1.0f); // Blue
glVertex3f(-1.0f,-1.0f,-1.0f); // Left Of Triangle (Left)
glColor3f(0.0f,1.0f,0.0f); // Green
glVertex3f(-1.0f,-1.0f, 1.0f); // Right Of Triangle (Left)
glEnd(); // Finished Drawing The Triangle
glLoadIdentity(); // Reset The Current Modelview Matrix
glTranslatef(1.5f,0.0f,-9.0f); // Move Right 1.5 Units And Into The Screen 6.0
glRotatef(angle_quad,1.0f,0.0f,0.0f); // Rotate The Quad On The X axis
glBegin(GL_QUADS); // Draw A Quad
glColor3f(0.0f,1.0f,0.0f); // Set The Color To Green
glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Top)
glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Top)
glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Quad (Top)
glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Quad (Top)
glColor3f(1.0f,0.5f,0.0f); // Set The Color To Orange
glVertex3f( 1.0f,-1.0f, 1.0f); // Top Right Of The Quad (Bottom)
glVertex3f(-1.0f,-1.0f, 1.0f); // Top Left Of The Quad (Bottom)
glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Bottom)
glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Bottom)
glColor3f(1.0f,0.0f,0.0f); // Set The Color To Red
glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Front)
glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Front)
glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Front)
glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Front)
glColor3f(1.0f,1.0f,0.0f); // Set The Color To Yellow
glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Back)
glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Back)
glVertex3f(-1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Back)
glVertex3f( 1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Back)
glColor3f(0.0f,0.0f,1.0f); // Set The Color To Blue
glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Left)
glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Left)
glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Left)
glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Left)
glColor3f(1.0f,0.0f,1.0f); // Set The Color To Violet
glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Right)
glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Right)
glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Right)
glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Right)
glEnd(); // Done Drawing The Quad
glPopMatrix();
angle_tri += 3.2f; // Increase The Rotation Variable For The Triangle ( NEW )
angle_quad -= 3.15f; // Decrease The Rotation Variable For The Quad ( NEW )
}
void GLWidget::resizeGL( int w, int h)
{
_width = w;
_height = h;
glViewport ( 0, 0, w, h );
glMatrixMode ( GL_PROJECTION ); // Select The Projection Matrix
glLoadIdentity ( ); // Reset The Projection Matrix
if ( h==0 ) // Calculate The Aspect Ratio Of The Window
gluPerspective ( 60, ( float ) w, 1.0, 50.0 );
else
gluPerspective ( 60, ( float ) w / ( float ) h, 1.0, 50.0 );
gluLookAt(0.0, 0.0, 2.0, // eye
0.0, 0.0, 0.0, // center
0.0, 1.0, 0.0); // up
glMatrixMode ( GL_MODELVIEW ); // Select The Model View Matrix
glLoadIdentity ( ); // Reset The Model View Matrix
}
void GLWidget::mousePressEvent(QMouseEvent *event)
{
std::cout << "mousePressEvent:" << std::endl;
_mouse_is_moving = true;
}
void GLWidget::mouseReleaseEvent(QMouseEvent *event)
{
std::cout << "mouseReleaseEvent:" << std::endl;
_mouse_is_moving = false;
}
void GLWidget::mouseMoveEvent(QMouseEvent *event)
{
if (_mouse_x == 0)
_mouse_x = event->pos().x();
if (_mouse_y == 0)
_mouse_y = event->pos().y();
std::cout << "mouseMoveEvent: " << event->pos().x() << "," << event->pos().y() << std::endl;
if (event->pos().x() > _mouse_x)
{
_eye_x += 0.10;
}
else if (event->pos().x() < _mouse_x)
{
_eye_x -= 0.10;
}
if (event->pos().y() > _mouse_y)
{
_eye_y += 0.10;
}
else if (event->pos().y() < _mouse_y)
{
_eye_y -= 0.10;
}
_mouse_x = event->pos().x();
_mouse_y = event->pos().y();
}
GLWidget.h:
#include <QGLWidget>
class GLWidget : public QGLWidget
{
Q_OBJECT
public:
explicit GLWidget(QWidget* parent = 0);
virtual ~GLWidget();
/* OpenGL initialization, viewport resizing, and painting */
void initializeGL();
void paintGL();
void resizeGL( int width, int height);
/* enable the user to interact directly with the scene using the mouse */
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
private:
float angle_tri; // Angle For The Triangle
float angle_quad; // Angle For The Quad
float _eye_x;
float _eye_y;
bool _mouse_is_moving;
int _mouse_x;
int _mouse_y;
int _width;
int _height;
protected slots:
void _tick();
};
main.cpp:
#include <QApplication>
#include "glwidget.h"
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
GLWidget gl_widget;
gl_widget.show();
return app.exec();
}
I think what you've got there looks mostly correct, though your glViewport parameters look wrong. glViewport is supposed to be (left, bottom, width, height), but you're using something else.
Set glViewport to glViewport(0,0,width,height);.
For more explanation:
After transformation by modelViewProjection matrix (and perspective divide), all coordinates lie in what's known as Normalized Device Coordinates (abbreviated as NDC). NDC ranges from -1 to 1 on each axis, which puts (0,0,0) right in the center of the viewing region.
When your point lies directly in front of the camera, this gets transformed to xy (0,0) in normalized device coordinates.
If you look at the formulas on glViewport, these map NDC to the actual pixels on the screen.
So if you supply (0,0,1024,768) as the parameters, it gets mapped as the following:
screen X = ( Xnd + 1 ) ( width / 2) + x;
screen Y = ( Ynd + 1 ) ( height / 2) + y;
Substituting our glViewport values:
screen X = ( 0 + 1 ) ( 1024 / 2) + 0;
screen Y = ( 0 + 1 ) ( 768 / 2) + 0;
screen X = ( 1 ) ( 1024 / 2) ;
screen Y = ( 1 ) ( 768 / 2) ;
screen X = ( 1 ) ( 512 ) ;
screen Y = ( 1 ) ( 384 ) ;
screen X = 512 ; //center of screen X
screen Y = 384 ; //center of screen Y
Your near value is quite large to be honest, usually this has to be a low value so that if you have a 2D environment as your example you can still render objects. I would say a 0.1(0.5) for the near value of the perspective should go nicely.
Note: If you set the near value to be a big number your geometry will be clipped by the camera (perspective frustum).