My OpenGL program is not working properly. Inside the drawScene() function I created two loops. One loop for GL_LINES another loop for GL_POINTS. The GL_LINES loop works fine but GL_POINTS loop doesn't work. Any help appreciated.
#include <iostream>
#include <stdlib.h>
#include <GL/glut.h>
#include <math.h>
#define PI 3.14159265
using namespace std;
//Called when a key is pressed
void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: //Escape key
exit(0);
}
}
//Initializes 3D rendering
void initRendering() {
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL); //Enable color
glClearColor(0.7f, 0.9f, 1.0f, 1.0f); //Change the background to sky blue
}
//Called when the window is resized
void handleResize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (double)w / (double)h, 1.0, 200.0);
}
float _angle = 0.0f;
float _cameraAngle = 0.0f;
float x = -1.5;
float y = -0.5;
//Draws the 3D scene
void drawScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLineWidth (9.0f);
glBegin(GL_LINES);
glColor3f(1.0f, 0.0f, 0.0f);
double r = 0.5;
for(int c = 0;c<=360;c++){
double y = r*cos (c*PI/180);
double x = r*sin (c*PI/180);
glVertex3d(x,y,-5.0);
glVertex3d(0.0,0.0,-5.0);
}
glEnd();
glPointSize (7.0f);
glBegin(GL_POINTS);
glColor3f(0.0f, 1.0f, 0.0f);
double r = 1.0;
for(int c = 0;c<=360;c++){
double y = r*cos (c*PI/180);
double x = r*sin (c*PI/180);
glVertex3d(x,y,-5.0);
//glVertex3d(0.0,0.0,-5.0);
}
glEnd();
glutSwapBuffers();
//glutPostRedisplay();
}
void update(int value) {
_angle += 2.0f;
if (_angle > 360) {
_angle -= 360;
}
glutPostRedisplay();
glutTimerFunc(60, update, 0);
}
int main(int argc, char** argv) {
//Initialize GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 400);
//Create the window
glutCreateWindow("two circle");
initRendering();
//Set handler functions
glutDisplayFunc(drawScene);
glutKeyboardFunc(handleKeypress);
glutReshapeFunc(handleResize);
glutTimerFunc(25, update, 0); //Add a timer
glutMainLoop();
return 0;
}
Right now, you're declaring the variable r in two places: where you set double r = 0.5; and at double r = 1.0;
Try changing it to:
double r = 0.5;
//First loop
r = 1.0;
//Second loop
Related
I am trying to scroll a text as a banner. I used openGL with glut to make this work. The whole code works if I use a figure like a square. The square scrolls over the screen.
Now I want to do this with text. Every time this program started. The text came at its starting position, but when the timer starts, it vanished. This is probably because the screen was cleared every clocktick, but the screen doesn't build up again.
Someone who can help me with this translation animation and text?
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <iostream>
#ifdef WIN32
#include <windows.h>
#endif
#include <GL/gl.h>
#include <GL/glut.h>
using namespace std;
static int font_index = 0;
int state = 1;
void print_bitmap_string(/*void* font,*/ const char* s)
{
while (*s) {
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, *s);
s++;
}
}
void my_reshape(int w, int h)
{
GLdouble size;
GLdouble aspect;
/* Use the whole window. */
glViewport(0, 0, w, h);
/* We are going to do some 2-D orthographic drawing. */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
size = (GLdouble)((w >= h) ? w : h) / 2.0;
if (w <= h) {
aspect = (GLdouble)h / (GLdouble)w;
glOrtho(-size, size, -size * aspect, size * aspect, -100000.0, 100000.0);
}
else {
aspect = (GLdouble)w / (GLdouble)h;
glOrtho(-size * aspect, size * aspect, -size, size, -100000.0, 100000.0);
}
/* Make the world and window coordinates coincide so that 1.0 in */
/* model space equals one pixel in window space. */
glScaled(aspect, aspect, 1.0);
/* Now determine where to draw things. */
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
float yild;
float ystep;
float x_pos = -200;
float y_pos = 70;
void draw()
{
const char* bitmap_font_names[7] = { "Hello train" };
/* Draw the strings, according to the current mode and font. */
glTranslatef(0.5, -100, 0);
//set the text color
glColor4f(0.0f, 255.0f, 140.0f, 1.0f);
ystep = 100.0;
yild = 20.0;
glRasterPos2f(x_pos, y_pos + 1.25 * yild);
print_bitmap_string(bitmap_font_names[0]);
}
void display(void)
{
//change background color
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
draw();
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_POLYGON);
glVertex2f(x_pos + 0.5f, 0.0f);
glVertex2f(x_pos+1.0f, 0.5f);
glVertex2f(x_pos+0.5f, 0.5f);
glEnd();
glutSwapBuffers();
}
void timer(int) {
glutPostRedisplay();
glutTimerFunc(1000 , timer, 0);
switch (state) {
case 1:
if (x_pos > -295) {
x_pos -= 1;
}
else {
state = -1;
}
break;
case -1:
x_pos = 180;
state = 1;
break;
}
cout << x_pos << endl;
}
int main(int argc, char** argv)
{
glutInitWindowSize(500, 150);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("Train Display");
glutDisplayFunc(display);
glutReshapeFunc(my_reshape);
glutTimerFunc(1000, timer, 0);
glutMainLoop();
return 0;
}
glTranslate does not just set a translation matrix, but multiply the current matrix by a translation matrix. You need to load the identity matrix with glLoadIdentity before glTranslatef or save and restore the current matrix with glPushMatrix/glPopMatrix:
void draw()
{
const char* bitmap_font_names[7] = { "Hello train" };
glPushMatrix();
/* Draw the strings, according to the current mode and font. */
glTranslatef(0.5, -100, 0);
//set the text color
glColor4f(0.0f, 255.0f, 140.0f, 1.0f);
ystep = 100.0;
yild = 20.0;
glRasterPos2f(x_pos, y_pos + 1.25 * yild);
print_bitmap_string(bitmap_font_names[0]);
glPopMatrix();
}
#include <stdio.h> // this library is for standard input and output
#include "glut.h"// this library is for glut the OpenGL Utility Toolkit
#include <math.h>
float squareX = 0.0f;
float squareY = -0.3f;
float squareZ = 0.0f;
static int flag = 1;
void drawShape(void) {
glTranslatef(squareX, squareY, squareZ);
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex2f(162, 50);
glVertex2f(162, 10);
glVertex2f(220, 10);
glVertex2f(220, 50);
glVertex2f(162, 50);
glEnd();
}
void initRendering() {
glEnable(GL_DEPTH_TEST);
}
// called when the window is resized
void handleResize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f, (float)w, 0.0f, (float)h, -1.0f, 1.0f);
}
void drawScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawShape();
glutSwapBuffers();
}
// make the square go up
void update(int value) {
if (flag) {
squareY += 1.0f;
if (squareY > 400.0) {
flag = 0;
}
}
glutPostRedisplay();
glutTimerFunc(25, update, 0);
}
// make the square go right
/* void update(int value) {
if (flag) {
squareX += 1.0f;
if (squareX > 400.0) {
flag = 0;
}
}
glutPostRedisplay();
glutTimerFunc(25, update, 0);
} */
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 400);
glutCreateWindow("Moving Square");
initRendering();
glutDisplayFunc(drawScene);
glutReshapeFunc(handleResize);
glutTimerFunc(25, update, 0);
glutMainLoop();
return(0);
}
I have uploaded this code before but this time I made the square go all the way up. The code just moves the square up, but I don't know how to position it on the left once it reaches the top, so then I can make it move to the right. I have uploaded a demonstration on how I want it to look below.
Preview:
What I want it to do next:
I recommend to initialize the variables squareX, squareY and squareZ with the start position of the rectangle:
float squareX = 162.0f;
float squareY = 0.0f;
float squareZ = 0.0f;
Do not draw a rectangle specific position, but draw a rectangle on the position (0,0) with a length (width, height). Let the model matrix (set by glTranslatef), do the job of the positioning:
void drawShape(void)
{
float width = 58.0f;
float height = 40.0f;
glTranslatef(squareX, squareY, squareZ);
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex2f(0, 0);
glVertex2f(width, 0);
glVertex2f(width, height);
glVertex2f(0, height);
glVertex2f(0, 0);
glEnd();
}
Use a variable state, which has stated the direction of the current movement:
int state = 1; // 0: stop; 1: move up; 2: move right
If the rectangle a certain position has reached, then the state has to be changed and a the new start position can be set. At the final position, the rectangle can stop or the process can even be restarted:
void update(int value)
{
if (state == 1) // 1 : move up
{
squareY += 1.0f;
if (squareY > 400.0)
{
state = 2;
squareX = 0.0f;
squareY = 180.0f;
}
}
else if (state == 2) // 2 : move right
{
squareX += 1.0f;
if (squareX > 400.0)
{
state = 0;
// restart
//state = 1;
//squareX = 162.0f;
//squareY = 0.0f;
}
}
glutPostRedisplay();
glutTimerFunc(25, update, 0);
}
I am trying to write a simple program that moves a Sphere around a Ellipse in OpenGL. I thought that if I set translate coordinates to the same as the Ellipse coordinates it would simulate motion.
This is the code I already have:
#include "stdafx.h"
#include <windows.h>
#include <GL/Gl.h>
#include <GL/GLU.h>
#include <GL/glut.h>
#include <math.h>
const float eRad = 6.5;
void drawSphere(void)
{
float x = 0.5;
float y = 0.4;
float z = 0.0;
glMatrixMode(GL_PROJECTION | GL_MODELVIEW);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT);
// Draw the Ellipse
glColor3d(1.0, 0.0, 1.0);
glBegin(GL_LINE_STRIP);
for (float i = 0; i <= eRad; i += 0.1)
{
glVertex2f(x*cos(i), y*sin(i));
}
glEnd();
//Draw the Sphere
glColor3d(1.0, 1.0, 0.0);
glPushMatrix();
glTranslatef(0.5, 0, 0);
glutWireSphere(0.15, 30, 30);
glPopMatrix();
glFlush();
}
void animation(void)
{
float x = 0.2;
float y = 0.1;
float z = 0.0;
for (float i = 0; i <= eRad; i += 0.1)
{
glTranslated(x*cos(i), y*sin(i), z);
}
drawSphere();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(600, 600);
glutInitWindowPosition(0, 0);
glutCreateWindow("Moving Sphere Test");
glutDisplayFunc(drawSphere);
glutIdleFunc(animation);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glViewport(0, 0, 600, 600);
glutMainLoop();
}
The issue I am having is that the Ellipse is drawn in and so is the sphere, but its just staying at one point on the ellipse. So what am I doing wrong?
Yes, you need to use the functions correctly. The animation happens in glutDisplayFunc, the state setting can happen in glutIdleFunc(It does not have to). The gultTimerFunc() callback is what you want to be called every frame. I made a few modifications to your code. But you might want to use the GLUT correctly.
const float eRad = 6.5;
static float iter = 0.0;
void drawSphere(void)
{
float x = 0.5;
float y = 0.4;
float z = 0.0;
glMatrixMode(GL_PROJECTION | GL_MODELVIEW);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT);
// Draw the Ellipse
glColor3d(1.0, 0.0, 1.0);
glBegin(GL_LINE_STRIP);
for (float i = 0; i <= eRad; i += 0.1)
{
glVertex2f(x*cos(i), y*sin(i));
}
glEnd();
//Draw the Sphere
glColor3d(1.0, 1.0, 0.0);
glPushMatrix();
glTranslatef(x*cos(iter), y*sin(iter), 0);
glutWireSphere(0.15, 30, 30);
glPopMatrix();
glFlush();
}
void animation(void)
{
iter = (iter < 6.5) ? iter+0.0001 : 0.0;
}
void Timer(int value) {
glutTimerFunc(33, Timer, 0);
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(600, 600);
glutInitWindowPosition(0, 0);
glutCreateWindow("Moving Sphere Test");
glutDisplayFunc(drawSphere);
glutIdleFunc(animation);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glViewport(0, 0, 600, 600);
Timer(0);
glutMainLoop();
}
I want to receive a small animation for four triangles. I wrote a several versions of the code, but none of these versions works. In result I have a blank black screen.
My code:
#define GLUT_DISABLE_ATEXIT_HACK
#define TIMERSECS 20
#include <windows.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/GL.H>
#include <stdlib.h>
float arc = 0.0f;
void draw_traingle(float x0, float y0, float x1, float y1, float x2, float y2) {
glColor4f(0.0f, 0.0f, 1.0f, 1.0f); //Blue
glVertex2f(x0, y0);
glVertex2f(x1, y1);
glVertex2f(x2, y2);
}
void draw(void) {
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT);
glRotatef(arc, 1.0f,0.0f,0.0f);
glBegin(GL_POLYGON);
float center_x = 300.0f;
float center_y = 300.0f;
float up_x = center_x;
float up_y = 250.0f;
float down_x = center_x;
float down_y = 350.0f;
float right_x = 350.0f;
float right_y = center_y;
float left_x = 250.0f;
float left_y = center_y;
glPushMatrix();
draw_traingle(up_x, up_y, right_x, right_y, center_x, center_y);
draw_traingle(right_x, right_y, down_x, down_y, center_x, center_y);
draw_traingle(down_x, down_y, left_x, left_y, center_x, center_y);
draw_traingle(left_x, left_y, up_x, up_y, center_x, center_y);
glPopMatrix();
glEnd();
glFlush();
glutSwapBuffers();
}
void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27:
exit(0);
}
}
void init(void) {
glClearColor(0.0, 0.0, 0.0, 0.0);
glViewport(0, 0, 600, 600);
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); //=1
gluOrtho2D(0.0, 600.0, 0.0, 600.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); //=1
}
void update(int value) {
arc += 2.0f;
if (arc > 360.f) {
arc -= 360;
}
glutPostRedisplay();
glutTimerFunc(TIMERSECS, update, 0);
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); //single buffer and RGBA
glutInitWindowSize(600, 600);
glutInitWindowPosition(100, 100);
glutCreateWindow("Window");
init();
glutDisplayFunc(draw);
glutTimerFunc(TIMERSECS, update, 0);
glutKeyboardFunc(handleKeypress);
glutMainLoop();
return 0;
}
I want to create an animation where my rectange builded from traingles will rotate for 2 degrees per some small time. I want to rotate it like clock works. i know that the problem is not in time (not to small) but in glRotatef - I don't know what parameters it should takes to give me a proper effect.
Thanks in advance! :)
#include <GL/glut.h>
#include <GL/gl.h>
#include <stdlib.h>
//#define TIMERSECS 200 prefer not to use preprocessor macros
//instead you can use:
static const int TIMERSECS = 200;
float arc = 0.0f;
void draw_traingle(float x0, float y0, float x1, float y1, float x2, float y2) {
glBegin(GL_POLYGON);
glColor4f(0.0f, 0.0f, 1.0f, 1.0f); //Blue
glVertex2f(x0, y0);
glVertex2f(x1, y1);
glVertex2f(x2, y2);
glEnd();
}
void draw(void) {
glClear(GL_COLOR_BUFFER_BIT);
glTranslatef(300, 300, 0);
glRotatef(arc, 0.0f,0.0f,1.0f);
glTranslatef(-300, -300, 0);
float center_x = 300.0f;
float center_y = 300.0f;
float up_x = center_x;
float up_y = 250.0f;
float down_x = center_x;
float down_y = 350.0f;
float right_x = 350.0f;
float right_y = center_y;
float left_x = 250.0f;
float left_y = center_y;
draw_traingle(up_x, up_y, right_x, right_y, center_x, center_y);
draw_traingle(right_x, right_y, down_x, down_y, center_x, center_y);
draw_traingle(down_x, down_y, left_x, left_y, center_x, center_y);
draw_traingle(left_x, left_y, up_x, up_y, center_x, center_y);
glutSwapBuffers();
}
void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27:
exit(0);
}
}
void init() {
glClearColor(0.0, 0.0, 0.0, 0.0);
glViewport(0, 0, 600, 600);
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); //=1
gluOrtho2D(0.0, 600.0, 0.0, 600.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); //=1
}
void update(int value) {
arc += 2.0f;
if (arc > 360.f) {
arc -= 360;
}
glutPostRedisplay();
glutTimerFunc(200, update, 1);
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); //single buffer and RGBA
glutInitWindowSize(600, 600);
glutCreateWindow("Window");
init();
glutDisplayFunc(draw);
glutTimerFunc(TIMERSECS, update, 1);
glutKeyboardFunc(handleKeypress);
glutMainLoop();
return 0;
}
Rotation is always relative to the coordinate system you are using. Transforimations are always applied in the reverse order. When we use rotatef function to rotate an object it's always relative to the center of the coordinate system. So first we need to translate it to to the center which is done by translatef(-300,-300,0). Now the object is on the center. Then we use rotatef to rotate the object to x,y or z axis. Then we translate the object again to the position that was before the transformation. Finally we write the functions in reverse order. You are good to go :)
While pressing the down key, I expect the teapot to be drawn away as farther, yet it remains the same size. Why?
Note: this is a homework thing, I'm not allowed to use glTranslate.
#include <stdlib.h>
#include <stdio.h>
#include <GL/glut.h>
#include <GL/gl.h>
void display(void);
class Camera {
public: float eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ;
float aimX, aimY, aimZ;
Camera () {
eyeX = 0.0f ;
eyeY = 0.0f;
eyeZ = 0.5f ;
centerX = 0.0f;
centerY = 0.0f;
centerZ = 0.0f;
upX = 0.0f;
upY = 1.0f;
upZ = 0.0f;
}
void move_camera(double speed) {
aimX = centerX - eyeX;
aimY = centerY - eyeY;
aimZ = centerZ - eyeZ;
eyeX += aimX * speed;
eyeY += aimY * speed;
eyeZ += aimZ * speed;
centerX += aimX *speed;
centerY += aimY *speed;
centerZ += aimZ *speed;
}
};
Camera camera;
void init(void){
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void specialKeys(int key, int x, int y){
if (key==GLUT_KEY_UP){
camera.move_camera(0.03f);
display();
}
if (key==GLUT_KEY_DOWN){
camera.move_camera(-0.03f);
display();
}
}
void reshape(int w, int h){
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (float)w/(float)h, 0.0f, 200.0f); // fov, aspect ratio, ncp, fcp
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//gluLookAt(camera.eyeX, camera.eyeY, camera.eyeZ, // eye
// camera.centerX, camera.centerY, camera.centerZ, // center
// camera.upX, camera.upY, camera.upZ // up
//
//);
}
void display(void){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(camera.eyeX, camera.eyeY, camera.eyeZ, // eye
camera.centerX, camera.centerY, camera.centerZ, // center
camera.upX, camera.upY, camera.upZ // up
);
//glTranslatef(0.0,0.0,1.0f);
glutWireTeapot(0.5f);
glutSwapBuffers();
glFlush();
}
int main (int argc, char *argv[]){
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
//glutCreateWindow(argv[0]);
glutInitWindowPosition(500,200);
glutInitWindowSize(800,600);
glutCreateWindow("fgh");
init();
glutDisplayFunc(display);
glutSpecialFunc(specialKeys);
glutIdleFunc(display);
glutMainLoop();
return 0;
}
Your projection matrix is damaged.
gluPerspective(45.0f, (float)w/(float)h, 0.0f, 200.0f); // fov, aspect ratio, ncp, fcp
The third argument is the distance of the near clipping plane. It cannot be equal to 0 as that would imply that you need an inifinite-precision depth buffer. Make it 0.1 or 0.01.
I was missing the call to glutReshapeFunc(reshape);. That's it.