Drawing 3d and 2d in the same window not working correctly openGl - c++

I am trying to draw some 3d ( a sun) and 2d (ground, cloud, ...) shapes in the same window, it actually worked! But the problem is when I when I run the program, it does not show smooth screen, it shows one shape then the other (while the first disappears), then the next shape and so on...
here is the code, than you.
#include<windows.h>
#include<stdio.h>
#include<GL/glut.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#define CIRCLE_RADIUS 0.15f
# define PI 3.14159265358979323846
int eggs_caught = 0, missed_eggs = 0, level_count = 1, points = 0;
int egg_xc, egg_yc;
// for coordinates of egg
int basket_x, basket_y;
// for coordinates of basket
int a = 600, b = 650; // for default size of the screen
int s = 0;
// for menu option
int dropped_eggs = 0;
int speed_1 = 1, speed_2 = 1.5, speed_3 = 2, speed_4 = 2.5;
int w = 48, h = 48, t = 10, e = 9, g = 12;
void myinit();
void start_screen(int, int);
void cloud1();
void egg();
void basket(int, int);
void duck(int, int);
void print_score();
void egg_start();
void color();
void score();
void display(void);
void basket_set(int, int);
void myReshape(int, int);
void keys(unsigned char, int, int);
void menu(int);
void myinit()
{
}
void sun()
{
GLfloat black[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat yellow[] = { 1.0, 1.0, 0.0, 1.0 };
GLfloat direction[] = { 1.0, 1.0, 1.0, 0.0 };
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, yellow);
glMaterialfv(GL_FRONT, GL_SPECULAR, yellow);
glMaterialf(GL_FRONT, GL_SHININESS, 30);
glLightfv(GL_LIGHT0, GL_AMBIENT, black);
glLightfv(GL_LIGHT0, GL_DIFFUSE, yellow);
glLightfv(GL_LIGHT0, GL_SPECULAR, yellow);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glPushMatrix();
glTranslatef(0, 0.0, 0);
glutSolidSphere(0.5, 30, 30);
glPopMatrix();
glPopMatrix();
glFlush();
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);
glDisable(GL_DEPTH_TEST);
}
void cloud1()
{
float theta;
GLfloat angle;
glLineWidth(1.5);
glColor3f(1, 1, 1);
glBegin(GL_POLYGON);
for (int i = 0; i < 360; i++)
{
theta = i * PI * i / 180;
glVertex2f(100 + 50 * cos(theta) / 2, 590 + 50 * sin(theta) / 2);
}
glEnd();
glLineWidth(1.5);
glColor3f(1, 1, 1);
glBegin(GL_POLYGON);
for (int i = 0; i < 360; i++)
{
theta = i * PI * i / 180;
glVertex2f(130 + 50 * cos(theta) / 2, 580 + 50 * sin(theta) / 2);
}
glEnd();
glLineWidth(1.5);
glColor3f(1, 1, 1);
glBegin(GL_POLYGON);
for (int i = 0; i < 360; i++)
{
theta = i * PI * i / 180;
glVertex2f(140 + 50 * cos(theta) / 2, 600 + 50 * sin(theta) / 2);
}
glEnd();
glLineWidth(1.5);
glColor3f(1, 1, 1);
glBegin(GL_POLYGON);
for (int i = 0; i < 360; i++)
{
theta = i * PI * i / 180;
glVertex2f(170 + 50 * cos(theta) / 2, 590 + 50 * sin(theta) / 2);
}
glEnd();
glFlush();
}
void backk(int i, int j)
{
glColor3f(0, .5, 1);
glBegin(GL_QUADS);
glVertex2f(0.0 + i, 0.0 + j);
glVertex2f(600.0 + i, 0.0 + j);
glVertex2f(600.0 + i, -500 + j);
glVertex2f(0.0 + i, -500 + j);
glEnd();
glFlush();
}
void ground(int i, int j)
{
glBegin(GL_QUADS);
glColor3f(0, 1.0, 0);
glVertex2f(0.0 + i, 0.0 + j);
glVertex2f(600.0 + i, 0.0 + j);
glVertex2f(600.0 + i, -j);
glVertex2f(0.0 + i, -j);
glEnd();
}
void duck(int i, int j)
{
int h;
glColor3f(1.0, 1.0, 0.0);
glBegin(GL_POLYGON);
glVertex2f(45 + i, 45 + j);
glVertex2f(70 + i, 20 + j);
glVertex2f(95 + i, 20 + j);
glVertex2f(120 + i, 45 + j);
glVertex2f(95 + i, 70 + j);
glVertex2f(70 + i, 70 + j);
glVertex2f(95 + i, 95 + j);
glVertex2f(82.5 + i, 107.5 + j);
glVertex2f(32.5 + i, 57.5 + j);
glEnd();
glFlush();
for (h = 0; h < 13; h += 4)
{
glBegin(GL_LINES);
glColor3f(0.7, 0.4, 0);
glVertex2f(57.5 + h + i, 52.5 + h + j);
glVertex2f(100 + h + i, 30 + h + j);
glEnd();
glFlush();
}
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_POLYGON);
glVertex2f(82.5 + i, 107.5 + j);
glVertex2f(65 + i, 107.5 + j);
glVertex2f(50 + i, 95 + j);
glVertex2f(70 + i, 95 + j);
glEnd();
glFlush();
glColor3f(0.0, 0.0, 0.0);
glPointSize(5);
glBegin(GL_POINTS);
glVertex2f(76 + i, 101 + j);
glEnd();
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_LINE_LOOP);
glVertex2f(72.5 + i, 107.5 + j);
glVertex2f(67.5 + i, 112.5 + j);
glVertex2f(72.5 + i, 110 + j);
glVertex2f(77.5 + i, 112.5 + j);
glEnd();
glFlush();
}
void display(void)
{
GLfloat aspect = GLfloat(a) / GLfloat(b);
glOrtho(-2.5 * aspect, 2.5 * aspect, -2.5, 2.5, -10.0, 10.0);
glClear(GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-2.5 * aspect, 2.5 * aspect, -2.5, 2.5, -10.0, 10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
sun();
glClear(GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, (GLdouble)a, 0.0, (GLdouble)b, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
cloud1();
ground(0, 650);
backk(0, 650);
duck(40, 375);
duck(180, 375);
duck(320, 375);
}
void myReshape(int w, int h)
{
}
void keys(unsigned char key, int x, int y)
{
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(a, b);
glutCreateWindow("EGG GAME");
myinit();
glutInitWindowPosition(100, 100);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutDisplayFunc(display);
glutKeyboardFunc(keys);
glutIdleFunc(display);
glutReshapeFunc(myReshape);
glutMainLoop();
}

not using GLUT but this is What I see at first look.
glClear(GL_DEPTH_BUFFER_BIT);
why not clear also color? try glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
no glutSwapBuffers();
without this call at the end of display function your render is not updated when it needs to.
no glFlush/glFinish before swapping buffers
its safe to have them at the end. I see you got them in some of the rendering calls not all though.
using int operands for glVertex2f
Why not use glVertex2i instead when all of your coordinates are integers anyway. The int to float conversions slowing things down ...
Take a look at some simple GLUT example I just found:
cube.c
In there the Display look like this:
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawBox(); // here yoru rendering stuff instead
glFlush(); // I usually add this before swapping buffers
glutSwapBuffers();
}
so change your code accordingly...
On top of all this I would maybe try to use Blending for the clouds ...

Related

Animate bouncing box using?

I need to make an animation where the box starts from (-15, 0) then going up to (-8, 15) and when it reach that, then it came down. and so on, just like a DVD screen saver, but i can't seem to find the formula for it to work.
Here's the code:
#include<windows.h>
#include<GL/glu.h>
#include<GL/glut.h>
#ifdef APPLE
#include<GLUT/glut.h>
#else
#include<GL/glut.h>
#endif
#include<stdio.h>
#include<stdlib.h>
#include <GL/freeglut.h>
//Variable menampung sudut awal
float xpos = -15.0;
float deltax = 0.5;
float ypos = 0.0;
bool balik = true;
bool turun = true;
//Variable mengatur perubahan sudut
void myInit(void) {
glClearColor(0.0, 0.0, 0.0, 1.0);
glColor3f(1.0, 1.0, 1.0);
glPointSize(2.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-15.0f, 15.0f, -15.0f, 15.0f);
}
void myDisplay(void) {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINES);
glColor3f(1.0, 1.0, 1.0);
glVertex2f(-15.0, 0.0);
glVertex2f(15.0, 0.0);
glEnd();
glBegin(GL_LINES);
glColor3f(1.0, 1.0, 1.0);
glVertex2f(-8.0, 15.0);
glVertex2f(-8.0, -15.0);
glEnd();
glBegin(GL_LINES);
glColor3f(1.0, 1.0, 1.0);
glVertex2f(8.0, 15.0);
glVertex2f(8.0, -15.0);
glEnd();
glBegin(GL_LINES);
glColor3f(1.0, 1.0, 1.0);
glVertex2f(0.0, 15.0);
glVertex2f(0.0, -15.0);
glEnd();
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_POLYGON);
glVertex2f(-0.2 + xpos, 0.2 + ypos);
glVertex2f(-0.2 + xpos, -0.2 + ypos);
glVertex2f(0.2 + xpos, -0.2 + ypos);
glVertex2f(0.2 + xpos, 0.2 + ypos);
glEnd();
glutSwapBuffers();
}
void Timer(int) {
glutPostRedisplay();
glutTimerFunc(100, Timer, 0);
if (ypos < 15 && xpos <-8 && turun == true){
xpos = xpos + deltax;
ypos = (2.143*xpos) + 32.143;
}
else {turun = false;};
if (ypos > -15 && xpos <8 && turun == false){
xpos = xpos + deltax;
ypos = -1,875*xpos + ;
}
else turun = true;
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("Animasi");
glutDisplayFunc(myDisplay);
myInit();
glutTimerFunc(0, Timer, 0);
//Perulangan
glutMainLoop();
return 0;
}
If you want the box to bounce you can just reverse the x or y velocity depending on which axis you hit. If you want the box to bounce with Gravity you will use vector parametric equations like so:
y = -16t^2 + vsin(x) + s.y and x = vcos(x) + s.x where t is time v is magnitude(velocity) and s is the starting position of the box which will be reset on every collision with the sides. Keep the magnitude the same to infinitely bounce. If the equation is confusing look up vector pre-calculus online.

Separating Triangle Strips in Circular Annulus

Given the problem description:
More specifically, the problem involves specifically the decorated annulus. The problem I am having is to separate the lightly shaded triangle from the dark shaded triangles.
I have produced code (based on a previous example) that produces a circular annulus. However, the triangles are together rather than separate, and produce the same color.
Here is the code that I have produced so far:
///////////////////////////////////////////////////////////////////////////////////////////
// circularAnnuluses.cpp
//
// This program draws three identical-looking circular annuluses in three different ways -
// see comments below.
//
// Interaction:
// Press the space bar to toggle between wirefrime and filled for the lower annulus.
//
// Sumanta Guha.
///////////////////////////////////////////////////////////////////////////////////////////
#include <cstdlib>
#include <cmath>
#include <iostream>
#ifdef __APPLE__
# include <GL/glew.h>
# include <GL/freeglut.h>
# include <OpenGL/glext.h>
#else
# include <GL/glew.h>
# include <GL/freeglut.h>
//# include <GL/glext.h>
#pragma comment(lib, "glew32.lib")
#endif
#define PI 3.14159265
#define N 6.0 // Number of vertices on the boundary of the disc.
using namespace std;
// Globals.
static int isWire = 0; // Is wireframe?
// Drawing routine.
void drawScene(void)
{
float angle;
int i;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the buffers including
// the depth buffer.
glPolygonMode(GL_FRONT, GL_FILL);
// Lower circular annulus: with a true hole.
if (isWire) glPolygonMode(GL_FRONT, GL_LINE); else glPolygonMode(GL_FRONT, GL_FILL);
glBegin(GL_TRIANGLE_STRIP);
for (i = 0; i <= N; ++i)
{
angle = 2 * PI * i / N;
glColor3f(1.0, 0.0, 0.0);
glVertex3f(50 + cos(angle) * 10.0, 50 + sin(angle) * 10.0, 0.0);
glColor3f(0, 1, 0);
glVertex3f(50 + cos(angle) * 20.0, 50 + sin(angle) * 20.0, 0.0);
}
glEnd();
// Write labels.
glColor3f(0.0, 0.0, 0.0);
glFlush();
}
// Initialization routine.
void setup(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0);
}
// OpenGL window reshape routine.
void resize(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 100.0, 0.0, 100.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
// Keyboard input processing routine.
void keyInput(unsigned char key, int x, int y)
{
switch (key)
{
case ' ':
if (isWire == 0) isWire = 1;
else isWire = 0;
glutPostRedisplay();
break;
case 27:
exit(0);
break;
default:
break;
}
}
// Routine to output interaction instructions to the C++ window.
void printInteraction(void)
{
cout << "Interaction:" << endl;
cout << "Press the space bar to toggle between wirefrime and filled for the lower annulus." << endl;
}
// Main routine.
int main(int argc, char** argv)
{
printInteraction();
glutInit(&argc, argv);
glutInitContextVersion(4, 3);
glutInitContextProfile(GLUT_COMPATIBILITY_PROFILE);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("DecoratedAnnulus.cpp");
glutDisplayFunc(drawScene);
glutReshapeFunc(resize);
glutKeyboardFunc(keyInput);
glewExperimental = GL_TRUE;
glewInit();
setup();
glutMainLoop();
}
The section of code where the problem lies is in the 'drawscene' function. I believe there should be two different for loops to separate the triangles from one another, but whenever I try to split the for loop it produces a monster of a shape.
I'm not exactly sure where to begin to complete this last problem.
As mentioned in the other answer, a possibility is to switch to flat shading mode by glShadeModel.
But note, you've also to offset the vertex coordinates of the outer circle:
glShadeModel( GL_FLAT );
glBegin(GL_TRIANGLE_STRIP);
for (i = 0; i <= N; ++i)
{
angle1 = 2 * PI * i / N;
angle2 = 2 * PI * (i+0.5) / N;
glColor3f(1.0, 0.0, 0.0);
glVertex3f(50 + cos(angle1) * 10.0, 50 + sin(angle1) * 10.0, 0.0);
glColor3f(0, 1, 0);
glVertex3f(50 + cos(angle2) * 20.0, 50 + sin(angle2) * 20.0, 0.0);
}
glEnd();
The other possibility is to draw the inner and outer triangles with the primitive type GL_TRIANGLES in 2 separate loops:
glShadeModel( GL_SMOOTH );
glBegin(GL_TRIANGLES);
glColor3f(1.0, 0.0, 0.0);
for (i = 0; i <= N; ++i)
{
angle1 = 2 * PI * i / N;
angle2 = 2 * PI * (i+0.5) / N;
angle3 = 2 * PI * (i+1) / N;
glVertex3f(50 + cos(angle1) * 10.0, 50 + sin(angle1) * 10.0, 0.0);
glVertex3f(50 + cos(angle2) * 20.0, 50 + sin(angle2) * 20.0, 0.0);
glVertex3f(50 + cos(angle3) * 10.0, 50 + sin(angle3) * 10.0, 0.0);
}
glEnd();
glBegin(GL_TRIANGLES);
glColor3f(0, 1, 0);
for (i = 0; i <= N; ++i)
{
angle1 = 2 * PI * (i-0.5) / N;
angle2 = 2 * PI * i / N;
angle3 = 2 * PI * (i+0.5) / N;
glVertex3f(50 + cos(angle1) * 20.0, 50 + sin(angle1) * 20.0, 0.0);
glVertex3f(50 + cos(angle2) * 10.0, 50 + sin(angle2) * 10.0, 0.0);
glVertex3f(50 + cos(angle3) * 20.0, 50 + sin(angle3) * 20.0, 0.0);
}
glEnd();
Both methods generate the following image:
If you want a more "circular" look, then you've to tessellate the segments along the inner or outer circle. Use the primitive type GL_TRIANGLE_FAN (see Triangle primitives) to draw a single segment:
int N2 = 10;
glShadeModel( GL_SMOOTH );
# draw the red segments
glColor3f(1.0, 0.0, 0.0);
for (int i = 0; i <= N; ++i)
{
float angle1 = 2 * PI * i / N;
float angle2 = 2 * PI * (i+0.5) / N;
float angle3 = 2 * PI * (i+1) / N;
# draw a single red segment
glBegin(GL_TRIANGLE_FAN);
glVertex3f(50 + cos(angle2) * 20.0, 50 + sin(angle2) * 20.0, 0.0);
for (int j = 0; j <= N2; ++j)
{
float a = angle1 + (angle3 - angle1) * (float)j / (float)N2;
glVertex3f(50 + cos(a) * 10.0, 50 + sin(a) * 10.0, 0.0);
}
glEnd();
}
# draw the green sgements
glColor3f(0, 1, 0);
for (int i = 0; i <= N; ++i)
{
float angle1 = 2 * PI * (i-0.5) / N;
float angle2 = 2 * PI * i / N;
float angle3 = 2 * PI * (i+0.5) / N;
# draw a single green segment
glBegin(GL_TRIANGLE_FAN);
glVertex3f(50 + cos(angle2) * 10.0, 50 + sin(angle2) * 10.0, 0.0);
for (int j = 0; j <= N2; ++j)
{
float a = angle1 + (angle3 - angle1) * (float)j / (float)N2;
glVertex3f(50 + cos(a) * 20.0, 50 + sin(a) * 20.0, 0.0);
}
glEnd();
}

OpenGL depth test works but not as expected

Using Windows7, VS2013, Qt 5.6, OpenGL 4.4
The code in question is as follows
void TestClass::paintGL()
{
/*
* Clear the screen
*/
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glClearColor(0, 0.25, 1, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glClearDepth(0.0);
glDepthFunc(GL_LEQUAL);
GLenum error = glGetError();
if (error != GL_NO_ERROR)
{
int i = 0;
i++;
}
/*
*/
//*************************************************
//double xx = mRotation.x() * mRotation.x();
//double xy = mRotation.x() * mRotation.y();
//double xz = mRotation.x() * mRotation.z();
//double xw = mRotation.x() * mRotation.scalar();
//double yy = mRotation.y() * mRotation.y();
//double yz = mRotation.y() * mRotation.z();
//double yw = mRotation.y() * mRotation.scalar();
//double zz = mRotation.z() * mRotation.z();
//double zw = mRotation.z() * mRotation.scalar();
//double m00 = 1 - 2 * (yy + zz);
//double m01 = 2 * (xy - zw);
//double m02 = 2 * (xz + yw);
//double m03 = 0;
//double m10 = 2 * (xy + zw);
//double m11 = 1 - 2 * (xx + zz);
//double m12 = 2 * (yz - xw);
//double m13 = 0;
//double m20 = 2 * (xz - yw);
//double m21 = 2 * (yz + xw);
//double m22 = 1 - 2 * (xx + yy);
//double m23 = 0;
//double m30 = 0;
//double m31 = 0;
//double m32 = -30;
//double m33 = 1;
//double blarg[] = {m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33};
//glLoadMatrixd(&blarg[0]);
//*************************************************
QMatrix4x4 yaw;
yaw.rotate(mYPR.x(), QVector3D(0, -1, 0));
QMatrix4x4 pitch;
pitch.rotate(mYPR.y(), QVector3D(1, 0, 0));
QMatrix4x4 roll;
roll.rotate(mYPR.z(), QVector3D(0, 0, -1));
QMatrix4x4 translate;
translate.translate(0, 0, -30);
//QMatrix4x4 vnToOpenGL(0, 0, -1, 0,
// 1, 0, 0, 0,
// 0, -1, 0, 0,
// 0, 0, 0, 1);
QMatrix4x4 vnToOpenGL(1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
QMatrix4x4 openGLMatrix = vnToOpenGL * translate * yaw * pitch * roll * vnToOpenGL.transposed();
glLoadMatrixf(reinterpret_cast<const float*>(openGLMatrix.constData()));
int depth;
glGetIntegerv(GL_DEPTH_BITS, &depth);
QString ytext(QString("yaw : ") + QString::number(mYPR.x()));
QString ptext(QString("pitch : ") + QString::number(mYPR.y()));
QString rtext(QString("roll : ") + QString::number(mYPR.z()));
QString dtext(QString("depth : ") + QString::number(depth));
QPainter painter(this);
painter.drawText(10, 10, ytext);
painter.drawText(10, 25, ptext);
painter.drawText(10, 40, rtext);
painter.drawText(10, 55, dtext);
painter.end();
//*************************************************
//double scalar = std::acos(mRotation.scalar()) * 2;
//double X = std::asin(mRotation.x()) * 2;
//double Y = std::asin(mRotation.y()) * 2;
//double Z = std::asin(mRotation.z()) * 2;
//glRotated(scalar * radToDeg, X * radToDeg, Y * radToDeg, Z * radToDeg);
glScaled(mScale, mScale, mScale);
QVector3D orthogonalPoint;
QVector3D orthogonalVector;
QVector3D currentNormal;
for (size_t index = 0; index < mSphere->getTriangles().size(); index++)
{
// BEGIN CODE IN QUESTION
glEnable(GL_DEPTH_TEST);
//glDepthMask(GL_TRUE);
//glClearDepth(0.0);
//glDepthFunc(GL_LEQUAL);
// END CODE IN QUESTION
currentNormal = mSphere->getTriangles()[index].getNormal();
orthogonalVector = QVector3D::crossProduct(QVector3D(currentNormal.x(), currentNormal.y(), currentNormal.z()),
QVector3D(currentNormal.x(), currentNormal.y(), 0));
orthogonalVector.normalize();
glLineWidth(1.0);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINES);
glVertex3f(0, 0, 0);
glVertex3f(currentNormal.x(), currentNormal.y(), currentNormal.z());
glEnd();
glLineWidth(3.0);
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_LINE_STRIP);
glVertex3f(0, 0, 0);
glVertex3f(0, 0, -1);
glEnd();
glLineWidth(3.0);
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_LINE_STRIP);
glVertex3f(0, 0, 0);
glVertex3f(1, 0, 0);
glEnd();
glLineWidth(3.0);
glColor3f(0.0, 1.0, 1.0);
glBegin(GL_LINE_STRIP);
glVertex3f(0, 0, 0);
glVertex3f(0, 1, 0);
glEnd();
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_TRIANGLE_FAN);
glVertex3d(currentNormal.x(), currentNormal.y(), currentNormal.z());
for (size_t fanIndex = 0; fanIndex < 9; ++fanIndex)
{
double degrees = static_cast<double>(fanIndex) * (360.0 / mTargetTesselations);
QMatrix4x4 matrix;
matrix.rotate(degrees, currentNormal.x(), currentNormal.y(), currentNormal.z());
orthogonalPoint = (orthogonalVector * matrix) / 20.0;
glVertex3d(currentNormal.x() + orthogonalPoint.x(),
currentNormal.y() + orthogonalPoint.y(),
currentNormal.z() + orthogonalPoint.z());
}
glEnd();
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_TRIANGLE_FAN);
glVertex3d(currentNormal.x(), currentNormal.y(), currentNormal.z());
for (size_t fanIndex = 0; fanIndex < 9; ++fanIndex)
{
double degrees = 360.0 - (static_cast<double>(fanIndex) * (360.0 / mTargetTesselations));
QMatrix4x4 matrix;
matrix.rotate(degrees, currentNormal.x(), currentNormal.y(), currentNormal.z());
orthogonalPoint = (orthogonalVector * matrix) / 20.0;
glVertex3d(currentNormal.x() + orthogonalPoint.x(),
currentNormal.y() + orthogonalPoint.y(),
currentNormal.z() + orthogonalPoint.z());
}
glEnd();
}
/*
* Don't forget about the model-view matrix
*/
glPopMatrix();
}
I had bee searching basically all night to figure out why the depth test was not working. Things in the distance were being drawn over the things in the foreground. Finally, after writing halfway through a question here on stackoverflow I placed the code
glEnable(GL_DEPTH_TEST);
//glDepthMask(GL_TRUE);
//glClearDepth(0.0);
//glDepthFunc(GL_LEQUAL);
at the start of my for loop in the paintGL function. Low and behold the depth was correct. So, now that I have it working I'd really like to know WHY it is working. Why does this work properly because I enabled 'GL_DEPTH_TEST' in the loop? If I don't manually change it shouldn't the state remain the same? I'd like to know because knowing is half the battle.

Rotating around a point different from origin

I'm trying to code a camera with glTranslate/glRotate. To implement the look-up / look-down functions I need all the objects in my rendering space to rotate around a point (that is, where the "camera" is at), point which usually differs from the origin. Still, things keep rotating around the origin. Is there a way to specify a different point?
EDIT: Added code
Thanks for your fast reply. It seems that I can't get it working right no matter what, so I've decided to add my code; I'd much appreciate if someone could take a look at it and tell me what changes are needed in order to translate/rotate/translate back.
#include <iostream>
#include <cmath>
#include <GLUT/GLUT.h>
const double roaming_step = .13;
double z_offset = .0;
double y_offset = .0;
double x_offset = .0;
const double angle_step = 1.5;
double angle_xz = .0;
double angle_yz = .0;
bool keyStates[256] = { false };
void drawFloor()
{
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_QUADS);
glVertex3f(-3.0, -1.0, 3.0);
glVertex3f(-3.0, -1.0, -3.0);
glVertex3f(3.0, -1.0, -3.0);
glVertex3f(3.0, -1.0, 3.0);
glEnd();
}
void drawBalls()
{
glTranslatef(-3.0, -.5, -3.0);
glColor3f(.8, .1, .1);
for(int i = 0; i < 3; i++)
{
glPushMatrix();
glTranslatef(.0, -.5, i * 3);
for(int j = 0; j < 3; j++)
{
glPushMatrix();
glTranslatef(j * 3, .0, .0);
glutSolidSphere(.5, 20, 20);
glPopMatrix();
}
glPopMatrix();
}
}
void keyPressed(unsigned char key, int x, int y)
{
keyStates[key] = true;
}
void keyReleased(unsigned char key, int x, int y)
{
keyStates[key] = false;
}
void keyboardOperations()
{
if(keyStates['w'])
z_offset += roaming_step;
if(keyStates['s'])
z_offset -= roaming_step;
if(keyStates['a'])
x_offset += roaming_step;
if(keyStates['d'])
x_offset -= roaming_step;
if(keyStates['i'])
{
angle_xz -= angle_step;
if(angle_xz < .0)
angle_xz += 360.0;
}
if(keyStates['o'])
{
angle_xz += angle_step;
if(angle_xz >= 360.0)
angle_xz -= 360.0;
}
if(keyStates['u'])
{
angle_yz -= angle_step;
if(angle_yz < .0)
angle_yz += 360.0;
}
if(keyStates['j'])
{
angle_yz += angle_step;
if(angle_yz >= 360.0)
angle_yz -= 360.0;
}
if(keyStates['q'])
exit(0);
}
// I guess it has to be done in this function
// but didn't get how
void camera()
{
glLoadIdentity();
// Forward / Backward
glTranslated(.0, .0, z_offset);
// Left / Right
glTranslated(x_offset, .0, .0);
// XZ Rotation
glRotated(angle_xz, .0, 1.0, .0);
// YZ Rotation
glRotated(angle_yz, 1.0, .0, .0);
}
void display(void)
{
keyboardOperations();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
camera();
drawFloor();
drawBalls();
glutSwapBuffers();
}
void reshape(int width, int height)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, width, height);
GLdouble aspect = (GLdouble) width / (GLdouble) height;
gluPerspective(60, aspect, 1, 100);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(0, 0);
glutCreateWindow("openGLtest3");
glClearColor(.0, .0, .0, .0);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_FLAT);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(display);
glutIgnoreKeyRepeat(true);
glutKeyboardFunc(keyPressed);
glutKeyboardUpFunc(keyReleased);
glutMainLoop();
return 0;
}
In openGL, glRotation fuction takes origin as a reference. In order to rotate around a point (your camera coordinate in this case) you should translate your camera position to the origin (Translate all your objects accordingly) and then apply rotation function.And then you can translate your camera back (with all your objects)
lets say your camera position is (a,b,c) so your code should be something like :
foreach object
{
glPushMatrix();
glTranslate(a,b,c);
glRotate(...);
glTranslate(-a,-b,-c);
//render
glPopMatrix();
}

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();