I'm struggling with a triangle translation in OpenGL and using uC++. Every bird (triangle) is a thread. The thing is that when the birds are translating, the camera or general image is moving up or down.
The draw code is this one:
void Graphics::draw(){
double AxisX;
double AxisY;
double Direction;
for (int i = 0; i < numBirds; i++)
{
AxisX = birds[i]->Px;
AxisY = birds[i]->Py;
Direction = birds[i]->Dir - 90;
glColor3d(1, 1, 1);
//Operacion para el triangulo
glTranslated(AxisX, AxisY, 0.0f);
glRotated(Direction, 0, 0, 1);
/*
Se mantienen estas proporciones:
Base: 1
Altura: 1.9364916731
Lado (isosceles): 2
*/
glBegin(GL_TRIANGLES); // Inicio del dibujo
glVertex3d(-5, 0, 0); // Primer vertice
glVertex3d( 5, 0, 0); // Segundo vertice
glVertex3d( 0, 15, 0); // Tercer vertice
glEnd(); // Fin del dibujo
// Deshago las operaciones de rotacion y translacion
glRotated(-Direction, 0, 0, 1);
glTranslated(-AxisX, -AxisY, 0.0f);
}
}
The question is, how can I fix this? I've been struggling for hours getting nothing.
Related
I am trying to create a ring of 8 spike-plates using freeglut. Every plate should be rotated/tilted by 30 degrees relative to the center ball, and all of them are supposed to be ordered in ring-form. Here is an example:
Here is my attempt:
void Larvitar::drawTail()
{
// Create tail ball
glPushMatrix();
glColor4f(0.2, 0, 1, 1.0);
GLUquadric *tail;
tail = gluNewQuadric();
glTranslatef(0, 0.2, -3.0);
gluSphere(tail, 1, 100, 30);
glPopMatrix();
double xrotate = 30;
for (int i = 0; i < 360; i += 45)
{
double rnd = ((double)rand() / (RAND_MAX));
glPushMatrix();
glColor4f(rnd, 0, rnd, 1.0);
glRotatef(xrotate, 1, 0, 0); // kippen?
glRotatef(i, 0, 0, 1); // Kreisform
glScalef(1, 0.4, 2);
glTranslatef(0, -2, -2.1);
glutSolidCube(1);
glPopMatrix();
xrotate -= xrotate;
}
}
The problem is that the plates are in ring form but not each one is tilted by 30 degrees outwards, only the first one is. What am I doing wrong? How can I solve this in a loop without having to create every plate by hand?
Solved it myself.
void Larvitar::drawTail() {
// Create tail ball
glPushMatrix();
glColor4f(0.2, 0, 1, 1.0);
GLUquadric *tail;
tail = gluNewQuadric();
glTranslatef(0, 0.2, -3.0);
gluSphere(tail, 1, 100, 30);
glPopMatrix();
glColor4f(0.58, 0.655, 0.482, 1.0);
for (int i = 0; i < 360; i += 45) {
glPushMatrix();
glRotatef(i, 0, 0, 1);
glRotatef(30, 1, 0, 0);
glScalef(1, 0.5, 2);
glTranslatef(0, -2, -2.1);
glutSolidCube(1);
glPopMatrix();
}
}
I've got a taks from university and have to make a small example of solar system, the objects have to rotate etc. The problem is that when I do not call GluLookAt() everything looks fine, but I would like to change the view and when I call the function, there occurs that one orbit renders completely strangely.
I do not know if problem is with wrong creation of the first orbit, or with the proper values in gluLookAt parameters. Can anyone help?
Here's how it looks without calling gluLookAt():
Here's how it looks after gluLookAt():
Here's the code:
#include "stdafx.h"
#include <GL\glut.h>
#include <math.h>
GLfloat yRotated=1;
GLfloat movement = 0;
void drawCircle(float r) { // radius
glBegin(GL_LINE_LOOP);
for (int i = 0; i <= 300; i++) {
double angle = 2 * 3.14 * i / 300;
double x = r*cos(angle);
double y = r*sin(angle);
glVertex3d(x, y, -5.5);
}
glEnd();
}
void display(void) {
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
//gluLookAt(5, 5, 5, 0, 0, -8, 0, 1, 0); // 3rd coordinate - depth
float radius1 = 6;
float radius2 = 1;
//first orbit
glColor3f(1, 1, 1);
glPushMatrix();
glTranslatef(0, 0, -5.5);
drawCircle(radius1);
glPopMatrix();
//second orbit with rotation
glPushMatrix();
glRotatef(yRotated, 0, 0, 1);
glPushMatrix();
glTranslatef(radius1 / 2, 0, 0);
drawCircle(radius2);
glPopMatrix();
glPopMatrix();
//first czajnik
glColor3f(0.8, 0.2, 0.1);
glPushMatrix();
glTranslatef(0.0, 0.0, -5.5);
// glScalef(1.0, 1.0, 1.0);
glRotatef(yRotated, 0, 0, 1);
glRotatef(90, 1, 0, 0);
glutSolidSphere(1,20,20);
//second czajnik
glPushMatrix();
glColor3f(0, 0, 1);
glTranslatef(radius1/2, 0, 0);
glRotatef(yRotated, 0, 1, 0);
glutSolidSphere(0.5, 20, 20);
//third czajnik
glPushMatrix();
glTranslatef(radius2, 0, 0);
glColor3f(1, 1, 0);
glRotatef(yRotated, 0, 1, 0);
glutSolidSphere(0.2, 20, 20);
glPopMatrix();
//second czajnik pop
glPopMatrix();
//first czajnik pop
glPopMatrix();
glFlush();
}
void idle() {
yRotated += 0.1;
Sleep(2);
display();
}
void myReshape(int w, int h) {
if (w == 0 || h == 0) return;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70.0, (GLdouble)w / (GLdouble)h, 0.5, 20.0);
glViewport(0, 0, w, h);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(900, 600);
glutCreateWindow("Solar system");
//window with a title
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glClearColor(0, 0, 0, 1.0);
glutDisplayFunc(display);
glutReshapeFunc(myReshape);
glutIdleFunc(idle);
glutMainLoop();
return 0;
}
Some of your objects are at different z values, e.g. 1st orbit at -5.5, second at 0, because you "popped" the matrix.
In general, do not do so many push\pops nested into each other, matrix stack isn't made of rubber.
There is more efficient circle drawing procedure than to calculate sine and cosine for each step, e.g. to get advantage of circle being a figure of rotation:
inline void circle(F32 r, U32 quality)
{
if (r < F_ALMOST_ZERO) return;
F32 th = M_PI /(quality-1);
F32 s = sinf(th);
F32 c = cosf(th);
F32 t;
F32 x = r;
F32 y = 0;
::glBegin (GL_LINE_LOOP);
for(U32 i = 0; i < quality; i++)
{
glVertex2f(x, y);
t = x;
x = c*x + s*y;
y = -s*t + c*y;
}
::glEnd();
}
it can be optimized further by using symmetry, but this one is the basis.
I'm really pulling my hair out with this problem. I'm trying to create a simple game where the player rolls a ball around a playing area.
I'm using WinAPI for window management and input handling.
I tried to render some simple quads too, instead of the GLU sphere, but that didn't work either.
I've separated the code across different classes. I present the relevant code below. This code is in my WinMain:
while (running) {
PeekMessage(&msg, hwnd, NULL, NULL, PM_REMOVE);
if (msg.message == WM_QUIT)
running = false;
else {
// handle key presses
// update
gameWorld->update(getDirections());
// render
gameWorld->render(deviceContext);
// I added this block of code for testing, still does not work
glColor4f(1, 1, 1, 1);
glBegin(GL_QUADS);
glVertex3f(10, 10, 0);
glVertex3f(10, -10, 0);
glVertex3f(-10, -10, 0);
glVertex3f(-10, 10, 0);
glEnd();
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
Here's GameWorld.cpp:
GameWorld::GameWorld()
{
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
this->ball = new Ball(1, 10, 10);
this->camera = new Camera(ball);
}
GameWorld::~GameWorld()
{
delete this->ball;
}
void GameWorld::render(HDC deviceContext) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
this->ball->draw();
SwapBuffers(deviceContext);
}
void GameWorld::update(Directions dirs) {
glLoadIdentity();
this->ball->handleInput(dirs);
this->ball->update();
this->camera->update();
}
Here's Camera update method:
void Camera::update() {
GLdouble ballX = ball->getLocation()->getX();
GLdouble ballY = ball->getLocation()->getY();
GLdouble ballZ = ball->getLocation()->getZ();
GLdouble x = ballX + cos(90) * this->distanceFromBall;
GLdouble y = ballY + cos(90) * this->distanceFromBall;
GLdouble z = ballZ + cos(90) * this->distanceFromBall;
gluLookAt(
x, y, z,
ballX, ballY, ballZ,
0, 1, 0
);
}
Here's the Ball draw method:
void Ball::draw() {
glPushMatrix();
this->quadric = gluNewQuadric();
glTranslated(this->location->getX(), this->location->getY(), this->location->getZ());
gluQuadricDrawStyle(this->quadric, GLU_FILL);
glColor4f(1, 1, 1, 1);
gluSphere(this->quadric, this->radius, this->slices, this->stacks);
gluDeleteQuadric(this->quadric);
glPopMatrix();
}
What the #!#% is wrong with this code? I should get this thing done in a week, so I really could use some help...
I had to use the gluPerspective() function to make this work. My GameWorld constructor now looks like this:
GameWorld::GameWorld()
{
glViewport(0, 0, WIDTH, HEIGHT); // reset the viewport to new dimensions
glMatrixMode(GL_PROJECTION); // set projection matrix current matrix
glLoadIdentity(); // reset projection matrix
// calculate aspect ratio of window
gluPerspective(54.0f, (GLfloat)WIDTH / (GLfloat)HEIGHT, 1.0f, 1000.0f);
glMatrixMode(GL_MODELVIEW); // set modelview matrix
glLoadIdentity();
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
this->ball = new Ball(1, 20, 20);
this->camera = new Camera(ball);
}
The code is copied from the sample code of Dave Astle's book "OpenGL Game Programming".
I'm trying to rotate an isosceles triangle given a certain direction in OpenGL (All this in 2D). For example, if the triangle is moving up, then the triangle must be pointing up, and this has to be applicated in all the directions(down-right side-left side-up right...etc) in the plane.
The question is, how this can be done? I have the dots (x,y) for the translation and the direction that is an angle(not radian). The code is the following.
void Graphics::draw(){
double P[2];
double Direction;
for (int i = 0; i < numBirds; i++)
{
P[0] = flock[i]->Px;
P[1] = flock[i]->Py;
Direction = flock[i]->Dir - 90;
glPushMatrix();
glColor3d(1, 1, 1);
//Operacion para el triangulo
glTranslated(P[0], P[1], 0.0);
glRotated(Direction, 0.0, 0.0, 1.0);
/*
Se mantienen estas proporciones:
Base: 1
Altura: 1.9364916731
Lado (isosceles): 2
*/
glBegin(GL_TRIANGLES); // Inicio del dibujo
glVertex3d(-1.5, 0, 0); // Primer vertice
glVertex3d( 1.5, 0, 0); // Segundo vertice
glVertex3d( 0, 7.9364916731, 0); // Tercer vertice
glEnd(); // Fin del dibujo
// Deshago las operaciones de rotacion y translacion
glRotated(-Direction, 0, 0, 1);
glTranslated(-P[0], -P[1], 0.0);
glPopMatrix();
//cout << "Velocidad pajaro "<< i <<" Graph x: "<<flock[i]->Vx << " Velocidad pajaro Graph Y:"<< flock[i]->Vy<<endl;
//flock[i]->Py
physics.updatePosition(flock, flock[i]);
//cout << "Velocidad update pajaro "<< i <<" Graph x: "<<flock[i]->Vx << " Velocidad pajaro Graph Y:"<< flock[i]->Vy<<endl;
}
}
In this version of the code, the triangles are moving in a certain direction(x,y), but the triangle is not pointing(isosceles triangles can point with one vertex) to/toward(?) that dir
ection.
i'm working on a project in wich i need to develop a solar system in openGL, then i need to add a rocket and launch it into another planet detecting the collision.
This is the code where i generate the planet, the rocket and the destination:
GLfloat dirCoheteX1 = 0.0f;
GLfloat dirCoheteY1 = 0.0f;
GLfloat dirCoheteZ1 = 0.0f;
GLfloat posx = 80.0f;
GLfloat posy = 0.0f;
GLfloat posz = 0.0f;
//Planet
glPushMatrix();
//Cambiamos el angulo para que tenga una órbita diferente.
glRotatef(angulo+160,0.0f,1.0f,0.0f);
glTranslatef(70.0f,0.0f,0.0f);
glRotatef(angulo+15,0.0f,1.0f,0.0f);
glRotatef(270,1,0,0);
//Carga de texturas
glBindTexture(GL_TEXTURE_2D,texturaTerra);
GLUquadricObj* q=gluNewQuadric();
gluQuadricDrawStyle(q, GLU_FILL);
gluQuadricNormals(q, GLU_SMOOTH);
gluQuadricOrientation(q, GLU_OUTSIDE);
gluQuadricTexture(q, GL_TRUE);
gluSphere(q,10,20,20);
gluDeleteQuadric(q);
glRotatef(-270,1,0,0);
//rocket
glPushMatrix();
glTranslatef(dirCoheteX1+0.0f,dirCoheteY1+0.0f,dirCoheteZ1+0.0f);
glRotatef(anguloY,0.0f,1.0f,0.0f);
glLineWidth(2.5);
glBegin(GL_LINES);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(15, 0, 0);
glEnd();
glPopMatrix();
//Target
glPushMatrix();
//Cambiamos el angulo para que tenga una órbita diferente.
glRotatef(angulo+240,0.0f,1.0f,0.0f);
glTranslatef(posx,posy,posz);
glRotatef(angulo+15,0.0f,1.0f,0.0f);
glBindTexture(GL_TEXTURE_2D,texturaSaturno);
GLUquadricObj* q5=gluNewQuadric();
gluQuadricDrawStyle(q5, GLU_FILL);
gluQuadricNormals(q5, GLU_SMOOTH);
gluQuadricOrientation(q5, GLU_OUTSIDE);
gluQuadricTexture(q5, GL_TRUE);
gluSphere(q5,5,20,20);
gluDeleteQuadric(q5);
glPushMatrix();
The planets are generated on X axis and they rotate around the Sun on Y axis.
Right now i'm adding the rocket's X position to move it from the planet and rotating it in it's Y axis to head it to the planet, but i don't know how to detect the collision correctly.
I'm using this algorithm:
dirCoheteX1+=0.05f; //move the rocket
anguloY+=0.05f; //rotate the rocket
dx = posx- dirCoheteX1;
dy = posy- dirCoheteY1;
dz = posz- dirCoheteZ1 ;
distance = sqrt(dx*dx + dy*dy + dz*dz);
if (distance < (1.0)) {
contact = true;
}
But the collision is being detected before it actually the rocket reaches the target.