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've been testing with OpenGL for a while and have not been able to get the depth buffer to work, despite using GLUT_DEPTH as a parameter in glutInitDisplayMode and doing glClear(GL_DEPTH_BUFFER_BIT) at the start of the display function. I don't know what else I'm missing.
Below is a minimum working example and Figure 1 and 2. Comment out the parameters under Figure 1 and 2 when you want to view the other one.
Figure 1 (above blue):
Figure 2 (below red):
Example:
#include <vector>
#include <gl\glut.h>
typedef std::vector<float> floatvec;
// Figure 1 (above blue)
float posX = 8.00f;
float posY = 7.54f;
float posZ = -0.89f;
float angleX = 300.50f;
float angleY = 45.33f;
// Figure 2 (below red)
float posX = 4.12f;
float posY = -4.87f;
float posZ = -3.84f;
float angleX = 343.25f;
float angleY = -45.00f;
int screenW = 720;
int screenH = 540;
float fMin = 0.5;
float fMax = 100.0;
float alpha = 60.0;
// Draws a rectangle in 3D
void DrawQuad(floatvec c) {
glBegin(GL_QUADS);
glVertex3f(-c[0], -c[1], -c[2]);
glVertex3f(-c[3], -c[4], -c[5]);
glVertex3f(-c[6], -c[7], -c[8]);
glVertex3f(-c[9], -c[10], -c[11]);
glEnd();
}
void Display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glPushMatrix();
glRotatef(angleY, 1.0f, 0.0f, 0.0f);
glRotatef(angleX, 0.0f, 1.0f, 0.0f);
glRotatef(180.0, 0.0f, 0.0f, 1.0f);
glTranslatef(posX, posY, posZ);
// Draws the tiles
glColor3f(1.0, 0.0, 0.0); // Red
DrawQuad({ 0, 0, 0,
5, 0, 0,
5, 0, 5,
0, 0, 5 });
glColor3f(0.0, 0.0, 1.0); // Blue
DrawQuad({ 0, 3, 0,
5, 3, 0,
5, 3, 5,
0, 3, 5 });
glPopMatrix();
glutSwapBuffers();
}
void Reshape(int width, int height) {
glViewport(0, 0, (GLsizei)width, (GLsizei)height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(alpha, (GLfloat)width / (GLfloat)height, fMin, fMax);
glMatrixMode(GL_MODELVIEW);
}
int main(int iArgc, char** cppArgv) {
glutInit(&iArgc, cppArgv);
glEnable(GL_DEPTH_TEST);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(screenW, screenH);
glutCreateWindow("Example");
glutDisplayFunc(Display);
glutIdleFunc(Display);
glutReshapeFunc(Reshape);
glutMainLoop();
return 0;
}
You just need to change where you call glEnable(GL_DEPTH_TEST);
Put it after glutCreateWindow and it will work fine.
Something like this:
int main(int iArgc, char** cppArgv) {
glutInit(&iArgc, cppArgv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(screenW, screenH);
glutCreateWindow("Example");
glEnable(GL_DEPTH_TEST);
glutDisplayFunc(Display);
glutIdleFunc(Display);
glutReshapeFunc(Reshape);
glutMainLoop();
return 0;
}
Just tested here and it worked.
I am a little bit rusty in OpenGL, but, putting the glEnable line in the Display function will make the trick.
#include <vector>
#include <GL/glut.h>
typedef std::vector<float> floatvec;
//Figure 1 (above blue)
//float posX = 8.00f;
//float posY = 7.54f;
//float posZ = -0.89f;
//float angleX = 300.50f;
//float angleY = 45.33f;
// Figure 2 (below red)
float posX = 4.12f;
float posY = -4.87f;
float posZ = -3.84f;
float angleX = 343.25f;
float angleY = -45.00f;
int screenW = 720;
int screenH = 540;
float fMin = 0.5;
float fMax = 100.0;
float alpha = 60.0;
// Draws a rectangle in 3D
void DrawQuad(floatvec c) {
glBegin(GL_QUADS);
glVertex3f(-c[0], -c[1], -c[2]);
glVertex3f(-c[3], -c[4], -c[5]);
glVertex3f(-c[6], -c[7], -c[8]);
glVertex3f(-c[9], -c[10], -c[11]);
glEnd();
}
void Display() {
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glPushMatrix();
glRotatef(angleY, 1.0f, 0.0f, 0.0f);
glRotatef(angleX, 0.0f, 1.0f, 0.0f);
glRotatef(180.0, 0.0f, 0.0f, 1.0f);
glTranslatef(posX, posY, posZ);
// Draws the tiles
glColor3f(1.0, 0.0, 0.0); // Red
DrawQuad({ 0, 0, 0,
5, 0, 0,
5, 0, 5,
0, 0, 5 });
glColor3f(0.0, 0.0, 1.0); // Blue
DrawQuad({ 0, 3, 0,
5, 3, 0,
5, 3, 5,
0, 3, 5 });
glPopMatrix();
glutSwapBuffers();
}
void Reshape(int width, int height) {
glViewport(0, 0, (GLsizei)width, (GLsizei)height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(alpha, (GLfloat)width / (GLfloat)height, fMin, fMax);
glMatrixMode(GL_MODELVIEW);
}
int main(int iArgc, char** cppArgv) {
glutInit(&iArgc, cppArgv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(screenW, screenH);
glutCreateWindow("Example");
glutDisplayFunc(Display);
glutIdleFunc(Display);
glutReshapeFunc(Reshape);
glutMainLoop();
return 0;
}
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.
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();