Rotation of an object in opengl - c++

I need to rotate the rectangular object upon pressing the left arrow key.
I am not able to rotate it, or maybe it is. There may be a problem playing with the buffer.
Weather the rotatef() function is placed correctly or where the problem lies.
#include<stdlib.h>
#include<glut.h>
#include<stdio.h>
#include<math.h>
#include<time.h>
void rot()
{ glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glPushMatrix();
glRotatef(30,0.0,0.0,1.0);
glBegin(GL_POLYGON);
glVertex2i(50,50);
glVertex2i(170,50);
glVertex2i(170,100);
glVertex2i(50,100);
glEnd();
glPopMatrix();
}
void shape()
{
glColor3f(1.0,0.0,0.0);
glBegin(GL_POLYGON);
glVertex2i(50,50);
glVertex2i(170,50);
glVertex2i(170,100);
glVertex2i(50,100);
glEnd();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
shape();
glutSwapBuffers();
glFlush();
}
void init()
{
glClearColor(1.0,1.0,1.0,1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glOrtho(0,700,0,700,-1,1);
glMatrixMode(GL_MODELVIEW);
}
void Keys(int key,int x,int y)
{
if(key==GLUT_KEY_LEFT)
rot();
glutPostRedisplay();
}
void main(int argc,char**argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
glutInitWindowSize(700,700);
glutCreateWindow("tetris");
glutDisplayFunc(display);
glutSpecialFunc(Keys);
init();
glutMainLoop();
}

You post a redisplay immediately after drawing your rotated vertices.
So right after drawing the rotated vertices, in your display callback function, you clear the window and then draw your vertices without rotation. So that is what you'll see (without rotation), until the next update.
One way to proceed is:
Do all your drawing in your display function
As reaction to a keypress, just update the angle ( I guess you want to rotate incrementally) and post a redisplay. Don't draw anything, your display function will use the updated angle.

Related

Rotate a simple polygon in OpenGL

I follow the code tutorial from the OpenGL programming book, but it doesn't work. It is showing white rectangle at the top left of my window. Could you please tell me what could be wrong with it?
#include<windows.h>
#include <GL/glut.h>
float yRot=0.0;
void Render()
{
//clear color and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();//load identity matrix
glTranslatef(0.0f,0.0f,-4.0f);//move forward 4 units
//rotate along the y-axis
glRotatef(yRot,0.0f,1.0f,0.0f);
glColor3f(0.0f,0.0f,1.0f); //blue color
glBegin(GL_POLYGON);//begin drawing of polygon
glVertex3f(-0.5f,0.5f,0.0f);//first vertex
glVertex3f(0.5f,0.5f,0.0f);//second vertex
glVertex3f(1.0f,0.0f,0.0f);//third vertex
glVertex3f(0.5f,-0.5f,0.0f);//fourth vertex
glVertex3f(-0.5f,-0.5f,0.0f);//fifth vertex
glVertex3f(-1.0f,0.0f,0.0f);//sixth vertex
glEnd();//end drawing of polygon
yRot+=0.1f;//increment the yRot variable
}
//method the reshape the entire figure.
void reshape(int x, int h){
glViewport(0,0,x,h);
}
void init()
{
glClearColor(0.0,0.0,0.2,0.8);
}
int main(int argc, char** argv)
{
glutCreateWindow("simple triangles");
glutDisplayFunc(Render);
glutReshapeFunc(reshape);
init();
glutMainLoop();
}
First of all, you're not calling glutInit(&argc, argv) in main() before all the other GLUT related calls. Second of all, you're not calling glutSwapBuffers() in Render().
Besides that you aren't changing the projection matrix, and thus don't have the same resize function as the one presented in the beginning of the tutorial.
void Resize(int width, int height)
{
glViewport(0, 0, (GLsizei)width, (GLsizei)height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 1.0f, 1000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
Changing those things and your code should work.

Simple GLUT library issue

This will be my first post on stackoverflow.
So, I'm making a simple program(VISUAL STUDIO 2012), using GLUT library. I basically try to display a torus, but instead I get a black screen.
#include<gl/glut.h>
#include<math.h>
GLfloat r=8;
GLint spin=0;
GLfloat light_position[]={0.0,0.0,0.0,1.0};
GLfloat ex,ey=0, ez, upx=0, upy=0, upz=0;
void init(){
glClearColor(1.0,1.0,1.0,1.0);
glShadeModel(GL_FLAT);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
}
void display(void){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_TEST);
glPushMatrix();
double sine = (float)sin((float)spin);
double cosine = (float)cos((float)spin);
ex=r*sine;
ez=r*cosine;
gluLookAt(ex,ey,-5.0,0,0,0,upx,upy,upz);
glColor3b(1.0,0,0);
glutSolidTorus(0.275,0.85,8,15);
glPopMatrix();
glFlush();
}
void reshape(int w, int h)
{
glViewport(0,0,(GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluPerspective(40.0, (GLfloat) w/(GLfloat) h, 1.0,20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLightfv( GL_LIGHT0, GL_POSITION, light_position);
}
void mouse(int button, int state, int x, int y)
{
switch(button)
{
case GLUT_LEFT_BUTTON:
if( state == GLUT_DOWN){
spin = (spin+15)%360;
glutPostRedisplay();
}
break;
default:
break;
}
}
void main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowSize(800,600);
glutInitWindowPosition(300,300);
glutCreateWindow("Light Rotating Torus");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMainLoop();
}
Can somebody modify it/give a hint, so it displays something?
Thanks
The most obvious problem is your UP vector. You set upx, upy and upz. That is not a valid up vector, try changing upy to 1.0f. Because of this, your torus was probably rendered out of screen.
Also, glClear doesn't take GL_DEPTH_TEST as a parameter.
Correct call should be:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Because of this, your screen was not cleared and stayed black (while you set glClearColor to be white).
And lastly, main function should always return int, never void (though it doesn't change anything in your case)

Using glutPassiveMotionFunc(); in GLUT

I have written a simple OpenGL program in C++ that displays a line joining the center of the window to the current position of the mouse pointer.
My code is :
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include<iostream>
using namespace std;
void passive(int,int);
void reshape(int,int);
void init(void);
void display(void);
void camera(void);
int x=3,y=3;
int main (int argc,char **argv) {
glutInit (&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA);
glutInitWindowSize(1364,689);
glutInitWindowPosition(0,0);
glutCreateWindow("Sample");
init();
glutDisplayFunc(display);
glutIdleFunc(display);
glutPassiveMotionFunc(passive);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
void display(void) {
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
camera();
glBegin(GL_LINES);
glVertex3f(0,0,0);
glVertex3f(x,y,0);
glEnd();
glutSwapBuffers();
}
void camera(void) {
glRotatef(0.0,1.0,0.0,0.0);
glRotatef(0.0,0.0,1.0,0.0);
glTranslated(0,0,-20);
}
void init(void) {
glEnable (GL_DEPTH_TEST);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_COLOR_MATERIAL);
}
void reshape(int w, int h) {
glViewport(0,0,(GLsizei)w,(GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60,(GLfloat)w/(GLfloat)h,1.0,100.0);
glMatrixMode(GL_MODELVIEW);
}
void passive(int x1,int y1) {
x=x1; y=y1;
}
The problem I am facing is that the x and y values set in the passive() function is not correctly mapped into the screen which uses perspective projection. So the line drawn is joining the center to some other coordinate outside the screen. Any modifications to the code to get it working properly?
An easy way would be to create an orthographic projection matrix and then render all of your "2D" elements (including this line, using the screen coordinates provided by glutPassiveMotionFunc).
Something like this:
void display() {
// clear
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective( ... ) // create 3D perspective projection matrix
glMatrixMode(GL_MODELVIEW);
// Render 3D content here
// Render 2D content
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, width, height, 0); // create 2D orthographic projection matrix with coordinate system roughly equivalent to window position
glMatrixMode(GL_MODELVIEW);
glBegin(GL_LINES);
glVertex2f( width / 2, height / 2 ); // now we can use "pixel coordinates"
glVertex2f( cursorX, cursorY );
glEnd();
...
}
Compare this to your modification of the perspective projection in your reshape method.
Obviously you'll also want to disable states that don't make sense for a "2D" rendering (like depth buffer checking, etc) but it should be pretty obvious. Take a look at this GDSE post for a discussion of how other people do this same task.

Opengl proper lighting problem

I have written the following program to display a teapot on a table in a room with 2side walls and a floor.
#include <stdio.h>
#include <glut.h>
void wall1(float thickness)
{
glPushMatrix();
glTranslatef(100,100,0);
glRotatef(90,1,0,0);
glScalef(thickness,1,1);
glutSolidCube(100);
glPopMatrix();
}
void wall2(float thickness)
{
glPushMatrix();
glTranslatef(150,100,-50);
glScalef(1,1,thickness);
glutSolidCube(100);
glPopMatrix();
}
void floor(float thickness)
{
glPushMatrix();
glTranslatef(150,50,0);
glScalef(1,thickness,1);
glutSolidCube(100);
glPopMatrix();
}
void leg(float thickness)
{
glPushMatrix();
glScalef(thickness,.5,thickness);
glutSolidCube(100);
glPopMatrix();
}
void tableTop(float thickess)
{
glPushMatrix();
glTranslatef(150,100,0);
glScalef(.5,thickess,.5);
glutSolidCube(100);
glPopMatrix();
}
void table()
{
tableTop(.05);
glPushMatrix();
glTranslatef(125,75,-25);
leg(.05);
glPopMatrix();
glPushMatrix();
glTranslatef(175,75,-25);
leg(.05);
glPopMatrix();
glPushMatrix();
glTranslatef(175,75,25);
leg(.05);
glPopMatrix();
glPushMatrix();
glTranslatef(125,75,25);
leg(.05);
glPopMatrix();
glPushMatrix();
glTranslatef(150,110,0);
glScalef(.1,.1,.1);
glutSolidTeapot(100);
glPopMatrix();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float pos[] = {200,200,0};
float dif[] = {.3,.3,.3,3};
float spe[] = {1,1,1,1};
float amb[] = {1,1,1,0};
glLightfv(GL_LIGHT0,GL_POSITION,pos);
glLightfv(GL_LIGHT0,GL_DIFFUSE,dif);
glLightfv(GL_LIGHT0,GL_AMBIENT,amb);
glLightfv(GL_LIGHT0,GL_SPECULAR,spe);
glTranslatef(50,50,0);
glRotatef(30,1,0,0);
glRotatef(-30,0,1,0);
wall1(.05);
wall2(.05);
floor(0.05);
table();
glFlush();
}
void reshape(int w,int h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,400,0,400,-400,400);
glMatrixMode(GL_MODELVIEW);
}
void main(int argc,char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH);
glutInitWindowPosition(100,100);
glutInitWindowSize(400,400);
glutCreateWindow("woot");
glClearColor(1,1,1,1);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glShadeModel(GL_SMOOTH);
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMainLoop();
}
The problem with this is my lighting part is not working as expected. Its not illuminating evenly all my objects... What am i missing? This making even the teapot hard to sea.
My lighting part is in display function.
I was missing
glEnable(GL_NORMALIZE);
in the main function, and thus opengl was not rendering it properly! Alse #Christian's answer of using ambient only worked.
:)
OpenGL fixed function pipeline lighting is evaluated at the vertices only. glutSolidCube just creates vertices at the corners and nowhere else. So your lighting is calculated only very coarse. You could either switch to per fragment lighting by using a shader, or tesselate your objects. The latter requires you don't use glutSolidCube and instead load objects modelled in a 3D modeller or write your own primitive generators that offer a higher tesselation. I strongly recommend the first option.
glutSolidCube is just a very crude stand in function BTW.
If you want to evenly light all objects, only use ambient lighting.

basic GL function glTranslatef don't seem to be working

I was following this tutorial, the triangle renders perfectly, but when I hit the Page Up key, nothing happens.
Here's my code:
// made in Visual Studio Express 2008
// OpenGL3-1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
// if you are not using Visual Studio to compile this then remove stdafx.h
#include <stdlib.h>
#include <windows.h>
#include "glut.h"
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST);
glShadeModel (GL_SMOOTH);
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* Loading the Identity matrix means we reset the screen coordinate system to XYZ axis of lenght 1:
The screen starts at z=0, x=-1 to x=1 and y=-1 to y=1 */
glLoadIdentity ();
glTranslatef(0,0.0f,-6.0f);
// translate everything by 6 units in the z axis.
glBegin(GL_TRIANGLES);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f( 0.0f, 1.0f, 0.0f);
glColor3f(0.0f,1.0f,0.0f); // Set The Color To Green
glVertex3f(-1.0f,-1.0f, 0.0f);
glColor3f(0.0f,0.0f,1.0f); // Set The Color To Blue
glVertex3f( 1.0f,-1.0f, 0.0f);
glEnd(); // Done Drawing A Triangle
Sleep(5);
glutSwapBuffers();
}
void reshape (int w, int h)
{
// just the window reshape function
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
glMatrixMode (GL_MODELVIEW);
}
void keyboard(unsigned char key, int x, int y)
{
// escapes from the program if the ESC key is hit
switch (key) {
case 27:
exit(0);
break;
}
}
void keyspecial( int key, int x, int y )
{
if( key == GLUT_KEY_PAGE_UP) // Page up
{
glTranslatef(90.0,0.0,0.0);
// ...... do what ever you want to do
glutPostRedisplay(); // redraw everything to reflect the changes
}
if (key == GLUT_KEY_PAGE_DOWN)
{
// ...... do what ever you want to do
glutPostRedisplay();// redraw everything to reflect the changes
}
if (key == GLUT_KEY_HOME)
{
// ...... do what ever you want to do
glutPostRedisplay();// redraw everything to reflect the changes
}
if (key == GLUT_KEY_END)
{
// ...... do what ever you want to do
glutPostRedisplay();// redraw everything to reflect the changes
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard); // tell glut to call this function when the user presses a key
glutSpecialFunc(keyspecial); // tell glut to call this function when the user presses a special a key
glutMainLoop();
return 0;
}
Note:
The tutorial suggested using glTranslate(x,y,z) instead of glTranslatef(x,y,z). I assumed that was a typo since glTranslate() doesn't exist
You're resetting your matrix in display, so your glTranslate* from the key event handler is lost. Rethink what you're trying to achieve.
What you're doing in this function is not the right thing to do
void reshape (int w, int h)
{ // just the window reshape function
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
glMatrixMode (GL_MODELVIEW);
}
Speak with me: Don't set the viewport size and projection in the reshape handler!
You always set viewport and projection together with everything else in the display handler. It's the only right place to do it.
Next, you don't "place" objects using OpenGL matrix functions. You're just manipulating the transformation matrix, which should be set according to the placement of the objects, which may be perfectly well stored as matrix but independently of OpenGL state. So your keyboard handler should set some variable, which is then used for setting the modelview matrix at the right moment.