I don't know if I did something wrong in my functions (maybe wrong parameters to glOrtho) and so the result is just wrong or if it's all normal as it would be.
In particular I have this situation:
I would like to have the green rect and all its inner content to take all the space of the window and not just a part of it (if you notice there are some empty spaces all around the main content: "the green rect").
Here there are my main functions:
#define HEXAGONAL_SHRINK 0.8655f
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(640, 480);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}
void reshape(int w, int h)
{
GLfloat aspect, dim;
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (s3hex->rows > s3hex->columns)
dim = s3hex->rows * 0.5f;
else
dim = s3hex->columns * 0.5f;
aspect = (GLfloat)w / (GLfloat)h;
if (w <= h)
glOrtho (-dim, dim, -dim/aspect, dim/aspect, 1.0, -1.0);
else
glOrtho (-dim*aspect, dim*aspect, -dim, dim, 1.0, -1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void display(void)
{
CALint i, j;
CALreal z, h, color;
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glTranslatef(-(s3hex->columns*HEXAGONAL_SHRINK)/2.0f, s3hex->rows/2.0f, 0);
glScalef(HEXAGONAL_SHRINK, -1, 1);
for (i=0; i<s3hex->rows; i++)
for (j=0; j<s3hex->columns; j++)
{
z = calGet2Dr(s3hex,Q.z,i,j);
h = calGet2Dr(s3hex,Q.h,i,j);
if (h > 0)
{
color = (h - h_min) / (h_Max - h_min);
glColor3d(1,color,0);
glRecti(j, i, j+1, i+1);
}
else
if (z > 0)
{
color = (z - z_min) / (z_Max - z_min);
glColor3d(color,color,color);
glRecti(j, i, j+1, i+1);
}
}
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glColor3d(0,1,0);
glRectd(0,0,s3hex->columns, s3hex->rows);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glPopMatrix();
glutSwapBuffers();
}
P.S: If you need to know what's s3hex is, then you can see it as a normal matrix in which every cell contains a set of substates. Then in according to the value of these substates I set the colors for the rendering in the display func.
Everything seems normal to me.
Nothing guaranties that s3hex->columns and s3hex->rows will match your viewport size.
What you can do is to scale up the modelview to make the drawing fill your viewport.
Something along the lines of:
glScalef(viewportWidth / s3hex->columns, viewportHeight / s3hex->rows, 1);
Don't do this if s3hex->columns or s3hex->rows is zero.
Related
I am unable to understand why I am not getting any output for the given program. This problem has been occurring to me for my last 2 openGL programs, the previous one being DDA algorithm, again in which I didnt get any output. Is there a problem with the algorithm, or in my understanding how openGL works internally ?
#include <iostream>
#include <GL/glut.h>
using namespace std;
float X1 = 0, X2 = 100, Y1 = 0, Y2 = 400, X11, Y11, X22, Y22, slope, dely, delx, c, intercept, pi;
float absl(float x) {
if (x >= 0) return x;
return -1*x;
}
void drawScene() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 500, 0, 500);
glClearColor(1.0, 1.0, 1.0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
//start bresenham algo
glBegin(GL_POINTS);
glVertex2f(X1, Y1);
while(X1 <= X2) {
X1++;
if(pi < 0) {
glVertex2f(X1, Y1);
}
else {
Y1++;
glVertex2f(X1, Y1);
}
float flag = (pi >= 0);
pi = pi + 2*dely - 2*delx*flag;
}
glEnd();
//end DDA algo
glFlush();
}
int main(int argc, char **argv) {
//cin >> X1 >> Y1 >> X2 >> Y2;
// dely = Y2 - Y1;
// delx = X2 - X1;
// pi = 2*dely - delx;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(0,0);
glutCreateWindow("DDA");
glutDisplayFunc(drawScene);
glutMainLoop();
return 0;
}
gluOrtho2D defines a 2D orthographic projection matrix. But it also multiplies the current matrix on the matrix stack with the orthographic projection matrix and replaces the current matrix with the product.
Note, in OpenGL fixed function pipeline all matrix operations work like this (except glPushMatrix, glPopMatrix, glLoadMatrix and glLoadIdentity).
This means you have to replace the current matrix with the identity matrix (glLoadIdentity), befor you apply the orthographic projection matrix:
glLoadIdentity();
gluOrtho2D(0, 500, 0, 500);
Or you do gluOrtho2D only one time before you start the main loop in the main function:
gluOrtho2D(0, 500, 0, 500);
glutMainLoop();
Since the display function is called (drawScene) continuously, you should use local control varibales and not modify X1 and Y1:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 500, 0, 500);
glClearColor(0.0, 0.0, 0.0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
//start bresenham algo
int x = X1, y = Y1;
glBegin(GL_LINES);
glVertex2f(100, 400);
glVertex2f(400, 100);
glEnd();
glBegin(GL_POINTS);
glVertex2f(x, Y1);
while(x <= X2) {
x ++;
if(pi < 0) {
glVertex2f(x, y);
}
else {
y ++
glVertex2f(x, y);
}
}
int flag = (pi >= 0);
pi = pi + 2*dely - 2*delx*flag;
glEnd();
I have this little program that is supposed to rotate a square in 2D. When I give it fixed vertexes, it works fine. But when I try to put it in motion, the square just starts to flash and blink and not really resemble a square at all. Everything looks good to me, so I must be missing something. Can anyone see it?
#include <stdio.h>
#include <math.h>
#include <glut/glut.h>
#define DEG_TO_RAD 0.017453
GLsizei ww, wh;
GLfloat theta;
void display()
{
//clear window
glClear(GL_COLOR_BUFFER_BIT);
//draw unit square polygon
glBegin(GL_POLYGON);
glVertex2f(sin(DEG_TO_RAD*theta), cos(DEG_TO_RAD*theta));
glVertex2f(-sin(DEG_TO_RAD*theta), cos(DEG_TO_RAD*theta));
glVertex2f(-sin(DEG_TO_RAD*theta), -cos(DEG_TO_RAD*theta));
glVertex2f(sin(DEG_TO_RAD*theta), -cos(DEG_TO_RAD*theta));
// glVertex2f(-0.5, -0.5);
// glVertex2f(-0.5, 0.5);
// glVertex2f(0.5, 0.5);
// glVertex2f(0.5, -0.5);
glEnd();
//flush gl buffers
glFlush();
}
void init() {
//set color to black
glClearColor(0.0, 0.0, 0.0, 0.0);
//set fill color to white
glColor3f(1.0, 1.0, 1.0);
//set up standard orthogonal view with clipping
//box as cube of side2 centered at origin
//this is default view and these statements could be removed
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.0, 1.0, -1.0, 1.0);
}
void myreshape(GLsizei w, GLsizei h) {
//adjust clipping window
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w<=h)
gluOrtho2D(-2.0, 2.0, -2.0 * (GLfloat) h / (GLfloat) w, 2.0 * (GLfloat) h / (GLfloat) w);
else
gluOrtho2D(-2.0 * (GLfloat) w / (GLfloat) h, 2.0 * (GLfloat) w / (GLfloat) h, -2.0, 2.0);
glMatrixMode(GL_MODELVIEW);
//adjust viewport
glViewport(0, 0, w, h);
//set global size for use by drawing routine
ww = w;
wh = h;
}
void myidle() {
theta += 2.0;
if (theta > 360.0) theta -= 360.0;
glutPostRedisplay();
}
int main(int argc, char** argv)
{
theta = 0.0;
// initialize mode and open a window in upper-left corner of screen
// window title is name of program (arg[0])
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);//Set the window size
glutInitWindowPosition(0, 0);
glutCreateWindow("rotating square");
glutDisplayFunc(display);
init();
glutReshapeFunc(myreshape);
glutIdleFunc(myidle);
glutMainLoop();
return 0;
}
Your vertex definitions just don't produce a square. Try the following:
glVertex2f(cos(DEG_TO_RAD*(theta + 135)), sin(DEG_TO_RAD*(theta + 135)));
glVertex2f(cos(DEG_TO_RAD*(theta + 45 )), sin(DEG_TO_RAD*(theta + 45 )));
glVertex2f(cos(DEG_TO_RAD*(theta - 45 )), sin(DEG_TO_RAD*(theta - 45 )));
glVertex2f(cos(DEG_TO_RAD*(theta - 135)), sin(DEG_TO_RAD*(theta - 135)));
The comment from Andon below your question is right. You should create the geometry (the vertices) only once and then rotate them by setting the matrix to ModelView and rotate with glRotatef(...). Recreating geometries on each render cycle is a wrong aproach.
this is my cube. Once created, it has a random x position on either -2, -1, 0, 1, or 2.
void cube(void)
{
srand (time(0));
int cube_posX;
int lowv = -2;
int highv = 2;
cube_posX = rand() % (highv - lowv + 1) + lowv;
glTranslatef(cube_posX, 0.0, cube_angle);
glRotatef(cube_angle, 90.0, 0.0, 1.0);
glutSolidCube(0.25);
}
and this is how I move the cube slowly forward
void MOVE_CUBE(int value)
{
cube_posZ = cube_posZ - 0.01;
glutPostRedisplay();
glutTimerFunc(25, MOVE_CUBE, 0);
}
and finally putting them in display:
void init(void)
{
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
}
float cam_eyeX = 0.0, cam_eyeY = 1.5, cam_eyeZ = 5.0;
float cam_centerX = 0.0, cam_centerY = 0.0, cam_centerZ = 0.0;
void display(void)
{
glClearColor(1.0,1.0,1.0,1.0); //to add background color (white)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(cam_eyeX, cam_eyeY, cam_eyeZ, cam_centerX, cam_centerY, cam_centerZ, 0.0, 1.0, 0.0); //camera! (cam position X, cam position Y, cam position Z, cam target X, cam target Y, cam target Z, up position X, up position Y, up position Z)
cube();
glutSwapBuffers();
angle += 0.05; //to affect the glRotate function
glFlush();
}
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);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); // Set up display buffer
glutInitWindowSize(750, 500); //window's size
glutInitWindowPosition(100, 100); //window's position
glutCreateWindow("Hendra Ganteng!"); //window's title
init();
glutDisplayFunc(display);
glutIdleFunc (display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard_Handler);
MOVE_CUBE(0);
glutMainLoop();
return 0;
}
But when I see it in action, the cube moves forward flawlessly, but keeps changing x position onto those 5 possibilities (-2,-1,0,1,2) every 0.5 to 1 second. If I disable the srand(time(0)), the cube changes its x position rapidly. I just want to make it stay in 1 x position so then I can call more cubes in different x position. Could someone please kindly what's wrong in my code?
How is that behaviour not expected? You are generating a random X position every time you display your cube. If you re-seed the random number generator using the time, then it will be start a different sequence whenever the time changes (once per second).
Instead, you should pre-generate your cube(s). How about this:
// Global cube data
struct Cube {
int x;
double angle;
};
vector<Cube> cubes;
const int num_cubes = 1;
// Example initialisation...
void InitCubes()
{
cubes.reserve(num_cubes);
for( int i = 0; i < num_cubes; i++ )
{
Cube cube;
cube.x = rand() % (highv - lowv + 1) + lowv;
cube.angle = 0.0;
cubes.push_back(cube);
}
}
Now the update/display cycles simply need to modify the angle, but not the x-position.
void UpdateCube( Cube & cube )
{
cube.angle += 0.05;
}
void DisplayCube( Cube & cube )
{
glTranslatef((double)cube.x, 0.0, cube.angle);
glRotatef(cube.angle, 90.0, 0.0, 1.0);
glutSolidCube(0.25);
}
In your main function, call InitCubes() during startup.
In your display function, do this:
void display(void)
{
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(cam_eyeX, cam_eyeY, cam_eyeZ, cam_centerX, cam_centerY, cam_centerZ, 0.0, 1.0, 0.0);
// Display cubes
for( int i = 0; i < cubes.size(); i++ ) DisplayCube( cubes[i] );
glutSwapBuffers();
glFlush();
// Update cubes for next render cycle.
for( int i = 0; i < cubes.size(); i++ ) UpdateCube( cubes[i] );
}
in this code i'm try to draw simple olympic ring and rotate it... the below work fine but i can't rotate the rings.. help me to solve this problme...
void myReshape (int width, int height)
{
glViewport (0, 0, width, height);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluOrtho2D (-5, 105, -5, 105);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glTranslatef (0.375, 0.375, 0.0);
}
int main (int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(100,100);
glutInitWindowSize(110*PIXEL_SIZE, 110*PIXEL_SIZE);
glutCreateWindow ("Olymipc Rings || rotation ");
glClearColor(1.0, 1.0, 1.0, 0.0);
glPointSize(PIXEL_SIZE);
glShadeModel (GL_FLAT);
glutDisplayFunc(display);
glutReshapeFunc(myReshape);
glutMainLoop();
return 0;
}
Use glRotatef(axis_x,axis_y,axis,z, angle) function before you draw the rings .
If you want to keep rotating the ring always use glutIdle(myidle) in your main() function and increment the value of angle there and also use glutPostRedisplay().
Use glPushMatrix() before and glPopMatrix() and after your ring drawings if you do not want the rotation to effect other drawings.
for example if you want to rotate your rings about x axis your code will look like
float angle=0;
void display (void) {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINE_LOOP);
glVertex2i(-1,-1);
glVertex2i(100,-1);
glVertex2i(100,100);
glVertex2i(-1,100);
glEnd();
glPushMatrix(); //enters temporarily in a stack
for(int i = 0 ; i <5; i++)
{
glRotatef(1,0,0, angle)
glColor3f(color[i][0],color[i][1],color[i][2]);
draw_circle(center[i][0],center[i][1],ring_radius);
}
glPopMatrix(); // comes out of the stack
glScalef(0.001, 0.001, 0.001);
drawText(MESSAGE);
glFlush();
}
void myidle()
{
angle++; //angle value keeps on increasing
glutPostRedisplay(); // draws your drawing with updated value of angle to the screen
}
int main (int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(100,100);
glutInitWindowSize(110*PIXEL_SIZE, 110*PIXEL_SIZE);
glutCreateWindow ("Olymipc Rings || rotation ");
glClearColor(1.0, 1.0, 1.0, 0.0);
glPointSize(PIXEL_SIZE);
glShadeModel (GL_FLAT);
glutDisplayFunc(display);
glutIdleFunc(myidle); //just like DisplayFunc keeps on getting calls
glutReshapeFunc(myReshape);
glutMainLoop();
return 0;
Read about glPopMatrix(), glPushMatrix() and call back functions like glutIdleFunc().
I hope this will help!!
Try this:
#include <stdlib.h>
#include <stdio.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <math.h>
#define PIXEL_SIZE 3
#define MESSAGE "hello world !"
void draw_circle(int x, int y, int r);
int ring_radius = 19;
int color[5][3]={{0,0,1}, {0,0,0},{1,0,0}, {1,1,0},{0,1,0}};
int center[5][2]={{15,60},{50,60},{85,60},{33,45},{68,45}};
//=========================================================
void drawText(const char * message)
{
glRasterPos2f((GLfloat)0, (GLfloat)-400);
while (*message)
{
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, *message);
glutStrokeCharacter(GLUT_STROKE_ROMAN,*message++);
}
}
void display (void)
{
int ms = glutGet(GLUT_ELAPSED_TIME);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluOrtho2D (-5, 105, -5, 105);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glTranslatef (0.375, 0.375, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINE_LOOP);
glVertex2i(-1,-1);
glVertex2i(100,-1);
glVertex2i(100,100);
glVertex2i(-1,100);
glEnd();
const float deg_per_sec = 60.0f;
float angle = deg_per_sec * ( (float)ms / 1000.0f );
for(int i = 0 ; i <5; i++)
{
glColor3f(color[i][0],color[i][1],color[i][2]);
glPushMatrix();
glTranslatef( center[i][0], center[i][1], 0 );
glRotatef(angle, 0, 0, 1);
glTranslatef( -center[i][0], -center[i][1], 0 );
draw_circle(center[i][0],center[i][1],ring_radius);
glPopMatrix();
}
glScalef(0.001, 0.001, 0.001);
drawText(MESSAGE);
glFlush();
glutSwapBuffers();
}
void draw_circle(int center_x, int center_y , int radius)
{
int r = radius;
int h = 1 - r ; /*initialization */
int x = 0;
int y = r;
int dU=3;
int dD = 5 - 2*r;
int i = center_x;
int j = center_y;
glPointSize(6);
glBegin(GL_POINTS);
while( y > x )
{
if (h<0)
{
dU= dU + 2;
h = h + dU;
x = x + 1;
dD = dD + 2;
}
else
{
dD = 2*(x-y) + 5;
h = h + dD;
x = x + 1;
y = y - 1;
dU = dU + 2;
dD = dD + 4;
}
glVertex2i(x+i, y+j);
glVertex2i(-x+i, y+j);
glVertex2i(x+i, -y+j);
glVertex2i(-x+i,-y+j);
glVertex2i(y+i, x+j);
glVertex2i(y+i, -x+j);
glVertex2i(-y+i, x+j);
glVertex2i(-y+i, -x+j);
}
glEnd();
}
void myReshape (int width, int height)
{
glViewport (0, 0, width, height);
}
void idle()
{
glutPostRedisplay();
}
int main (int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowPosition(100,100);
glutInitWindowSize(110*PIXEL_SIZE, 110*PIXEL_SIZE);
glutCreateWindow ("Olymipc Rings || rotation ");
glClearColor(1.0, 1.0, 1.0, 0.0);
glPointSize(PIXEL_SIZE);
glShadeModel (GL_FLAT);
glutDisplayFunc(display);
glutReshapeFunc(myReshape);
glutIdleFunc(idle);
glutMainLoop();
return 0;
}
glRotatef
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.