How can I change the color of a cylinder in opengl? - c++

I want to draw one cylinder using OpenGL in Visual C++.
I want to make the color of the cylinder red, so I add the following code in the renderCylinder function, but it doesn't change.
glColor3f(1.0, 0.0, 0.0);
Could you help me to solve this problem?
The following codes are the full codes to make a cylinder for a test.
#include <GL/glew.h>
#include <GL/glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <fstream>
#include <string>
#include <cstring>
#include <cmath>
#include <iostream>
int selectedObject = 1;
bool drawThatAxis = 0;
bool lightEffect = 1;
float fovy = 60.0, aspect = 1.0, zNear = 1.0, zFar = 100.0;
float depth = 8;
float phi = 0, theta = 0;
float downX, downY;
bool leftButton = false, middleButton = false;
void renderCylinder(double x1, double y1, double z1, double x2, double y2, double z2, double radius, GLUquadricObj* quadric);
void displayCallback(void);
GLdouble width, height;
int wd;
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH);
glutInitWindowSize(800,600);
wd = glutCreateWindow("3D Molecules");
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
glClearColor(0.0, 0.0, 0.0, 0.0);
GLuint id;
id = glGenLists(1);
printf("hi %d\n", id);
GLUquadric* myQuad;
myQuad = gluNewQuadric();
glNewList(id, GL_COMPILE);
renderCylinder(0, 0, 0, 5, 5, 5, 1.5, myQuad);
glEndList();
glutDisplayFunc(displayCallback);
glutMainLoop();
return 0;
}
void renderCylinder(double x1, double y1, double z1, double x2, double y2, double z2, double radius, GLUquadricObj* quadric)
{
double vx = x2 - x1;
double vy = y2 - y1;
double vz = z2 - z1;
double ax, rx, ry, rz;
double len = sqrt(vx * vx + vy * vy + vz * vz);
glPushMatrix();
glColor3f(1.0, 0.0, 0.0);
glTranslatef(x1, y1, z1);
if (fabs(vz) < 0.0001)
{
glRotatef(90, 0, 1, 0);
ax = 57.2957795 * -atan(vy / vx);
if (vx < 0)
{
}
rx = 1;
ry = 0;
rz = 0;
}
else
{
ax = 57.2957795 * acos(vz / len);
if (vz < 0.0)
ax = -ax;
rx = -vy * vz;
ry = vx * vz;
rz = 0;
}
glRotatef(ax, rx, ry, rz);
gluQuadricOrientation(quadric, GLU_OUTSIDE);
gluCylinder(quadric, radius, radius, len, 10, 10);
glPopMatrix();
}
void displayCallback(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fovy, aspect, zNear, zFar);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 0, 40, 0, 0, 0, 0, 1, 0);
glTranslatef(0.0, 0.0, -depth);
glRotatef(-theta, 1.0, 0.0, 0.0);
glRotatef(phi, 0.0, 1.0, 0.0);
if (lightEffect) {
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
}
else
{
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);
}
switch (selectedObject)
{
case (1):
glCallList(1);
break;
default:
break;
}
glFlush();
}

You have lighting ON so glColor is ignored and material & light properties are used instead...
To remedy that add this to your code near place where you enable light:
glEnable(GL_COLOR_MATERIAL);

Related

why the glutPassiveMotionFunc does not have time to process all the calls to move the mouse [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I study OpenGL and make something like 3d shooter. If you move the mouse slowly, then everything works fine. If it is fast, then the rotation of the camera does not keep pace with the mouse.
Previously, this was all written in three classes. I decided to simplify in order to optimize. Maybe something else needs to be optimized?
main.cpp
#include "game_engine.h"
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(wnd_width, wnd_height);
glutInitWindowPosition(300, 100);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glutCreateWindow("OpenGL my");
glutDisplayFunc(display);
//glutIdleFunc(Idle);
glutKeyboardFunc(KeyPressed);
glutPassiveMotionFunc(MouseMove);
glutSetCursor(GLUT_CURSOR_CROSSHAIR);
TextureInit("t.jpg");
glutMainLoop();
return 0;
}
game_engine.h
#ifndef GAME_ENGINE_H
#define GAME_ENGINE_H
#include <GL/glut.h>
#include <stb_image.h>
#include <dirent.h>
const int wnd_width=1300;
const int wnd_height=900;
const GLdouble aspect = wnd_width/wnd_height;
extern unsigned int texture_floor;
extern unsigned int texture_wall;
extern float text_coords[];
extern int prev_mouse_x;
extern int prev_mouse_y;
extern int tmp;
void DrawFloor(float x, float y, float z, float width,
float length, float lift=0); // x, y, z - center start point);
void DrawWall(float x1, float z1, float x2, float z2);
void KeyPressed(unsigned char key, int x, int y);
void TextureInit(char* file);
void display();
void MouseMove(int x, int y);
void Idle();
#endif
game_engine.cpp
#define STB_IMAGE_IMPLEMENTATION
#include "game_engine.h"
#include "camera.h"
#include <cstdio>
float text_coords[] = {0,0, 1,0, 1,1, 0,1};
int prev_mouse_x=0;
int prev_mouse_y=0;
int tmp=0;
unsigned int texture_floor=0;
void TextureInit(char* file)
{
int width, height, cnt;
unsigned char* data = stbi_load(file, &width, &height, &cnt, 0);
if(data==nullptr) { printf("NO\n"); }
else { printf("%d\t%d\n",width, height); }
glGenTextures(1, &texture_floor);
glBindTexture(GL_TEXTURE_2D, texture_floor);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height,
0, GL_RGB, GL_UNSIGNED_BYTE, data);
glBindTexture(GL_TEXTURE_2D, 0);
stbi_image_free(data);
}
void display()
{
glClearColor(0.6, 0.8, 1, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90, aspect, 0.1, 5);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(pos.x, pos.y, pos.z,
view.x, view.y, view.z,
0, 0.2, 0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture_floor);
glBegin(GL_QUADS);
DrawFloor(0, 0, 0, 1.5, 2.5);
DrawFloor(0, 0, 2.5, 1.5, 5);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
DrawWall(-0.5, 0.1, -0.5, 2);
DrawWall(0.5, 0.1, 0.5, 1.7);
DrawWall(0.5, 1.7, 1.5, 1.7);
DrawWall(-0.5, 2, 0.9, 2.1);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glEnd();
glutSwapBuffers();
}
void DrawFloor(float x, float y, float z, float width, float length, float lift)
{
float r = width/2;
glVertex3d(x-r, y, z);
glVertex3d(x+r, y, z);
glVertex3d(x+r, y+lift, z+length);
glVertex3d(x-r, y+lift, z+length);
}
void DrawWall(float x1, float z1, float x2, float z2)
{
glTexCoord2f(0, 0);
glVertex3f(x1, 0, z1);
glTexCoord2f(1, 0);
glVertex3f(x2, 0, z2);
glTexCoord2f(1, 1);
glVertex3f(x2, 0.7, z2);
glTexCoord2f(0, 1);
glVertex3f(x1, 0.7, z1);
}
void KeyPressed(unsigned char key, int x, int y)
{
switch (key)
{
case 'w':
{ MoveForward(); break; }
case 's':
{ MoveBack(); break; }
case 'q':
exit(0);
}
if(key==32){
pos.y+=0.02;
view.y+=0.02;
}
glutPostRedisplay();
}
void MouseMove(int x, int y)
{
if(x>prev_mouse_x)
{
angle_rad +=0.03;
view.x = pos.x + (radius * cos(angle_rad));
view.z = pos.z + (radius * sin(angle_rad));
}
if(x<prev_mouse_x)
{
angle_rad -=0.03;
view.x = pos.x + (radius * cos(angle_rad));
view.z = pos.z + (radius * sin(angle_rad));
}
if(y>prev_mouse_y) { view.y-=0.0006; }
if(y<prev_mouse_y) { view.y+=0.0006; }
glutPostRedisplay();
prev_mouse_x = x;
prev_mouse_y = y;
}
void Idle()
{
}
camera.h
#ifndef CAMERA_H
#define CAMERA_H
#include <glm/glm.hpp>
using namespace glm;
const float pi = 3.14159265359;
extern float angle_deg; // in degrees
extern float angle_rad; // in radians
extern float radius;
extern vec3 pos;
extern vec3 view;
extern vec3 next_pnt;
vec3 operator*(vec3 v, int d);
void MoveForward();
void MoveBack();
void PrintPosition();
#endif
camera.cpp
#include "camera.h"
float angle_deg = 1;
float angle_rad = 1.57;
float radius = 0.02;
vec3 pos = vec3(0, 0.3, 0.0);
vec3 view = vec3(0.0, 0.3, 0.02);
vec3 next_pnt = vec3(0.0, 0.0, 0.0);
vec3 operator*(vec3 v, int d)
{
float x = v.x * d;
float y = v.y * d;
float z = v.z * d;
return vec3(x, y, z);
}
void MoveForward()
{
vec3 d = view - pos;
d = d * 2;
next_pnt = pos + d;
pos = view;
view = next_pnt;
}
void MoveBack()
{
vec3 d = view - pos;
next_pnt = pos - d;
view = pos;
pos = next_pnt;
}
You are not taking the mouse move distance into account. When the mouse moves faster, the distance between x and prev_mouse_x will be larger, but you always add 0.3. Scale the angle by the difference beteween x and prev_mouse_x and you should be fine.
int diffx = x - prev_mouse_x;
angle_rad += 0.03 * diffx;
view.x = pos.x + (radius * cos(angle_rad));
view.z = pos.z + (radius * sin(angle_rad));
...
Note, that even the OS layer only sends mouse events at a certain rate and you will never be able to get a separate event for each moved pixel.
Also note, that since you are not using angles but distances for the camera movement along the y axis, the y-rotation will not be constant anyway and feel strange.

how can I add collision to my object and around the screen in my program?

I am trying to create a car game with along with obstacles. I want to add collision so every time my object hits one of the obstacles, obstacle changes color and we know there has been a collision. I also want there to be a collision around my screen so that my object can not leave the view port?
--void 'draw car' is my movable object
#include "include\freeglut.h" // OpenGL toolkit - in the local shared folder
#include <cmath>
#include <iostream>
//set up some constants
#define X_CENTRE 0.0 /* centre point of square */
#define Y_CENTRE 0.0
#define LENGTH 5.0 /* lengths of sides of square */
//forward declaration - best in the header
void drawStar(GLfloat radius, GLfloat x, GLfloat y);
void drawSquare(GLfloat length, GLfloat x, GLfloat y);
void drawRect(GLfloat lengthX, GLfloat lengthY, GLfloat x, GLfloat y);
void drawCar(GLfloat length, GLfloat x, GLfloat y);
GLfloat red = 1.0, green = 1.0, blue = 1.0;
GLint xmove = -12.0, ymove = -12.5, zmove = 0.0;
/* reshape callback function
executed when window is moved or resized. This function should be used in Tutorial 1 */
void reshape(int width, int height)
{
GLfloat aspect = (GLfloat)width / (GLfloat)height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION); // To operate on the Projection matrix
glLoadIdentity();
// glOrtho(-10.0, 10.0, -10.0, 10.0, -1.0, 1.0); //sets the x,y,z plane from -1 to 1
if (width <= height) //if aspect is less or equal to 1
glOrtho(-10.0, 10.0, -10.0/aspect, 10.0/aspect, -1.0, 1.0);
else // aspect is greater than 1
glOrtho(-10.0 * aspect, 10.0* aspect, -10.0 , 10.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
}
/* display callback function
called whenever contents of window need to be re-displayed */
//this is the all important drawing method - all drawing code goes in here
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT); /* clear window */
/*glColor3f(1.0, 1.0, 1.0); /* white drawing objects */
glColor3f(0.0, 0.0, 1.0); /* blue drawing objects */
/* define object to be drawn as a square polygon */
glColor3f(0.3, -3.0, 4.0);
drawSquare(2, -3, 8);
glColor3f(0.3, -1.0, 2.0);
drawSquare(2, -3, 8);
glColor3f(1.0, 0.0, 0.0);
drawSquare(2, -5, -6);
glColor3f(0.0, 1.0, 0.0);
drawSquare(2, 0.0, 0.0);
glColor3f(2.0, 3.0, 1.1);
drawSquare(2, 6.0, 0.0);
glColor3f(0.3, -1.0, 2.0);
drawSquare(2, -6, 5);
glColor3f(0.7, -1.0, 2.0);
drawSquare(2, 5, -5);
glColor3f(0.0, 0.0, 1.0);
drawSquare(2, 5, 8);
glColor3f(0.75, 0.5, 0.25);
drawCar(1,0,0);
glFlush(); /* execute drawing commands in buffer */
}
void drawCar(GLfloat length, GLfloat x, GLfloat y) {
glPushMatrix();
glTranslatef(xmove, ymove, zmove);
//glBegin(GL_TRIANGLES);
////specify the vertices (points in 3D space) of the shape - note that these are 2D points
//glVertex2f(X_CENTRE - LENGTH / 3, Y_CENTRE - LENGTH / 3);
//glVertex2f(X_CENTRE - LENGTH / 3, Y_CENTRE + LENGTH / 3);
//glVertex2f(X_CENTRE + LENGTH / 3, Y_CENTRE + LENGTH / 3);
//glVertex2f(X_CENTRE + LENGTH / 3, Y_CENTRE - LENGTH / 3);
//glEnd();
glRectf(3, 4, 6, 2);
glPopMatrix();
glFlush();
}
void keyInput(unsigned char key, int x, int y)
{
switch (key)
{
case 'w':
ymove++;
if (ymove >= 10) ymove = 3.0;
break;
case 's':
ymove--;
// if (ymove <= -5) ymove = 0.0;
break;
case 'd':
xmove++;
// if (xmove >= 5) xmove = 0.0;
break;
case 'a':
xmove--;
// if (xmove <= -5) xmove = 0.0;
break;
}
glutPostRedisplay();
}
void drawSquare(GLfloat length, GLfloat x, GLfloat y)
{
//x1,y1 is the top left-hand corner coordinate
GLfloat x1, y1, x2, y2, x3, y3, x4, y4;
//glColor3f(0.1, 1.0, 0.2);
x1 = x - length / 2;
y1 = y + length / 2;
x2 = x + length / 2;
y2 = y + length / 2;
x3 = x + length / 2;
y3 = y - length / 2;
x4 = x - length / 2;
y4 = y - length / 2;
glBegin(GL_POLYGON);
glVertex2f(x1, y1);
glVertex2f(x2, y2);
glVertex2f(x3, y3);
glVertex2f(x4, y4);
glEnd();
glFlush();
}
void drawRect(GLfloat lengthX, GLfloat lengthY, GLfloat x, GLfloat y)
{
//x1,y1 is the top left-hand corner coordinate
GLfloat x1, y1, x2, y2, x3, y3, x4, y4;
//This example is for a rectangle
x1 = x - lengthX / 2;
y1 = y + lengthY / 2;
x2 = x + lengthX / 2;
y2 = y + lengthY / 2;
x3 = x + lengthX / 2;
y3 = y - lengthY / 2;
x4 = x - lengthX / 2;
y4 = y - lengthY / 2;
glBegin(GL_POLYGON);
glVertex2f(x1, y1);
glVertex2f(x2, y2);
glVertex2f(x3, y3);
glVertex2f(x4, y4);
glEnd();
glFlush();
}
//Draws a 5 pointed star using lines
void drawStar(GLfloat radius, GLfloat x, GLfloat y)
{
//x1,y1 is the top coordinate
//glColor3f(0.0, 1.0, 1.0);
GLfloat x1, y1, x2, y2, x3, y3, x4, y4, x5, y5;
x1 = x;
y1 = y + radius;
x2 = x + 0.90 * radius;
y2 = y + 0.40 * radius;
x3 = x + 0.65 * radius;
y3 = y - 0.55 * radius;
x4 = x - 0.65 * radius;
y4 = y - 0.55 * radius;
x5 = x - 0.90 * radius;
y5 = y + 0.40 * radius;
glLineWidth(1.0);
glBegin(GL_LINES);
glVertex2f(x1, y1);
glVertex2f(x3, y3);
glVertex2f(x1, y1);
glVertex2f(x4, y4);
glVertex2f(x2, y2);
glVertex2f(x4, y4);
glVertex2f(x2, y2);
glVertex2f(x5, y5);
glVertex2f(x3, y3);
glVertex2f(x5, y5);
glEnd();
glFlush();
}
/* graphics initialisation */
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0); //Setting up the background color
}
int main(int argc, char** argv)
{
/* window management code ... */
/* initialises GLUT and processes any command line arguments */
glutInit(&argc, argv);
/* use single-buffered window and RGBA colour model */
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
/* window width = 400 pixels, height = 400 pixels */
/* window width = 640 pixels, height = 480 pixels for a 4:3 ascpect ratio */
/* window width = 1024 pixels, height = 576 pixels for a 16:9 ascpect ratio */
glutInitWindowSize(750, 750);
/* window upper left corner at (100, 100) */
glutInitWindowPosition(100, 100);
/* creates an OpenGL window with command argument in its title bar */
glutCreateWindow("Example 1");
glutKeyboardFunc(keyInput);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
Keep track of your window size (750, 750), and your orthographic projection multiplier (10.0), then you should be able to tell when a certain world space coordinate is at the edge of the screen from these two.

Open GL Rotation

i'm trying to draw 100 arrows in a grid and trying to rotate each arrow according to the size of the input i read. But here when i try to rotate one arrow, all the arrows rotate at once with it. whats wrong with it ?
void drawArrow(void) {
float y1 = 2.0;
float y2 = 2.15;
float y3 = 2.4;
int count2 = 0;
for (float col = 0; col < 10; col++) {
y1 -= 0.5;
y2 -= 0.5;
y3 -= 0.5;
float x1 = -2.25;
float x2 = -2.20;
float x3 = -2.15;
float x4 = -2.35;
float x5 = -2.30;
for (float rows = 0; rows < 10; rows++) {
glPushMatrix();
glTranslatef(-0.35 + 0.5 - 0.1, 0.4 - 0.01 + 0.1, 0.0);
float m = (windx[count2] * windx[count2]) + (windy[count2] * windy[count2]);
float rotator = sqrt(m);
glRotatef(rotator-50, 0.0, 0.0, 1.0);
glBegin(GL_LINE_STRIP);//start drawing a line loop
glColor3f(1.0, 0.0, 0.0);
glVertex3f(x1, y1, 0.0f);
glVertex3f(x2, y2, 0.0f);
glVertex3f(x3, y2, 0.0f); // drawing a arrow
glVertex3f(x1, y3, 0.0f);
glVertex3f(x4, y2, 0.0f);
glVertex3f(x5, y2, 0.0f);
glVertex3f(x1, y1, 0.0f);
x1 += .5;
x2 += .5;
x3 += .5;
x4 += .5;
x5 += .5;
count2 ++;
glEnd();//end drawing of line loop
glPopMatrix();
}
}
int main(int argc, char **argv) {
glMatrixMode(GL_PROJECTION);
glutInit(&argc, argv); // Initialize GLUT
glutInitDisplayMode(GLUT_SINGLE); // Set up a basic display buffer (only single buffered for now)
glutInitWindowSize(1000, 800); // Set the width and height of the window
glutInitWindowPosition(100, 100); // Set the position of the window
glutCreateWindow("Weather Analysis"); // Set the title for the window
readDataFile(); //Read Data From File
glutKeyboardFunc(keyboard);
glutDisplayFunc(display); // Tell GLUT to use the method "display" for rendering
glutReshapeFunc(reshape); // Tell GLUT to use the method "reshape" for reshaping
glutMainLoop(); // Enter GLUT's main loop
void reshape(int width, int height) {
glViewport(0, 0, (GLsizei)width, (GLsizei)height); // Set our viewport to the size of our window
glMatrixMode(GL_PROJECTION); // Switch to the projection matrix so that we can manipulate how our scene is viewed
glLoadIdentity(); // Reset the projection matrix to the identity matrix so that we don't get any artifacts (cleaning up)
gluPerspective(60, (GLfloat)width / (GLfloat)height, 1.0, 100.0); // Set the Field of view angle (in degrees), the aspect ratio of our window, and the new and far planes
glMatrixMode(GL_MODELVIEW); // Switch back to the model view matrix, so that we can start drawing shapes correctly
}
void display(void) {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Clear the background of our window to red
glClear(GL_COLOR_BUFFER_BIT); //Clear the colour buffer (more buffers later on)
glLoadIdentity(); // Load the Identity Matrix to reset our drawing locations
glTranslatef(0.0f, 0.5f, -6.0f);
renderPrimitive(); // Render the primitive
drawArrow();
glFlush(); // Flush
}
and ALSO i dont know what to enter in the GLtranslatef method. Im really a beginner, sorry.
Try to draw your arrow in one rutine lets call it DrawArrow I suggest it size must be between [-1.0f; 1.0f] than place it at the proper position using affine transform first of all translation secondly rotation.
void DrawArrow(void)
{
float x1 = 0;
float x2 = -0.05;
float x3 = -0.1;
float x4 = 0.1;
float x5 = 0.05;
float y1 = -0.15;
float y2 = 0;
float y3 = 0.15;
glBegin(GL_LINE_STRIP);//start drawing a line loop
glColor3f(1.0, 0.0, 0.0);
glVertex3f(x1, y1, 0.0f);
glVertex3f(x2, y2, 0.0f);
glVertex3f(x3, y2, 0.0f); // drawing a arrow
glVertex3f(x1, y3, 0.0f);
glVertex3f(x4, y2, 0.0f);
glVertex3f(x5, y2, 0.0f);
glVertex3f(x1, y1, 0.0f);
glEnd();//
}
Than your array drawing function like this (you may correct inacurrances):
void drawArrows(void) {
float y1 = 2.0;
int count2 = 0;
for (float col = 0; col < 10; col++) {
y1 -= 0.5;
float x1 = -2.25;
for (float rows = 0; rows < 10; rows++) {
glPushMatrix();
glTranslatef(x1, y1, 0.0);
float m = (windx[count2] * windx[count2]) + (windy[count2] * windy[count2]);
float rotator = sqrt(m);
glRotatef(rotator-50, 0.0, 0.0, 1.0);
DrawArrow();
x1 += .5;
count2 ++;
glPopMatrix();
}
}
}
I have made some tests the result will be like this (with constant rotator).

OpenGL with GLUT - black screen

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 :)

Drawing Circle with OpenGL

I'm trying to draw simple circle with C++/OpenGl
my code is:
#include <GL/glut.h>
#include <math.h>
void Draw() {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_QUADS);
glColor3f (0.0, 0.0, 0.0);
glVertex3f (0.1, 0.1, 0.0);
glVertex3f (0.9, 0.1, 0.0);
glVertex3f (0.9, 0.9, 0.0);
glVertex3f (0.1, 0.9, 0.0);
glEnd();
glFlush();
}
void DrawCircle(float cx, float cy, float r, int num_segments)
{
glBegin(GL_LINE_LOOP);
for(int ii = 0; ii < num_segments; ii++)
{
float theta = 2.0f * 3.1415926f * float(ii) / float(num_segments);//get the current angle
float x = r * cosf(theta);//calculate the x component
float y = r * sinf(theta);//calculate the y component
glVertex2f(x + cx, y + cy);//output vertex
}
glEnd();
}
void Initialize() {
glClearColor(1.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}
int main(int iArgc, char** cppArgv) {
glutInit(&iArgc, cppArgv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(950, 500);
glutInitWindowPosition(200, 200);
glutCreateWindow("Universum");
Initialize();
glutDisplayFunc(Draw);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
DrawCircle(0.5, 0.5, 0.2, 5);
glutMainLoop();
return 0;
}
I'm beginner with OpenGL and now i'm starting to learn,
Can someone please explain me why i don't get the circle (i only see the black box),
Thanks!
It looks like immediately after you draw the circle, you go into the main glut loop, where you've set the Draw() function to draw every time through the loop. So it's probably drawing the circle, then erasing it immediately and drawing the square. You should probably either make DrawCircle() your glutDisplayFunc(), or call DrawCircle() from Draw().
#include <Windows.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define window_width 1080
#define window_height 720
void drawFilledSun(){
//static float angle;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0, 0, -10);
int i, x, y;
double radius = 0.30;
//glColor3ub(253, 184, 19);
glColor3ub(255, 0, 0);
double twicePi = 2.0 * 3.142;
x = 0, y = 0;
glBegin(GL_TRIANGLE_FAN); //BEGIN CIRCLE
glVertex2f(x, y); // center of circle
for (i = 0; i <= 20; i++) {
glVertex2f (
(x + (radius * cos(i * twicePi / 20))), (y + (radius * sin(i * twicePi / 20)))
);
}
glEnd(); //END
}
void DrawCircle(float cx, float cy, float r, int num_segments) {
glBegin(GL_LINE_LOOP);
for (int ii = 0; ii < num_segments; ii++) {
float theta = 2.0f * 3.1415926f * float(ii) / float(num_segments);//get the current angle
float x = r * cosf(theta);//calculate the x component
float y = r * sinf(theta);//calculate the y component
glVertex2f(x + cx, y + cy);//output vertex
}
glEnd();
}
void main_loop_function() {
int c;
drawFilledSun();
DrawCircle(0, 0, 0.7, 100);
glutSwapBuffers();
c = getchar();
}
void GL_Setup(int width, int height) {
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glEnable(GL_DEPTH_TEST);
gluPerspective(45, (float)width / height, .1, 100);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitWindowSize(window_width, window_height);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("GLUT Example!!!");
glutIdleFunc(main_loop_function);
GL_Setup(window_width, window_height);
glutMainLoop();
}
This is what I did. I hope this helps. Two types of circle are here. Filled and unfilled.
There is another way to draw a circle - draw it in fragment shader.
Create a quad:
float right = 0.5;
float bottom = -0.5;
float left = -0.5;
float top = 0.5;
float quad[20] = {
//x, y, z, lx, ly
right, bottom, 0, 1.0, -1.0,
right, top, 0, 1.0, 1.0,
left, top, 0, -1.0, 1.0,
left, bottom, 0, -1.0, -1.0,
};
Bind VBO:
unsigned int glBuffer;
glGenBuffers(1, &glBuffer);
glBindBuffer(GL_ARRAY_BUFFER, glBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*20, quad, GL_STATIC_DRAW);
and draw:
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
glEnableVertexAttribArray(ATTRIB_VERTEX);
glEnableVertexAttribArray(ATTRIB_VALUE);
glVertexAttribPointer(ATTRIB_VERTEX , 3, GL_FLOAT, GL_FALSE, 20, 0);
glVertexAttribPointer(ATTRIB_VALUE , 2, GL_FLOAT, GL_FALSE, 20, BUFFER_OFFSET(12));
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
Vertex shader
attribute vec2 value;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
varying vec2 val;
void main() {
val = value;
gl_Position = projectionMatrix*viewMatrix*vertex;
}
Fragment shader
varying vec2 val;
void main() {
float R = 1.0;
float R2 = 0.5;
float dist = sqrt(dot(val,val));
if (dist >= R || dist <= R2) {
discard;
}
float sm = smoothstep(R,R-0.01,dist);
float sm2 = smoothstep(R2,R2+0.01,dist);
float alpha = sm*sm2;
gl_FragColor = vec4(0.0, 0.0, 1.0, alpha);
}
Don't forget to enable alpha blending:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
UPDATE: Read more
We will find the value of X and Y from this image. We know, sinθ=vertical/hypotenuse and cosθ=base/hypotenuse from the image we can say X=base and Y=vertical. Now we can write X=hypotenuse * cosθ and Y=hypotenuse * sinθ.
Now look at this code
void display(){
float x,y;
glColor3f(1, 1, 0);
for(double i =0; i <= 360;){
glBegin(GL_TRIANGLES);
x=5*cos(i);
y=5*sin(i);
glVertex2d(x, y);
i=i+.5;
x=5*cos(i);
y=5*sin(i);
glVertex2d(x, y);
glVertex2d(0, 0);
glEnd();
i=i+.5;
}
glEnd();
glutSwapBuffers();
}
glBegin(GL_POLYGON); // Middle circle
double radius = 0.2;
double ori_x = 0.0; // the origin or center of circle
double ori_y = 0.0;
for (int i = 0; i <= 300; i++) {
double angle = 2 * PI * i / 300;
double x = cos(angle) * radius;
double y = sin(angle) * radius;
glVertex2d(ori_x + x, ori_y + y);
}
glEnd();
Here is a code to draw a fill elipse, you can use the same method but replacing de xcenter and y center with radius
void drawFilledelipse(GLfloat x, GLfloat y, GLfloat xcenter,GLfloat ycenter) {
int i;
int triangleAmount = 20; //# of triangles used to draw circle
//GLfloat radius = 0.8f; //radius
GLfloat twicePi = 2.0f * PI;
glBegin(GL_TRIANGLE_FAN);
glVertex2f(x, y); // center of circle
for (i = 0; i <= triangleAmount; i++) {
glVertex2f(
x + ((xcenter+1)* cos(i * twicePi / triangleAmount)),
y + ((ycenter-1)* sin(i * twicePi / triangleAmount))
);
}
glEnd();
}
I have done it using the following code,
glBegin(GL.GL_LINE_LOOP);
for(int i =0; i <= 300; i++){
double angle = 2 * Math.PI * i / 300;
double x = Math.cos(angle);
double y = Math.sin(angle);
gl.glVertex2d(x,y);
}
glEnd();
glBegin(GL_POLYGON);
double x = 2;
double y = 2;
for (int i = 0; i <= 360; i++) {
glVertex2d(x * sin(i), y * cos(i));
}
glEnd();