I need to show the same object in OpenGL in two different viewports, for instance, one using ortographic projection and the other using perspective. In order to do this, do I need to draw again the object after each call to glViewport()?
Nehe has a good tutorial on how to do this, and his site is generally a good resource for OpenGL questions.
// normal mode
if(!divided_view_port)
glViewport(0, 0, w, h);
else
{
// right bottom
glViewport(w/2, h/2, w, h);
glLoadIdentity ();
gluLookAt(5.0f, 5.0f, 5.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
display();
// left bottom
glViewport(0, h/2, w/2, h);
glLoadIdentity();
gluLookAt (5.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
display();
// top right
glViewport(w/2, 0, w, h/2);
glLoadIdentity();
gluLookAt(0.0f, 0.0f, 5.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
display();
// top left
glViewport(0, 0, w/2, h/2);
glLoadIdentity();
gluLookAt(0.0f, 5.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
display();
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-2.0, 2.0,
-2.0 * (GLfloat) h / (GLfloat) w, 2.0 * (GLfloat) h / (GLfloat) w,
-10.0, 100.0);
else
glOrtho(-2.0 * (GLfloat) w / (GLfloat) h, 2.0 * (GLfloat) w / (GLfloat) h,
-2.0, 2.0,
-10.0, 100.0);
glMatrixMode(GL_MODELVIEW);
Minimal runnable example
Similar to this answer, but more direct and compilable. Output:
main.c
#include <stdlib.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
static int width;
static int height;
static void display(void) {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f, 0.0f, 0.0f);
glViewport(0, 0, width/2, height/2);
glLoadIdentity();
gluLookAt(0.0, 0.0, -3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glutWireTeapot(1);
glViewport(width/2, 0, width/2, height/2);
glLoadIdentity();
gluLookAt(0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glutWireTeapot(1);
glViewport(0, height/2, width/2, height/2);
glLoadIdentity();
gluLookAt(0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0);
glutWireTeapot(1);
glViewport(width/2, height/2, width/2, height/2);
glLoadIdentity();
gluLookAt(0.0, -3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0);
glutWireTeapot(1);
glFlush();
}
static void reshape(int w, int h) {
width = w;
height = h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return EXIT_SUCCESS;
}
Compile and run:
gcc -o main.out main.c -lGL -lGLU -lglut
./main.out
I think that in modern OpenGL 4 you should just render to textures, and then place those textures orthogonaly on the screen, see this as a starting point: http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-14-render-to-texture/
Tested on OpenGL 4.5.0 NVIDIA 352.63, Ubuntu 15.10.
yes,
and you should also change the scissor settings to have a clean separation between the two views if they are in the same window.
In GL 4 you can render to many viewports in one rendering pass. See ARB_viewport_array and related concepts.
Think of OpenGL as being nothing more than commands which prepare you to output to the window you're currently working with.
There's two commands with OpenGL that even NEHE's tutorials don't tell you the importance of:
wglCreateContext - which takes a window device context DC, can be obtained from ANY window - whether it's a user control, a windows form, a GL window, or another application window (like notepad). This creates an OpenGL device context - they refer to as a resource context - which you later use with ...
wglMakeCurrent - which takes two parameters, the Device Context you're dealing with (the parameter passed in for the Windows Device Context in wglCreateContext) - and the Resource Context that returns.
Leveraging ONLY these two things - here's my advice:
NEHE's tutorial provides a solution that leverages the existing window ONLY and segments the screen for drawing. Here's the tutorial: http://nehe.gamedev.net/tutorial/multiple_viewports/20002/
Leveraging glViewport you'll need to re-draw on every update.
That's one method.
But there's another - less graphically and processor intense method:
Create a window for each view by leveraging a user control.
Each window has it's own hWnd.
Get the DC, process the wglcreatecontext, and then, on a timer (mine is 30 frames a second), if you detect state change, then select wglMakeCurrent for that view and redraw. Otherwise, just skip the section entirely.
This conserves valuable processing power, and also reduces the code from having to manage the window and viewport calculations manually.
Related
I am curious about how OpenGL assigns Multiple Display List IDs.
Currently I have:
void MyCreateList() {
MyListID = glGenLists(1);
glNewList(MyListID, GL_COMPILE);
//gluSphere(qobj, 1.0, 20, 20); //Sphere
//gluCylinder(qobj, 1.0, 0.0, 2.0, 20, 8); //Cylinder
gluDisk(qobj, 0.25, 1.0, 20, 3); //Disk
//gluPartialDisk(qobj, 0.5, 1.0, 26, 13, 0, 180); //PartialDisk
glEndList();
}
=> ID of One Display List.
void MyCreateList() {
GLuint listOne, listTwo, listThree, listFour;
listOne = glGenLists(4);
listTwo = listOne + 1;
listThree = listTwo + 1;
listFour = listThree + 1;
glNewList(listThree, GL_COMPILE);
gluSphere(qobj, 1.0, 20, 20); //Sphere
gluCylinder(qobj, 1.0, 0.0, 2.0, 20, 8); //Cylinder
gluDisk(qobj, 0.25, 1.0, 20, 3); //Disk
gluPartialDisk(qobj, 0.5, 1.0, 26, 13, 0, 180); //PartialDisk
glEndList();
}
=> ID of Multiple Display Lists.
Here's the desired result:
If you assign only one ID using the Display List, there is no problem, but if you assign more than one ID, it will not work.
Any ideas?
A display list groups a sequence of OpenGL commands and data, so that it can be executed repeatedly after its initial creation, in order to improve the program's performance (more information on display lists with various code examples can be found here).
Note that display lists have been deprecated in OpenGL 3.0 and removed in OpenGL 3.1, which was already discussed here: Why were display lists deprecated in opengl 3.1?
The four glu*() calls in your second code snippet create graphics primitives, that are stored in only one of the four generated display lists, namely in listThree. In that display list, the sphere, cylinder, disk and the partial disk are placed at the same position, and will therefore overlap. Also, the four display list ID variables listOne, listTwo, listThree, listFour are local to the scope of the function MyCreateList(), so they will not be accessible after the function call.
If the program should generate the result from the posted screenshot, then only one shape (generated with gluDisk()) and one display list is required. (Why should multiple display lists be used for that task?)
If this is an educational exercise, I think it's about putting transforms into a display list, to generate the shown skewed scape, for example like this (disk stretched with glScalef() and turned with glRotatef()):
/* $ gcc -Wall -pedantic skewed.c -o skewed -lGL -lGLU -lglut && ./skewed */
#include <GL/glut.h>
static GLuint _displayList = 0;
static void _create_display_list(void)
{
GLUquadricObj *qobj = NULL;
_displayList = glGenLists(1);
qobj = gluNewQuadric();
glNewList(_displayList, GL_COMPILE);
glPushMatrix();
glRotatef(30.0f, 0.0f, 0.0f, 1.0f);
glScalef(0.8f, 1.0f, 0.8f);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
gluDisk(qobj, 0.25, 1.0, 20, 3);
glPopMatrix();
glEndList();
gluDeleteQuadric(qobj);
qobj = NULL;
}
static void _reshape(GLint w, GLint h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.0f, 1.0f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
static void _display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glCallList(_displayList);
glFlush();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutCreateWindow("test");
glutDisplayFunc(_display);
glutReshapeFunc(_reshape);
_create_display_list();
glutMainLoop();
return 0;
}
And, here a modified example, that illustrates the use of multiple display lists:
/* $ gcc -Wall -pedantic test_gl.c -o test_gl -lGL -lGLU -lglut && ./test_gl */
#include <GL/glut.h>
static GLuint _displayList = 0;
static void _create_display_lists(void)
{
GLUquadricObj *qobj = NULL;
_displayList = glGenLists(4);
/* shapes (white) */
qobj = gluNewQuadric();
glNewList(_displayList + 2, GL_COMPILE);
glPushMatrix();
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glTranslatef(-2.0f, -2.0f, 0.0f);
gluSphere(qobj, 1.0, 20, 20);
glTranslatef(4.0f, 0.0f, 0.0f);
gluCylinder(qobj, 1.0, 0.0, 2.0, 20, 8);
glTranslatef(0.0f, 4.0f, 0.0f);
gluDisk(qobj, 0.25, 1.0, 20, 3);
glTranslatef(-4.0f, 0.0f, 0.0f);
gluPartialDisk(qobj, 0.5, 1.0, 26, 13, 0, 180);
glPopMatrix();
glEndList();
gluDeleteQuadric(qobj);
qobj = NULL;
/* diagonal line (cyan) */
glNewList(_displayList, GL_COMPILE);
glBegin(GL_LINES);
glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
glVertex4f(-3.0f, 3.0f, 0.0f, 1.0f);
glVertex4f(3.0f, 3.0f, 0.0f, 1.0f);
glEnd();
glEndList();
/* horizontal line (yellow) */
glNewList(_displayList + 1, GL_COMPILE);
glBegin(GL_LINES);
glColor4f(0.0f, 1.0f, 1.0f, 1.0f);
glVertex4f(-3.0f, -3.0f, 0.0f, 1.0f);
glVertex4f(3.0f, 3.0f, 0.0f, 1.0f);
glEnd();
glEndList();
/* diagonal line (magenta) */
glNewList(_displayList + 3, GL_COMPILE);
glBegin(GL_LINES);
glColor4f(1.0f, 0.0f, 1.0f, 1.0f);
glVertex4f(-3.0f, 3.0f, 0.0f, 1.0f);
glVertex4f(3.0f, -3.0f, 0.0f, 1.0f);
glEnd();
glEndList();
}
static void _reshape(GLint w, GLint h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-4.0f, 4.0f, -4.0f, 4.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
static void _display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glCallList(_displayList);
glCallList(_displayList + 1);
glCallList(_displayList + 2);
glCallList(_displayList + 3);
glFlush();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutCreateWindow("test");
glutDisplayFunc(_display);
glutReshapeFunc(_reshape);
glLineWidth(5.0f);
glDisable(GL_DEPTH_TEST);
_create_display_lists();
glutMainLoop();
return 0;
}
The documentation of all the used GL/GLU functions can be found there:
https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/
The documentation of all the used GLUT functions can be found there:
https://www.opengl.org/resources/libraries/glut/spec3/spec3.html
More information on the topic of "Legacy OpenGL" can be found here.
I need to translate my wired sphere along z-axis back and forth while also changing camera angle. Whenever my sphere gets translated, it slowly turns into ellipsoid. I really don't understand why. Here you can see pieces of code where I believe is a mistake. Also, shapes shouldn't be changed when resizing the window, only their size.
void init() {
glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST);
}
void display(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glLoadIdentity();
gluLookAt(ex, ey, ez, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glTranslatef(0.0,0.0,tra);
glScalef(0.65, 0.65, 0.65);
glColor3f(1.0f, 0.8f, 1.0f);
glutWireSphere(0.65, 10, 15);
glPopMatrix();
glPushMatrix();
glLoadIdentity();
gluLookAt(ex, ey, ez, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glColor3f(0.1f, 0.8f, 1.0f);
glutWireTorus(0.25, 1.0, 15, 15);
glPopMatrix();
glFlush();
glFlush();
}
void reshape(int w, int h) {
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70.0, (GLfloat)w / (GLfloat)h, 1.0, 80.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
[...] while also changing camera angle. Whenever my sphere gets translated, it slowly turns into ellipsoid.
That's caused by the Perspective distortion or wide-angle distortion and increases towards the edge of the view. The effect can be decreased by reducing the field of view angle, but the effect will never be canceled completely (except parallel projection).
See als How to fix perspective projection distortion?.
Also, shapes shouldn't be changed when resizing the window, only their size."
At perspective projection the size of the objects is always relative to the size of the viewport rather than the size of your screen.
If you don't want perspective distortion and if you want that the size of the objects has to be relative to the size of the screen (measured in pixel), then you have to use an orthographic projection, relative to the size of the viewport.
For instance:
void reshape(int w, int h) {
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluPerspective(70.0, (GLfloat)w / (GLfloat)h, 1.0, 80.0);
float sx = w / 100.0f;
float sy = h / 100.0f;
glOrtho(-sx/2.0f, sx/2.0f, -sy/2.0f, sy/2.0f, 1.0f, 80.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
I have an OpenGL project which uses GLUT (not freeglut) wherein I would like to display 2D text on the viewport at a fixed location. The rest of my objects are in 3D world co-ordinates.
This answer to a related old question says that,
the bitmap fonts which ship with GLUT are simple 2D fonts and are not suitable for display inside your 3D environment. However, they're perfect for text that needs to be overlayed on the display window.
I've tried the approach outlined in the accepted answer, but it does not give me the desired output. Following is a code snippet of the display function:
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0, 0.0, -(dis+ddis)); //Translate the camera
glRotated(elev+delev, 1.0, 0.0, 0.0); //Rotate the camera
glRotated(azim+dazim, 0.0, 1.0, 0.0); //Rotate the camera
.
.
.
draw 3D scene
.
.
.
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0.0, win_width, 0.0, win_height);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glRasterPos2i(10, 10);
string s = "Some text";
void * font = GLUT_BITMAP_9_BY_15;
for (string::iterator i = s.begin(); i != s.end(); ++i)
{
char c = *i;
glColor3d(1.0, 0.0, 0.0);
glutBitmapCharacter(font, c);
}
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glFlush();
glSwapBuffers();
}
A similar question to what I want seems to have been asked, but has no accepted answers by the author.
Answers in general seem to suggest using other libraries (mostly OS specific) to achieve the overlay. However, there is no clear indication to whether this can be achieved with GLUT alone. Can it be done?
I ran into this same problem using glut to create a model of the solar system. Here's how I solved it: (using your code from above)
glDisable(GL_TEXTURE_2D); //added this
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0.0, win_width, 0.0, win_height);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glRasterPos2i(10, 10);
string s = "Some text";
void * font = GLUT_BITMAP_9_BY_15;
for (string::iterator i = s.begin(); i != s.end(); ++i)
{
char c = *i;
glColor3d(1.0, 0.0, 0.0);
glutBitmapCharacter(font, c);
}
glMatrixMode(GL_PROJECTION); //swapped this with...
glPopMatrix();
glMatrixMode(GL_MODELVIEW); //...this
glPopMatrix();
//added this
glEnable(GL_TEXTURE_2D);
You'll note i switched glMatrixMode(GL_PROJECTION); and glMatrixMode(GL_MODELVIEW); near the end. I decided to do this because of this website. I also has to surround the code section with glDisable(GL_TEXTURE_2D) and glEnable(GL_TEXTURE_2D).
Hope that helps- I worked for me. My solar system uses classes to perform all of this, I'd be happy to share more details upon request.
As I said, the code you posted works perfectly fine. Here's the code I used to test it:
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include "GL/glu.h"
//glm not required
//#include <glm.hpp>
//#include <gtc/matrix_transform.hpp>
#include <string>
int win_width = 500, win_height = 500;
void renderScene(void) {
static float dis=0, ddis=0, elev=0, delev=0, azim=0, dazim=0;
azim += 0.5f;
if (azim >= 360.0f){
azim -= 360.0f;
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -(dis + ddis));
glRotated(elev + delev, 1.0, 0.0, 0.0);
glRotated(azim + dazim, 0.0, 1.0, 0.0);
glScalef(2.0f,2.0f,2.0f);
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 1.0f, 0.0f);
glVertex3f(-0.5f, -0.5f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.5f, 0.0f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 0.5f, 0.0f);
glEnd();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
//I like to use glm because glu is deprecated
//glm::mat4 orth= glm::ortho(0.0f, (float)win_width, 0.0f, (float)win_height);
//glMultMatrixf(&(orth[0][0]));
gluOrtho2D(0.0, win_width, 0.0, win_height);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glColor3f(1.0f, 0.0f, 0.0f);//needs to be called before RasterPos
glRasterPos2i(10, 10);
std::string s = "Some text";
void * font = GLUT_BITMAP_9_BY_15;
for (std::string::iterator i = s.begin(); i != s.end(); ++i)
{
char c = *i;
//this does nothing, color is fixed for Bitmaps when calling glRasterPos
//glColor3f(1.0, 0.0, 1.0);
glutBitmapCharacter(font, c);
}
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glEnable(GL_TEXTURE_2D);
glutSwapBuffers();
glutPostRedisplay();
}
int main(int argc, char **argv) {
// init GLUT and create Window
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100, 100);
glutInitWindowSize(win_width, win_height);
glutCreateWindow("GLUT Test");
// register callbacks
glutDisplayFunc(renderScene);
// enter GLUT event processing cycle
glutMainLoop();
return 1;
}
The usual disclaimers about deprecated fixed function pipeline and others apply.
There is a tricky way to solve your problem.
Please write a code before you call a function or what ever it is as written below:
glutBitmaCharacter(font, ' ');//
Does it....! And it should work...
I've been searching on how to draw an Indicator-Axis in my OpenGL scene. The project's nested in a Qt OpenGL widget, but I think the problem is independent of Qt.
I have found on here and forums from years ago that suggest storing the viewport and data, loading new ones for the botttom corner, apply my rotations and draw, then restore the matrices. This seems the most beneficial to me, but I'm guessing I'm still missing some critical info in my OpenGL knowledge.
For now I just have it drawing a red line from -x to x, so I expected to have a red square in the bottom left of the screen:
void GLWidget::drawAxis()
{
float tempPro[16];
float tempMod[16];
glGetFloatv(GL_PROJECTION_MATRIX, &tempPro[0]);
glGetFloatv(GL_MODELVIEW_MATRIX, &tempMod[0]);
glViewport(0, 0, 50, 50);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, 1.0f, 0.1f, 20.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glBegin(GL_LINES);
glColor3f(1.0f, 0.0f, 0.0f);
glEnable( GL_LINE_SMOOTH );
glLineWidth( 1.5 );
glVertex3f(-1000, 0, 0);
glVertex3f(1000, 0, 0);
glEnd();
glPopMatrix();
glViewport(0, 0, 960, 600);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(tempPro);
gluPerspective(45.0f, (960.0/600.0), 0.1f, 400.0f);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(tempMod);
}
Instead I get nothing, just a large empty scene, and I'm unsure how to proceed. My paintGL is essentially:
void GLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
Camera.Render();
glTranslatef(0.0, 0.0, 0.0);
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(50.0f, 0.0f, 50.0f);
glVertex3f(50.0f, 0.0f, -50.0f);
glVertex3f(-50.0f, 0.0f, -50.0f);
glVertex3f(-50.0f, 0.0f, 50.0f);
glEnd();
drawAxis();
}
Not calling the draw-axis function still gives me my plane, with it, I get a large blank scene. Am I missing something in how I'm implementing the drawAxis? Should I setup another camera for the function or something like that?
You can use glPushMatrix() and glPopMatrix() to save and restore the state of your Projection and ModelView matrices.
Your not setting up your ModelView matrix to anything useful.
Try something like this:
void GLWidget::drawAxis()
{
glViewport(0, 0, 50, 50);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
gluPerspective(45.0f, 1.0f, 0.1f, 20.0f);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
//This really has to come from your camera....
gluLookAt(10.0f,10.0f,10.0f, 0.0f,0.0f,0.0f, 0.0f,0.1f,0.0f);
glColor3f(1.0f, 0.0f, 0.0f);
glEnable( GL_LINE_SMOOTH );
glLineWidth( 1.5 );
glBegin(GL_LINES);
glVertex3f(-1000, 0, 0);
glVertex3f(1000, 0, 0);
glEnd();
//Restore View
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glViewport(0, 0, 960, 600);
}
I'm learning OpenGL, and I am reading a book to help me a long. I've followed it through half way and have decided to go off on my own path now that I'm familiar with the basics. I've started to develop an application, the intention is to just show a grid.
I've pretty much nailed it, but when I run my application, part of the grid is cut off. I've attached a condensed version of the code (which has the same result) - does anyone know what I am doing wrong to make it cut off part of the screen? I've tinkered about a lot and I've run through a few values but I just cannot get this thing sorted. Any help or a nudge in the right direction is much appreciated.
Code:
#include <Windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "deps\glut\glut.h"
void display();
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(800, 600);
glutCreateWindow("");
glutDisplayFunc(display);
glClearColor(1.0, 1.0, 1.0, 1.0);
glColor3f(0.0, 0.0, 0.0);
// Init
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-8.0, 8.0, -8.0, 8.0, -8.0, 8.0);
glutMainLoop();
return 0;
}
void display() {
float f;
// Clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0);
// This next bit of code just creates the grid
glColor3f(0.0f, 0.0f, 0.0f);
glPointSize(1.0);
for(f=-10.0f;f<10.0f;f++) {
glBegin(GL_LINES);
glVertex3f(f, 0.0f, -10.0f);
glVertex3f(f, 0.0f, 10.0f);
glEnd();
}
glRotatef(90, 0.0, 1.0, 0.0);
for(f=-10.0f;f<10.0f;f++) {
glBegin(GL_LINES);
glVertex3f(f, 0.0f, -10.0f);
glVertex3f(f, 0.0f, 10.0f);
glEnd();
}
// Swap the buffers
glutSwapBuffers();
}
You can't draw outside the unit cube.
Your glOrtho call scales the coordinates so that you can use the range -8...8 for x, y, and z coordinates, but your for loop then tries to use -10...10, which exceeds the range and will be clipped.
You're hitting the Z limits due to the diagonal of a unit cube being sqrt(3) longer than the side. So I suggest you use -14…14 ( = ± round( 8*sqrt(3) ) ) as limits for the near and far plane.