I'm trying to draw clouds in the window and animate them towards the camera. The problem I'm having is that I want to do this continuously without anything being abruptly redrawn. Can someone tell me what I'm missing here?
Here is the code:
#include <gl/glut.h>
int width = 800, height = 600;
float theta = 0, distance1 = -600, distance2 = -600;
void drawCloud()
{
glPushMatrix();
glTranslated(1,0,-2);
glutSolidSphere(4,10,10);
glTranslated(-2,0,-5);
glutSolidSphere(4,10,10);
glTranslated(-1,0,3);
glutSolidSphere(4,10,10);
glPopMatrix();
}
void drawCloudFormation()
{
glPushMatrix();
glTranslated(-60,30,-300);
drawCloud();
glPopMatrix();
glPushMatrix();
glTranslated(15,3,-150);
drawCloud();
glPopMatrix();
glPushMatrix();
glTranslated(50,30,-200);
drawCloud();
glPopMatrix();
glPushMatrix();
glTranslated(-15,-15,-250);
drawCloud();
glPopMatrix();
glPushMatrix();
glTranslated(25,-25,-100);
drawCloud();
glPopMatrix();
glPushMatrix();
glTranslated(-30,0,-50);
drawCloud();
glPopMatrix();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glPushMatrix();
glTranslated(0,0,distance1);
drawCloudFormation();
glPopMatrix();
glPushMatrix();
glTranslated(0,0,distance1-200);
glScaled(-1,1,1);
drawCloudFormation();
glPopMatrix();
glPushMatrix();
glTranslated(0,0,distance2-400);
glScaled(1,1,-1);
drawCloudFormation();
glPopMatrix();
glPushMatrix();
glTranslated(0,0,distance2-600);
glScaled(-1,1,1);
glScaled(1,1,-1);
drawCloudFormation();
glPopMatrix();
glutSwapBuffers();
}
void idle()
{
theta += 0.2;
if (theta == 360) theta = 360;
distance1 += 1;
if (distance1 > 200) distance1 = -600;
distance2 += 1;
if (distance2 > 600) distance2 = -600;
glutPostRedisplay();
}
void main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(width, height);
glutInitWindowPosition(100, 200);
glutCreateWindow("Space Ship");
glClearColor(0, 0, 1, 1);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(120, 1, 0.1, 600);
//glOrtho(-2, 2, -2, 2, 0.1, 200);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//gluLookAt(0, 0, -200, 0, 0, -600, 0, 1, 0);
glutDisplayFunc(display);
glutIdleFunc(idle);
glutMainLoop();
}
Look into particle systems.
You essentially want a rectangular emitter on the far side of your scene spewing clouds (particles) with a fixed velocity toward the camera. When the clouds move behind the camera mark them as inactive and the particle system will spawn a new ones back at the emitter.
Related
I am working on a simple OpenGL project.
I want to get a simple camera to move in perspective mode.
I keep reading about the projection matrix, gluLookAt, and the model view matrix. I keep reading that all I should do are my perspective calls in the projection matrix and then all of my transformations and camera movement in the model view matrix.
#include "GLheaders.h"
void drawWorldAxis() {
glLoadIdentity();
glBegin(GL_LINES);
glNormal3f(0, 0, 1);
glColor3ub(255, 0, 0);
glVertex3f(0,0,0);
glVertex3f(1,0,0);
glColor3ub(0, 255, 0);
glVertex3f(0,0,0);
glVertex3f(0,1,0);
glColor3ub(0, 0, 255);
glVertex3f(0,0,0);
glVertex3f(0,0,1);
glEnd();
}
void keyboard(unsigned char key, int x, int y) {
glutPostRedisplay();
}
static float eye[3] = {.5, .5, .5};
#include <stdio.h>
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(55.0, 1, .1, 10000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawWorldAxis();
printf("eye at <%f, %f, %f>\n", eye[0], eye[1], eye[2]);
fflush(stdout);
gluLookAt(eye[0], eye[1], eye[2], 0, 0, 0, 0, 1, 0);
eye[0] += .1;
eye[1] += .1;
glFlush();
glutSwapBuffers();
}
void reshape(int w, int h) {
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(55.0, 1, -1, 10000);
glMatrixMode(GL_MODELVIEW);
glutPostRedisplay();
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE| GLUT_DEPTH);
glutInitWindowSize(400,400);
glutCreateWindow("Tiny Test");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glEnable(GL_NORMALIZE);
glEnable(GL_DEPTH_TEST);
glutMainLoop();
return EXIT_SUCCESS;
}
I am expecting this code to display three lines representing the world coordinate system's x, y, and z axises, and as keys are pressed the camera should move and start to look at the origin/coordinate axises from more and more drastic angles.
What is going wrong here? I've been bashing my head into a wall trying to figure out why nothing is moving. It only changes if I put the gluLookAt call in the projection matrix which I keep being told is a terrible idea.
The coordinate cross is drawn before you set the lookAt matrix, thus the matrix has no effect.
You have to change the order such that the matrix is already present when drawing:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(eye[0], eye[1], eye[2], 0, 0, 0, 0, 1, 0);
drawWorldAxis();
printf("eye at <%f, %f, %f>\n", eye[0], eye[1], eye[2]);
fflush(stdout);
Then there is a second problem: You are resetting the model matrix in the first line of drawWorldAxis. Here, you can either remove the glLoadIdentity call or push the previous matrix to the stack first:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(eye[0], eye[1], eye[2], 0, 0, 0, 0, 1, 0);
glPushMatrix();
drawWorldAxis();
glPopMatrix();
printf("eye at <%f, %f, %f>\n", eye[0], eye[1], eye[2]);
fflush(stdout);
thanks to #BDL for helping fix this! This is the correct code that I wanted
#include "GLheaders.h"
void drawWorldAxis() {
glBegin(GL_LINES);
glNormal3f(0, 0, 1);
glColor3ub(255, 0, 0);
glVertex3f(0,0,0);
glVertex3f(1,0,0);
glColor3ub(0, 255, 0);
glVertex3f(0,0,0);
glVertex3f(0,1,0);
glColor3ub(0, 0, 255);
glVertex3f(0,0,0);
glVertex3f(0,0,1);
glEnd();
}
void keyboard(unsigned char key, int x, int y) {
glutPostRedisplay();
}
static float eye[3] = {-.1, -.1, 1};
#include <stdio.h>
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(55.0, 1, .1, 10000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
printf("eye at <%f, %f, %f>\n", eye[0], eye[1], eye[2]);
fflush(stdout);
gluLookAt(eye[0], eye[1], eye[2], 0, 0, 0, 0, 1, 0);
drawWorldAxis();
eye[0] += .1;
eye[1] += .1;
glFlush();
glutSwapBuffers();
}
void reshape(int w, int h) {
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(55.0, 1, -1, 10000);
glMatrixMode(GL_MODELVIEW);
glutPostRedisplay();
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE| GLUT_DEPTH);
glutInitWindowSize(400,400);
glutCreateWindow("Tiny Test");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glEnable(GL_NORMALIZE);
glEnable(GL_DEPTH_TEST);
glutMainLoop();
return EXIT_SUCCESS;
}
I want to make a square (2D) by using several smaller squares(like a grid). I need to do this because I want to texture an image on the main square and divide the picture into several pixels(the said smaller squares).
Here's the program:-
int h=1,w=1;
int res=25;// res is the number of smaller squares I want
float hratio=h/res;
float wratio=w/res;
void Draw()
{
float x,y;
for(y=-.5;y<=h;y+=h/res)
{
for(x=-.5;x<=w;x+=w/res)
{
glColor3f(1,1,1);
glBegin(GL_QUADS);
glVertex3f(x,y+(h/res),0);
glVertex3f(x+(w/res),y+(h/res),0);
glVertex3f(x+(w/res),y,0);
glVertex3f(x,y,0);
glEnd();
}
}
glFlush();
glutPostRedisplay();
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Draw();
glutSwapBuffers();
glutPostRedisplay();
}
int main(int iArgc, char** cppArgv)
{
glutInit(&iArgc, cppArgv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(600, 600);
glutInitWindowPosition(200, 200);
glutCreateWindow("PIXELS");
glEnable(GL_DEPTH_TEST);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
when I run this program, all I get is a black screen.
Try this display function:
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
//set viewport
glViewport(0, 0, screen.width, screen.height);
//set projection matrix using intrinsic camera params
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float aspect = screen.width*1.0/screen.height;
//gluPerspective is arbitrarily set, you will have to determine these values based
//on the intrinsic camera parameters
gluPerspective(60.0f, aspect, 0.1f, 100.0f);
//you will have to set modelview matrix using extrinsic camera params
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0);
glLoadIdentity();
glTranslatef(0.0, 0.0, -5.0);
Draw();
glutSwapBuffers(); // Swap the front and back frame buffers (double buffering)
gluPostRedisplay();
}
In your case screen.width is 600 and screen.height is 600.
I am using Visual C++ and GLUT. Am I missing something such a normals? this is the exact code I am using. I tried to insert glNormal3f(0, 0, 1); before the vertex statements but this did not change anything. The glutSolidSphere renders just as I expect it to but not the quad.
#include "stdafx.h"
#include <stdlib.h>
#include <GL/glut.h>
float spin = 0.0f;
float zDir = 0;
GLfloat diffuseIntensity[] = {.75, .75, .75, 1};
GLfloat specularHue[] = {0, 0, .5f, 1};
GLfloat shininess[] = {5};
void moveCamera();
void checkKeys(int, int, int);
void setUpLighting();
void changeSize(int w, int h) {
if (h == 0)
h = 1;
float ratio = w * 1.0 / h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, w, h);
gluPerspective(45,ratio,1,1000);
glMatrixMode(GL_MODELVIEW);
}
void renderScene(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
moveCamera();
glTranslatef(0, 0, zDir-5);
glEnable(GL_COLOR_MATERIAL);
glShadeModel(GL_FLAT);
glMaterialfv(GL_FRONT, GL_SHININESS, shininess);
glMaterialfv(GL_FRONT, GL_SPECULAR, specularHue);
glPushMatrix();
glRotatef(90, 1, 0, 0);
glRotatef(spin, 0, 0, 1);
glutSolidSphere(.5f, 24, 24);
glPopMatrix();
spin += .01f;
if(spin > 360) spin -= 360;
glBegin(GL_QUADS);
glVertex3f(-10, 0, -10);
glVertex3f(-10, 0, 10);
glVertex3f(10, 0, 10);
glVertex3f(10, 0, -10);
glEnd();
glutSwapBuffers();
glutPostRedisplay();
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(800,600);
glutCreateWindow("Lighthouse3D - GLUT Tutorial");
glutDisplayFunc(renderScene);
glutReshapeFunc(changeSize);
glutSpecialFunc(checkKeys);
glEnable(GL_DEPTH_TEST);
setUpLighting();
glutMainLoop();
return 1;
}
void moveCamera(){
glTranslatef(0, 0, zDir);
}
void checkKeys(int key, int x, int y){
switch(key){
case GLUT_KEY_UP:
zDir += .1f;
glutPostRedisplay();
break;
case GLUT_KEY_DOWN:
zDir += -.1f;
glutPostRedisplay();
break;
case GLUT_KEY_END:
exit(0);
}
}
void setUpLighting(){
GLfloat position0[] = {3, 1, 0, 1};
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, position0);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseIntensity);
}
Give this a shot:
#include <GL/glut.h>
float zDir = 12;
void checkKeys(int key, int x, int y)
{
switch(key)
{
case GLUT_KEY_UP:
zDir += -.5f;
glutPostRedisplay();
break;
case GLUT_KEY_DOWN:
zDir += .5f;
glutPostRedisplay();
break;
case GLUT_KEY_END:
exit(0);
}
}
float spin = 0;
void renderScene(void)
{
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
gluPerspective(45,w/h,0.1,100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -zDir);
// set up light
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
GLfloat diffuseIntensity[] = {.75, .75, .75, 1};
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseIntensity);
// draw sphere at light position
glDisable( GL_LIGHTING );
glPushMatrix();
// spin light position around the y axis
glRotatef( -spin, 0, 1, 0 );
GLfloat position0[] = {3,3,3, 1};
glLightfv(GL_LIGHT0, GL_POSITION, position0);
glTranslatef( position0[0], position0[1], position0[2] );
glColor3ub(255,255,255);
glutSolidSphere(0.1,8,8);
glPopMatrix();
glEnable( GL_LIGHTING );
// draw sphere
glEnable(GL_COLOR_MATERIAL);
glShadeModel(GL_FLAT);
GLfloat specularHue[] = {0, 0, .5f, 1};
GLfloat shininess[] = {5};
glMaterialfv(GL_FRONT, GL_SHININESS, shininess);
glMaterialfv(GL_FRONT, GL_SPECULAR, specularHue);
spin += .01f;
if(spin > 360) spin -= 360;
glPushMatrix();
glRotatef(spin, 0, 1, 0);
glutSolidSphere(2, 24, 24);
glPopMatrix();
// draw quad
glColor3ub(255,0,0);
glPushMatrix();
glScalef( 3, 3, 3 );
glBegin(GL_QUADS);
glNormal3f( 0, 0, 1 );
glVertex2f( -1, -1 );
glVertex2f( 1, -1 );
glVertex2f( 1, 1 );
glVertex2f( -1, 1 );
glEnd();
glPopMatrix();
glutSwapBuffers();
glutPostRedisplay();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(800,600);
glutCreateWindow("Lighthouse3D - GLUT Tutorial");
glutDisplayFunc(renderScene);
glutSpecialFunc(checkKeys);
glutMainLoop();
return 1;
}
The quad is rendered, but you don't see it because it is drawn very much like the surface of a table and your eyes are at the same level of the table. Because of this, the effect is like that of which nothing was drawn at all. That or you'll see a line.
Your rotation above, being wrapped in a PushMatrix/PopMatrix only works with the solid sphere.
I want to draw several cubes using glutSolidCube in some points in space. The examples I have found just call glutSolidCube and it works, but the only way a cube gets drawn for me is if the line is enclosed in glBegin(GL_POLYGON), which isn't required in the examples I've seen, and I only get one cube instead of several. What I have is:
glColor3f(1, 0, 0);
glLoadIdentity();
glTranslatef(5,2,1);
glutSolidCube(1);
glLoadIdentity();
glTranslatef(10,8,0);
glutSolidCube(1);
glLoadIdentity();
glTranslatef(3,7,9);
glutSolidCube(1);
glLoadIdentity();
glTranslatef(1,4,6);
glutSolidCube(1);
When I run this nothing happens. I know there's not a problem with the points being outside my view because if I draw vertices at the same points, I can see them. As far as I can tell from the examples and documentation I've read, I'm not doing anything incorrect. Can someone tell me what I'm doing wrong or give me a snippet of code that draws multiple cubes?
Try this:
glColor3f(1, 0, 0);
glPushMatrix();
glTranslatef(5,2,1);
glutSolidCube(1);
glPopMatrix();
glPushMatrix();
glTranslatef(10,8,0);
glutSolidCube(1);
glPopMatrix();
glPushMatrix();
glTranslatef(3,7,9);
glutSolidCube(1);
glPopMatrix();
glPushMatrix();
glTranslatef(1,4,6);
glutSolidCube(1);
glPopMatrix();
Without re-setting the model view matrix with glLoadIdentity(). Note that to start with you need to call glOrtho() or glPerspective() to set the camera once.
#include <GL/glut.h>
void init()
{
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
double aspect = (double)viewport[2] / (double)viewport[3];
gluPerspective(60, aspect, 1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// move back a bit
glTranslatef( 0, 0, -35 );
static float angle = 0;
angle += 1.0f;
glPushMatrix();
glTranslatef(0,0,0);
glRotatef(angle, 0.1, 0.2, 0.5);
glColor3ub(255,0,255);
glutSolidCube(5);
glPopMatrix();
glPushMatrix();
glTranslatef(10,-10,0);
glRotatef(angle, 0.1, 0.2, 0.5);
glColor3ub(255,0,0);
glutSolidCube(5);
glPopMatrix();
glPushMatrix();
glTranslatef(10,10,0);
glRotatef(angle, 0.1, 0.2, 0.5);
glColor3ub(0,255,0);
glutSolidCube(5);
glPopMatrix();
glPushMatrix();
glTranslatef(-10,10,0);
glRotatef(angle, 0.1, 0.2, 0.5);
glColor3ub(0,0,255);
glutSolidCube(5);
glPopMatrix();
glPushMatrix();
glTranslatef(-10,-10,0);
glRotatef(angle, 0.1, 0.2, 0.5);
glColor3ub(255,255,0);
glutSolidCube(5);
glPopMatrix();
glutSwapBuffers();
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
}
void timer(int extra)
{
glutPostRedisplay();
glutTimerFunc(16, timer, 0);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitWindowSize(640,480);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutCreateWindow("CUBES");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutTimerFunc(0, timer, 0);
init();
glutMainLoop();
return 0;
}
I am practicing the exercises from my textbook but I could not get the outputs that I should.
Here is what I have :
#include <math.h>
#include <GLUT/glut.h>
#include <OpenGL/OpenGL.h>
//Initialize OpenGL
void init(void) {
glClearColor(0.0,0.0,0.0,0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0,300.0,0.0,300.0);
}
void drawLines(void) {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0,0.4,0.2);
glPointSize(3.0);
glBegin(GL_LINES);
glVertex2d(180, 15);
glVertex2d(10, 145);
glEnd();
}
int main(int argc, char**argv) {
glutInit(&argc, argv);
glutInitWindowPosition(10,10);
glutInitWindowSize(500,500);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutCreateWindow("Example");
init();
glutDisplayFunc(drawLines);
glutMainLoop();
}
When I run this piece of code, I get completely blank white screen.
i'm also not an expert on OpenGL but the problem is that you haven't set a viewport to where your scene should be projected. Your init should look somewhat like this:
glClearColor(0, 0, 0, 0);
glViewport(0, 0, 500, 500);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 500, 0, 500, 1, -1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
You also need to put a glFlush(); after your drawing.
void drawLines(void) {
...
glFlush();
}
Determine and draw the output of OpenGL sub function below:
1.
glColor3f(0.0, 0.0, 0.0, 0.0);
glBegin(Gl_LINES);
glVertex2i (200, 200);
glVertex2i (70, 20);
glVertex2i (120, 150);
glVertex2i (200, 20);
glVertex2i (60, 100);
glEnd();
int p1[]={200,100};
int p2[]={70,20};
int p3[]={120,150};
int p4[]={200,20};
int p5[]={60,100};
glBegin(GL_LINE_STRIP);
glVertex2iv (p1);
glVertex2iv (p2);
glVertex2iv (p3);
glVertex2iv (p4);
glVertex2iv (p5);
glEnd();