I am in the process of building a simple 3D game engine that is built on top of OpenGL, and for windowing and I/O, GLUT. I have run into a problem with the OpenGL accumulation buffer when trying to build a motion-blur option into the engine. Essentially, here is the small block of code that is supposed to do this for me:
glAccum(GL_MULT, 0.99f);
glAccum(GL_ACCUM, 1.0f - 0.99f);
glAccum(GL_RETURN, 1.0f);
I first tried this block of code by planting it in my Render() method, but it showed a corrupt-looking view where only a select few pixels were visible. So, I then tried it with the rest of the source from the website from which I found the code. I still got the same issue. Below is an image of the issue:
Then, I just took out the accumulation buffer portion (the three lines that are supposed to achieve the motion blur), and here is what I got:
Of course, there would be no motion blur since I removed the glAccum() lines, but that at least told me there is either a problem with my graphics card (it doesn't like accumulation buffers?) or those lines of code don't work.
I don't know if it matters, but I am running the code through NetBeans 7.2 (C++) on a MacBook Pro from 2011. Also, I did request an accumulation buffer in the following line:
glutInitDisplayMode(GLUT_DEPTH | GLUT_ACCUM | GLUT_DOUBLE | GLUT_RGBA);
Here is a sample piece of code I just threw together. I'm not sure if something is wrong in the code, and I know I probably didn't use best practices either, but it gets the point across. I still experienced the error with this code:
#include <iostream>
#include <GLUT/GLUT.h>
using namespace std;
float Rotation = 0.0f;
void Reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1, 1, -1.0f * ((float)height / (float)width), 1.0f * ((float)height / (float)width), 0.1f, 200.0f);
glMatrixMode(GL_MODELVIEW);
}
void Update(int value)
{
Rotation++;
glutPostRedisplay();
glutTimerFunc(17, Update, 0);
}
void InitGL()
{
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnable(GL_COLOR_MATERIAL);
glClearDepth(100.0f);
}
void Render(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0, 0, 5.0f, 0, 0, 0, 0, 1, 0);
glPushMatrix();
{
glRotatef(Rotation, 0.0, 1.0, 0.0);
/* Render Icosahedron */
glColor3f(0.5f, 0.5f, 0.5f);
glutSolidIcosahedron();
/* Render wireframe */
glColor4f(1.0, 1.0, 1.0, 1.0);
glLineWidth(2.0);
glutWireIcosahedron();
}
glPopMatrix();
/* Blur */
glAccum(GL_MULT, 0.99);
glAccum(GL_ACCUM, 0.01);
glAccum(GL_RETURN, 1.0);
glFlush();
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA | GLUT_ACCUM);
glutInitWindowSize(400, 400);
glutCreateWindow("Test");
glutDisplayFunc(Render);
glutReshapeFunc(Reshape);
InitGL();
Reshape(400, 400);
glutTimerFunc(17, Update, 0);
glutMainLoop();
return 0;
}
Related
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've been trying to draw a cone and a cylinder using GLUT. The code I've written so far takes two points from the user, which represents the height of the cone/cylinder, and I want to draw a cone and a cylinder using the two points.
I looked up Google and found standard functions called glutWireCone() and gluCylinder(), but I'm unable to understand how to use these functions to draw in the manner that I want to draw. Can someone tell me how to draw a cone and a cylinder using the two points? Please let me know if you need some extra information to understand my question correctly.
Here are my init() and main() functions for you to know the settings of my program:
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, WINDOW_WIDTH-1, WINDOW_HEIGHT-1, 0, -1000.0, 1000.0);
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
glutInitWindowPosition(220, 80);
glutCreateWindow("Mini Paint - 3D");
init();
glutDisplayFunc(display);
glutMouseFunc(mouseClick);
glutMotionFunc(mouseMove);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
Well lets take that gluCylinder function and apply it to your display function. Look at it's parameters:
void gluCylinder(GLU quadric* quad,
GLdouble base,
GLdouble top,
GLdouble height,
GLint slices,
GLint stacks);
So you want to draw a cylinder given the height parameter as input. I'm guessing everything else will remain constant. every time you render you'll want to use glPushMatrix and maybe glRotatef depending on how you would like its orientation, ending this call with a glPopMatrix
Ex: OnRender(float pHeight)
void OnRender(float pHeight) {
glClearColor(1.0f, 0.0f, 0.0f, 1.0f); //clear
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity();
gluCylinder(quadratic, 0.1f, 0.1f, pHeight, 32, 32);
glFlush();
}
declaring a quadratic object:
GLUquadricObj *quadratic;
quadratic = gluNewQuadric();
gluCylinder documentation: https://www.opengl.org/sdk/docs/man2/xhtml/gluCylinder.xml
Main function:
int _tmain(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitWindowSize (500, 500);
glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glutInitWindowPosition (700, 100);
glutCreateWindow("Result");
glutDisplayFunc(display2);
glutReshapeFunc(reshape2);
glutMouseFunc(main_mouse);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
Display2 function:
void display2()
{
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//Green square
glColor3f(0.0,1.0,0.0);
glBegin(GL_POLYGON);
glVertex3f(0.5,0.5,-1.0);
glVertex3f(0.5,1.5,-1.0);
glVertex3f(1.5,1.5,-1.0);
glVertex3f(1.5,0.5,-1.0);
glEnd();
//Red square
glColor3f(1.0,0.0,0.0);
glBegin(GL_POLYGON);
glVertex3f(0.0,0.0,-2.0);
glVertex3f(0.0,1.0,-2.0);
glVertex3f(1.0,1.0,-2.0);
glVertex3f(1.0,0.0,-2.0);
glEnd();
glutSwapBuffers();
}
reshape2 function
void reshape2(int width, int height)
{
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glOrtho(-3.0,3.0,-3.0,3.0,0.01,3.0);
}
I have problem with depth buffer in openGL. I try to draw 2 square red and green. The red one is located behind the green one.
Red square have z value -2 while green square have z value -1. But the red square displayed at front of green square. I have enabled the depth test but still not work. What is wrong with my program?
Don't call any gl* function before you call glutCreateWindow, so move glEnable and glDepthFunc after it.
Every gl functions make calls to the context which is only created with the GLUT window. No OpenGL functions is effective before that.
When i try to run this program it starts, shows the title bar but there is nothing - it only docks for the bottom task line and when i click it - nothing shows. There is no window with the program. Any idea ? Here's the code that uses OpenGL stuff :
#include <GL/glut.h> // Header File For The GLUT Library
#include <GL/gl.h> // Header File For The OpenGL32 Library
#include <GL/glu.h> // Header File For The GLu32 Library
void SetupRC(void);
void RenderScene(void);
void ChangeSize(GLsizei w, GLsizei h);
// Called to draw scene
void RenderScene(void)
{
// Clear the window with current clearing color
glClearColor (0.f,0.f,0.f,0.f);
glClear(GL_COLOR_BUFFER_BIT);
// set the color to these values
// R G B
glColor3f(1.0f, 1.0f, 1.0f);
// Draw a filled rectangle with current color
glRectf(-25.0f, 25.0f, 25.0f, -25.0f);
// Flush drawing commands
glFlush();
glutSwapBuffers();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH); // color, buffer
glutCreateWindow("Simple");
glutInitWindowPosition(400,200);
glutInitWindowSize(640,468);
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
SetupRC();
glutMainLoop();
return 0;
}
// Setup the rendering state
void SetupRC(void)
{
glClearColor(0.0f, 1.0f, 1.0f, 0.0f);
}
// Handling window resizing
void ChangeSize(GLsizei w, GLsizei h)
{
GLfloat aspectRatio;
// Prevent divide by zero
if (h == 0)
h = 1;
// Set Viewport to window dimensions
glViewport(0, 0, w, h);
// Reset coordinate system
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Establish clipping volume (left, right, bottom, top, near, far)
aspectRatio = (GLfloat) w / (GLfloat) h;
if (w <= h) {
glOrtho(-100.0, 100.0, -100 / aspectRatio, 100.0 / aspectRatio, 1.0, -1.0);
}
else
glOrtho(-100.0 * aspectRatio, 100.0 * aspectRatio, -100.0, 100.0, 1.0, -1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
Run glxinfo from the terminal and see if any issues show up.
You might have to install mesa-utils to use glxinfo
sudo apt-get install mesa-utils
From what you've shared, it seems like a graphics card issue. You might be able to get better help over at the Ubuntu Forums. Good luck.
Just change single buffering with double buffering and it will work (instead of GLUT_SINGLE put GLUT_DOUBLE).
I was writing a program to draw a square in my XY plane and make it rotate 360 degree, but it is not working.
void setupRC()
{
glClearColor(0,0,1,1);
glColor3f(1,0,0);
}
void timerfunc(int value)
{
glutPostRedisplay();
glutTimerFunc(33, timerfunc ,1);
}
void RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
static GLfloat rot = 0.0f,x =0.0f , y=10.0f , z=0.0f;
rot++;
x = 10 * cos(rot);
y = 10 * sin(rot);
glPushMatrix();
glRotatef(rot,0.0,1.0,0.0);
glBegin(GL_POLYGON);
glVertex3i(10,-10,0);
glVertex3i(10,10,0);
glVertex3i(-10,10,0);
glVertex3i(-10,-10,0);
glVertex3i(10,-10,0);
glEnd();
glPopMatrix();
glutSwapBuffers();
}
void ChangeSize(GLint w, GLint h)
{
if(h==0)
h = 1;
GLfloat aspectratio = (GLfloat)w/(GLfloat)h;
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0f, aspectratio, -1.0, 400.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc , char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(800,600);
glutInitWindowPosition(0,0);
glutCreateWindow("chelsea");
glutTimerFunc(33, timerfunc , 1);
setupRC();
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
glutMainLoop();
return 0;
}
I get no output, just a blank screen.
gluPerspective(60.0f, aspectratio, -1.0, 400.0);
Looks wrong, the near clipping plane needs to be a positive number
You should really use glRotatef for rotating, because your code is wrong if you want a plane rotating around XY (x and y will be 0 for some values of rot and you'll get to see nothing at all).
And you should perhaps give your polygons a color using the glColor commands.
As JB said, your gluPerspective call seems wrong, too. See this link for a reference.