I am still trying to figure out, why i see only typical "black screen". I render just one rectangle, but nothing happened.
#include "expwidget.h"
#include <iostream>
ExpWidget::ExpWidget(QObject *parent) :
QGLWidget(QGLFormat(QGL::DoubleBuffer), (QWidget *) parent)
{
QGLFormat fmt = this->format();
fmt.setDepth(true);
this->setFormat(fmt);
}
void ExpWidget::initializeGL() {
QGLWidget::initializeGL();
std::cout << "inicializace...\n";
glClearColor(0.0f,0.0f,0.0f,0.0f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glDisable(GL_LIGHTING);
}
void ExpWidget::paintGL() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glColor3f(1, 0, .5);
glBegin(GL_QUADS);
glVertex3f(-1.0f,-1.0f,-5.0f);
glVertex3f(1.0f,-1.0f,-5.0f);
glVertex3f(1.0f,1.0f,-5.0f);
glVertex3f(-1.0f,1.0f,-5.0f);
glEnd();
glFlush();
}
void ExpWidget::resizeGL(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-2.0, 2.0, -2.0, 2.0, 0.0, -30.0);
glMatrixMode(GL_MODELVIEW);
}
I've faced a similar problem in the past, but I don't claim to be an expert.
Calls to glFrustum are in the form glFrustum(left, right, bottom, top, near, far)
near and far must both be positive and non-zero. (http://www.opengl.org/sdk/docs/man2/xhtml/glFrustum.xml)
so in your case I would recommend changing your call to:
glFrustum(-2.0, 2.0, -2.0, 2.0, 1.0, 30.0);
Also, your coordinates should have negative Z to render in this view.
http://www.opengl.org/sdk/docs/man2/xhtml/glFrustum.xml:
nearVal, farVal
Specify the distances to the near and far depth clipping planes. Both distances must be positive.
Related
I am working on bring back to life a program I wrote seven years ago. It is all written in Qt and uses some OpenGL to draw some frame lines on an image that the application is displaying. The problem is that 'gluOrtho2D' is used but is no longer found. I am wondering how I can get around the problem. Here is the code:
void MSContext::ResizePaint(int width, int height)
{
// setup viewport, projection etc.:
glViewport(0, 0, (GLint)width, (GLint)height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, (GLdouble) width, 0.0, (GLdouble) height);
glMatrixMode(GL_MODELVIEW);
glClearColor(0.5, 0.5, 0.5, 1.0);
glShadeModel(GL_FLAT);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
CreatePrintCropMarks();
}
void MSContext::CreatePrintCropMarks()
{
GLuint print45CropId = openGLListMgr()->print45CropId();
glNewList( print45CropId, GL_COMPILE);
{
qreal lineSize = 4.0;
// Shrink down the canvas by 4 pixels so that the crop will show up
const QRectF& viewPort = primaryCanvas()->imageView()->viewRectangle();
QRectF shrunkingCanvas = viewPort.adjusted(lineSize, lineSize, -lineSize, -lineSize);
QRectF print45Crop = GetCropRect(shrunkingCanvas, 5, 4);
QRectF print57Crop = GetCropRect(print45Crop, 7, 5);
glLineWidth(lineSize / 2);
glLineStipple(1,0xFF00);
DrawBox(print57Crop);
glLineWidth(lineSize);
glLineStipple(1,0xFFFF);
DrawBox(print45Crop);
}
glEndList();
}
At the back of my head, I was wondering why I'd never heard of this function... turns out there is a fine alternative in (old-school) OpenGL. From the SGI GLU implementation:
void GLAPIENTRY
gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top)
{
glOrtho(left, right, bottom, top, -1, 1);
}
So you can write:
glOrtho(0.0, (GLdouble) width, 0.0, (GLdouble) height, -1, 1);
My program refuses to do depth testing. The two sphere objects are always drawn in the order they are created, not according to their position. Sphere alpha is positioned at (0, 0, 1) and Sphere beta is positioned (0, 0, -10), yet OpenGL still draws beta on top of alpha. I set depth test to enabled in my program.
Nothing appears to work. I want OpenGL to do depth test automatically on any objects drawn in the window. Any help or advise would be greatly appreciated. Here is the full code.
#include "GL/freeglut.h"
#include "GL/gl.h"
#include "GL/glu.h"
const int SPHERE_RES = 200;
double Z_INIT = -28.0;
double RADIUS = 2;
double Red[3] = {1, 0, 0};
double Blue[3] = {0, 0, 1};
using namespace std;
/*
* Method handles resize of the window
*/
void handleResize (int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double ratio = (float)w/ (float)h;
gluPerspective(45.0, ratio, 1.0, 100.0);
}
/*
* Color and depth is enabled and in this method
*/
void configureColor(void)
{
glClearColor(1.0f, 1.0f, 1.0f, 0.0f); //Set background to white
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Clear window.
glDepthFunc(GL_ALWAYS);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
}
void display (void) {
configureColor();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GLfloat sun_direction[] = { 0.0, 0.0, -1.0, 0.0};
glLightfv(GL_LIGHT0, GL_POSITION, sun_direction);
GLUquadric* quad = gluNewQuadric();
//first sphere is drawn
glColor3f(Red[0], Red[1], Red[2]);
glPushMatrix();
glLoadIdentity();
glTranslatef(0, 0, Z_INIT);
glTranslatef(0, 0, 1.0);
gluSphere(quad, RADIUS, SPHERE_RES, SPHERE_RES);
glPopMatrix();
//second sphere is supposed to be drawn behind it,
//but it is drawn on top.
glColor3f(Blue[0], Blue[1], Blue[2]);
glPushMatrix();
glLoadIdentity();
glTranslatef(0, 0, Z_INIT);
glTranslatef(0, 0, -10.0);
gluSphere(quad, RADIUS, SPHERE_RES, SPHERE_RES);
glPopMatrix();
free(quad);
glFlush();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv); //initializes the GLUT
glutInitDisplayMode(GLUT_SINGLE);
glutInitWindowSize(600,600);
glutInitWindowPosition(100,100);
glutCreateWindow("OpenGL - First window demo");
glutReshapeFunc(handleResize);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
I am using Ubuntu 14.04 operating system.
glDepthFunc(GL_ALWAYS);
This is the reason you see the spheres in the order they are drawn. Setting the depth function to GL_ALWAYS simply means all depth tests always pass, for any fragment, be it closer or farther.
You need GL_LESS for the result you want. A fragment having depth lesser than the one in the frame buffer wins; the closer (lesser z) one wins over the farther (greater z) one.
You can either call glDepthFunc(GL_LESS) or comment out glDepthFunc(GL_ALWAYS) since GL_LESS is the default.
I am attempting to make a simple drawing using openGL. However, the depth buffer doesn't appear to be working.
Other people with a similar problem are typically doing one of two things wrong:
Not including glEnable(GL_DEPTH_TEST)
Bad clipping values
However, my code does not have either of these problems.
...
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gluPerspective(25.0,1.0,10.0,200.0);
// Set the camera location
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(20.0, 10.0, 50.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
// Enable depth test
glEnable(GL_DEPTH_TEST);
// Cull backfacing polygons
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE)
drawCoordinateAxis();
drawBox(5.0,2.0,5.0,0.8,0.0,0.0);
glTranslated(1.0,-1.0,1.0); //The box is 5x2x5, it is shifted 1 unit down and 1 in the x and z directions
drawBox(5.0,2.0,5.0,0.0,1.0,1.0);
...
When I execute my code, this is drawn. http://imgur.com/G9y41O1
Note that the blue box and the red box collide, so the red box should be covering part of the blue box.
The functions drawCoordinateAxis() and drawBox() just draw a few primitives, nothing fancy inside.
I am running this on Debian squeeze.
void reshape(GLint width, GLint height)
{
g_Width = width;
g_Height = height;
glViewport(0, 0, g_Width, g_Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(65.0, (float)g_Width / g_Height, g_nearPlane, g_farPlane);
glMatrixMode(GL_MODELVIEW);
}
So set Matrix Mode to GL_PROJECTION first, then gluPerspective.... and then back to MODELVIEW mode.
I've been experimenting with programs from my text book that involved clipping 2-D polygons using glOrtho and then creating glutWireSpheres in gluPerspective. My goal is to clip half the sphere with a plane, however, I am having trouble clipping 3-D objects. I created a toggle button to show the sphere clipped and unclipped, however, the button instead shows the sphere moving in a ellipse motion I believe.
Here is my drawscene for creating the sphere
double eqn0[4] = {1, 0, 0.0, -60}; // Data for clipping plane 0.
// Choose window.
glutSetWindow(id2);
gluLookAt(0.0, 3.0, 12.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glClipPlane(GL_CLIP_PLANE0, eqn0); // Specify clipping plane 0.
if (isClip0) glEnable(GL_CLIP_PLANE0); // Clip points s.t. z > 0.25.
else glDisable(GL_CLIP_PLANE0);
glPushMatrix();
glColor3f(1.0, 0.0, 0.0);
glutWireSphere(1.0, 10, 10);
glPopMatrix();
glFlush();
And here is my toggle
case '0':
if (isClip0 == 0) isClip0 = 1;
else isClip0 = 0;
glutPostRedisplay();
break;
Can someone help me get in the right direction for clipping 3-D objects? Because this will work on 2-D polygons, yet when I try to apply it to spheres, the toggle button doesn't even act like a toggle.
EDIT: Full code:
#include <cmath>
#include <iostream>
#ifdef __APPLE__
# include <GLUT/glut.h>
#else
# include <GL/glut.h>
#endif
#define PI 3.14159265
using namespace std;
// Globals.
static int id1, id2; // Window identifiers.
static int isClip0 = 0; // Is clipping plane 0 enabled?
static int isClip1 = 0; // Is clipping plane 1 enabled?
static int isClip3 = 0; // Is clipping plane 0 enabled?
static int isClip4 = 0; // Is clipping plane 1 enabled?
// Drawing routine for first window.
void drawScene1(void)
{
// Choose window.
glutSetWindow(id1);
glClear(GL_COLOR_BUFFER_BIT);
// A red square.
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(10.0, 10.0, 0.0);
glVertex3f(40.0, 10.0, 0.0);
glVertex3f(40.0, 40.0, 0.0);
glVertex3f(10.0, 40.0, 0.0);
glEnd();
glFlush();
}
// Drawing routine for second window.
void drawScene2(void)
{
double eqn0[4] = {1, 0, 0.0, -1000}; // Data for clipping plane 0.
// Choose window.
glutSetWindow(id2);
gluLookAt(0.0, 3.0, 12.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glClipPlane(GL_CLIP_PLANE0, eqn0); // Specify clipping plane 0.
if (isClip0) glEnable(GL_CLIP_PLANE0); // Clip points s.t. z > 0.25.
else glDisable(GL_CLIP_PLANE0);
glPushMatrix();
glColor3f(1.0, 0.0, 0.0);
glutWireSphere(1.0, 10, 10);
glPopMatrix();
glFlush();
}
// Initialization routine for first window.
void setup1(void)
{
// Black background.
glClearColor(0.0, 0.0, 0.0, 0.0);
}
// Initialization routine for second window.
void setup2(void)
{
// Green background.
glClearColor(1.0, 1.0, 1.0, 0.0);
}
// Reshape routine for first window.
void resize1(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Non-square aspect ratio squashes the square.
glOrtho(0.0, 50.0, 0.0, 100.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
// Reshape routine for second window.
void resize2(int w, int h)
{
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (float)w/(float)h, 1.0, 50.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
// Keyboard input processing routine shared by both windows.
void keyInput(unsigned char key, int x, int y)
{
switch(key)
{
case 27:
exit(0);
break;
case '0':
if (isClip0 == 0) isClip0 = 1;
else isClip0 = 0;
glutPostRedisplay();
break;
default:
break;
}
}
// Main routine.
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
// First top-level window definition.
glutInitWindowSize(250, 500);
glutInitWindowPosition(100, 100);
// Create the first window and return id.
id1 = glutCreateWindow("windows.cpp - window 1");
// Initialization, display, and other routines of the first window.
setup1();
glutDisplayFunc(drawScene1);
glutReshapeFunc(resize1);
glutKeyboardFunc(keyInput); // Routine is shared by both windows.
// Second top-level window definition.
glutInitWindowSize(250, 500);
glutInitWindowPosition(400, 100);
// Create the second window and return id.
id2 = glutCreateWindow("windows.cpp - window 2");
// Initialization, display, and other routines of the second window.
setup2();
glutDisplayFunc(drawScene2);
glutReshapeFunc(resize2);
glutKeyboardFunc(keyInput); // Routine is shared by both windows.
glutMainLoop();
return 0;
}
Sphere is dealt with in drawScene2
So, after adding a glLoadIdentity() right before the gluLookAt(), the movements will go away (as I already had suggested...). And when one sets a useful clip plane equation, the clipping works as expected, too. As you define a sphere with radius 1 around the object space center, setting
GLdouble eqn0[4] = {1, 0, 0.0, 0.5};
will result in the sphere being clipped at x=-0.5, so 3/4 of it is still visible, as one would expect.
Been integrating this camera tutorial http://www.swiftless.com/tutorials/opengl/camera2.html and having a bit of trouble centering the camera in the skybox.
Using this code below makes my camera inside the box:
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-1.0, 1.0, -1.0*(GLfloat)h/(GLfloat)w,
1.0*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
else
glOrtho(-1.0*(GLfloat)w/(GLfloat)h,
1.0*(GLfloat)w/(GLfloat)h, -1.0, 1.0, -10.0, 10.0);
glMatrixMode(GL_MODELVIEW);
}
To draw the skybox, I followed this tutorial: http://sidvind.com/wiki/Skybox_tutorial
I've been trying to translate objects closer to the camera, but didn't work as I expected. Now I'm not sure what I need to do.
Appreciate any help.
First: Don'y apply the projection in the reshape handler. Otherwise simple things appear impossible (like doing a skybox). Second: For a skybox to work you must use the very same projection like for the rendering of the rest of the scene. What you should change is the translation of the modelview to 0, yet keeping the camera orientation.
You can do this by setting the last column of the modelview matrix to (0,0,0,1).
So this makes your rendering code like this:
void render_skybox()
{
push_modelview();
set_modelview_column(3, 0, 0, 1);
draw_skybox();
pop_modelview();
}
void render()
{
set_viewport();
set_projection();
apply_camera_transform();
render_skybox();
render_scene();
}