Zıplayan Toplar - OpenGL - C
//Uygulama genel olarak bir platform üstüne birbirinden bağımsız zıplayan topları göstermektedir.
// Platform da gölgelendirme yapılmıştır, yakınlaşıp - uzaklaşma yukarı-aşağı hareketleri vardır. Duvarlar eklenmiştir.
//Ayrıca mause tuşlarıyla da hareketler eklenmiştir.
#ifdef __APPLE_CC__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include <cmath>
int i=0;
// Renkler tanımlanır
GLfloat WHITE[] = {1, 1, 1}; /*beyaz*/
GLfloat RED[] = {1, 0, 0}; /*kırmızı*/
GLfloat GREEN[] = {0, 1, 0}; /*yeşil*/
GLfloat MAGENTA[] = {1, 0, 1}; /*eflatun*/
GLfloat Yellow[]= { 1.0, 1.0, 0.0 ,1}; /* sari*/
GLfloat Blue[]= { 0.0, 0.0, 1.0 ,1}; /*mavi*/
// Kamera: Yarıçapı 10 olan daire merkezli olmak üzere yatay olarak hareket eder. Dikey olarak da yukarı aşağa hareket eder.
class Camera {
double theta; // x, z pozisyonları hesaplanır
double y; // mevcut y pozisyonu
double dTheta; // kameranın dönmesiyle teta arttırılır
double dy; // y arttırılır kameranın yukarı aşağa hareketiyle
public:
Camera(): theta(0), y(1), dTheta(0.04), dy(0.2) {}
double getX() {return 10 * cos(theta);}
double getY() {return y;}
double getZ() {return 10 * sin(theta);}
void moveRight() {theta += dTheta;}
void moveLeft() {theta -= dTheta;}
void moveUp() {y += dy;}
void moveDown() {if (y > dy) y -= dy;}
};
//Ball yani topun bir yarıçapı, rengi ve xz yüzeyi ile maksimum yükseklik arasında yukarı-aşağı olmak üzere bir zıplaması vardır.
//Bu yüzden x z koordinatları sağlanmıştır. Topların yukarı-aşağı zıplamaları için her kare 0.05 birim alınmıştır.
class Ball {
double radius;
GLfloat* color;
double maximumHeight;
double x;
double y;
double z;
int direction;
public:
Ball(double r, GLfloat* c, double h, double x, double z):
radius(r), color(c), maximumHeight(h), direction(-1),
y(h), x(x), z(z) {
};
void update() {
y += direction * 0.05;
if (y > maximumHeight) {
y = maximumHeight; direction = -1;
} else if (y < radius) {
y = radius; direction = 1;
}
glPushMatrix();
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
glTranslated(x, y, z);
glutSolidSphere(radius, 30, 30);
glPopMatrix();
}
};
//Platformun olduğu sınıf. Kareler 1x1 şeklindedir. 4,3,7 koordinatlarında gölgelendirme yapılmıştır.
class Checkerboard {
int displayListId;
int width;
int depth;
public:
Checkerboard(int width, int depth): width(width), depth(depth) {}
double centerx() {return width / 2;}
double centerz() {return depth / 2;}
void create() {
displayListId = glGenLists(1);
glNewList(displayListId, GL_COMPILE);
GLfloat lightPosition[] = {4, 3, 7, 1}; //ışıklandırma 4,3,7 pozisyonunda
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
glBegin(GL_QUADS);
glNormal3d(0, 1, 0); //yakınlaşıp uzaklaştıkça, döndürmelerde gölgelendirme etkisi
for (int x = 0; x < width - 1; x++) {
for (int z = 0; z < depth - 1; z++) {
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE,
(x + z) % 2 == 0 ? GREEN : GREEN); //duvar platformlarının rengi
glVertex3d(x, 0, z);
glVertex3d(x+1, 0, z);
glVertex3d(x+1, 0, z+1);
glVertex3d(x, 0, z+1);
}
}
glEnd();
glEndList();
}
//duvarlar oluşturuldu
void DuvarCiz()
{
int i;
int k;
int l;
int m;
//Sol kenara küplerden duvar yaptıran döngü
for (i=0 ; i<155 ; i=i+5){
//Döngüye sokulan küpün çizimi
glPushMatrix();
glTranslatef(-7.0,-7.0,i);
glBegin(GL_QUADS);
glColor3f(0.50196078431f,0.0f,0.0f);
glVertex3f(3.0f,3.0f,-3.0f);
glVertex3f(-3.0f,3.0f,-3.0f);
glVertex3f(-3.0f,3.0f,3.0f);
glVertex3f(3.0f,3.0f,3.0f);
glColor3f(0.933f,0.901f,0.521f);
glVertex3f(3.0f,-3.0f,3.0f);
glVertex3f(-3.0f,-3.0f,3.0f);
glVertex3f(-3.0f,-3.0f,-3.0f);
glVertex3f(3.0f,-3.0f,-3.0f);
glVertex3f(3.0f,3.0f,3.0f);
glVertex3f(-3.0f,3.0f,3.0f);
glVertex3f(-3.0f,-3.0f,3.0f);
glVertex3f(3.0f,-3.0f,3.0f);
glVertex3f(3.0f,-3.0f,-3.0f);
glVertex3f(-3.0f,-3.0f,-3.0f);
glVertex3f(-3.0f,3.0f,-3.0f);
glVertex3f(3.0f,3.0f,-3.0f);
glVertex3f(-3.0f,3.0f,3.0f);
glVertex3f(-3.0f,3.0f,-3.0f);
glVertex3f(-3.0f,-3.0f,-3.0f);
glVertex3f(-3.0f,-3.0f,3.0f);
glVertex3f(3.0f,3.0f,-3.0f);
glVertex3f(3.0f,3.0f,3.0f);
glVertex3f(3.0f,-3.0f,3.0f);
glVertex3f(3.0f,-3.0f,-3.0f);
glEnd();
glPopMatrix();
}
//Üst kenara küplerden duvar yaptıran döngü
for(k=0; k<155; k=k+5){
//Döngüye sokulacak küpün çizimi gerçekleştirildi
glPushMatrix();
glTranslatef(k,-10.0,-5.0);
glBegin(GL_QUADS);
glColor3f(0.50196078431f,0.0f,0.0f);
glVertex3f(3.0f,3.0f,-3.0f);
glVertex3f(-3.0f,3.0f,-3.0f);
glVertex3f(-3.0f,3.0f,3.0f);
glVertex3f(3.0f,3.0f,3.0f);
glColor3f(0.933f,0.901f,0.521f);
glVertex3f(3.0f,-3.0f,3.0f);
glVertex3f(-3.0f,-3.0f,3.0f);
glVertex3f(-3.0f,-3.0f,-3.0f);
glVertex3f(3.0f,-3.0f,-3.0f);
glVertex3f(3.0f,3.0f,3.0f);
glVertex3f(-3.0f,3.0f,3.0f);
glVertex3f(-3.0f,-3.0f,3.0f);
glVertex3f(3.0f,-3.0f,3.0f);
glVertex3f(3.0f,-3.0f,-3.0f);
glVertex3f(-3.0f,-3.0f,-3.0f);
glVertex3f(-3.0f,3.0f,-3.0f);
glVertex3f(3.0f,3.0f,-3.0f);
glVertex3f(-3.0f,3.0f,3.0f);
glVertex3f(-3.0f,3.0f,-3.0f);
glVertex3f(-3.0f,-3.0f,-3.0f);
glVertex3f(-3.0f,-3.0f,3.0f);
glVertex3f(3.0f,3.0f,-3.0f);
glVertex3f(3.0f,3.0f,3.0f);
glVertex3f(3.0f,-3.0f,3.0f);
glVertex3f(3.0f,-3.0f,-3.0f);
glEnd();
glPopMatrix();
}
//Sağ kenara küplerden duvar oluşturan döngü yapıldı
for(l=0; l<155; l=l+5){
glPushMatrix();
glTranslatef(155,-10.0,l);
glBegin(GL_QUADS);
glColor3f(0.50196078431f,0.0f,0.0f);
glVertex3f(3.0f,3.0f,-3.0f);
glVertex3f(-3.0f,3.0f,-3.0f);
glVertex3f(-3.0f,3.0f,3.0f);
glVertex3f(3.0f,3.0f,3.0f);
glColor3f(0.933f,0.901f,0.521f);
glVertex3f(3.0f,-3.0f,3.0f);
glVertex3f(-3.0f,-3.0f,3.0f);
glVertex3f(-3.0f,-3.0f,-3.0f);
glVertex3f(3.0f,-3.0f,-3.0f);
glVertex3f(3.0f,3.0f,3.0f);
glVertex3f(-3.0f,3.0f,3.0f);
glVertex3f(-3.0f,-3.0f,3.0f);
glVertex3f(3.0f,-3.0f,3.0f);
glVertex3f(3.0f,-3.0f,-3.0f);
glVertex3f(-3.0f,-3.0f,-3.0f);
glVertex3f(-3.0f,3.0f,-3.0f);
glVertex3f(3.0f,3.0f,-3.0f);
glVertex3f(-3.0f,3.0f,3.0f);
glVertex3f(-3.0f,3.0f,-3.0f);
glVertex3f(-3.0f,-3.0f,-3.0f);
glVertex3f(-3.0f,-3.0f,3.0f);
glVertex3f(3.0f,3.0f,-3.0f);
glVertex3f(3.0f,3.0f,3.0f);
glVertex3f(3.0f,-3.0f,3.0f);
glVertex3f(3.0f,-3.0f,-3.0f);
glEnd();
glPopMatrix();
}
//Alt kenara küplerden duvar oluşturan döngü yapıldı
for(m=150; m>-5; m=m-5){
glPushMatrix();
glTranslatef(m,-10.0,155);
glBegin(GL_QUADS);
glColor3f(0.50196078431f,0.0f,0.0f);
glVertex3f(3.0f,3.0f,-3.0f);
glVertex3f(-3.0f,3.0f,-3.0f);
glVertex3f(-3.0f,3.0f,3.0f);
glVertex3f(3.0f,3.0f,3.0f);
glColor3f(0.933f,0.901f,0.521f);
glVertex3f(3.0f,-3.0f,3.0f);
glVertex3f(-3.0f,-3.0f,3.0f);
glVertex3f(-3.0f,-3.0f,-3.0f);
glVertex3f(3.0f,-3.0f,-3.0f);
glVertex3f(3.0f,3.0f,3.0f);
glVertex3f(-3.0f,3.0f,3.0f);
glVertex3f(-3.0f,-3.0f,3.0f);
glVertex3f(3.0f,-3.0f,3.0f);
glVertex3f(3.0f,-3.0f,-3.0f);
glVertex3f(-3.0f,-3.0f,-3.0f);
glVertex3f(-3.0f,3.0f,-3.0f);
glVertex3f(3.0f,3.0f,-3.0f);
glVertex3f(-3.0f,3.0f,3.0f);
glVertex3f(-3.0f,3.0f,-3.0f);
glVertex3f(-3.0f,-3.0f,-3.0f);
glVertex3f(-3.0f,-3.0f,3.0f);
glVertex3f(3.0f,3.0f,-3.0f);
glVertex3f(3.0f,3.0f,3.0f);
glVertex3f(3.0f,-3.0f,3.0f);
glVertex3f(3.0f,-3.0f,-3.0f);
glEnd();
glPopMatrix();
}
}
void draw() {
glCallList(displayListId);
DuvarCiz();
}
};
//Kamera, platform ve toplar için değerler
Checkerboard checkerboard(8, 8); //platformun boyutu
Camera camera;
Ball balls[] = {
Ball(1, GREEN, 7, 6, 1),
Ball(1.5, MAGENTA, 6, 3, 4),
Ball(0.4, WHITE, 5, 1, 7),
Ball(0.6, Yellow, 4, 3, 2),
Ball(0.3, GREEN, 5, 1, 4),
Ball(0.1, WHITE, 6, 1, 7),
Ball(0.3, Yellow, 7, 2, 4),
Ball(0.2, Yellow, 5, 1, 3)
};
//Uygulamaya özel başlatma kısmı:
//Genel aydınlatma parametreleri ayarlandı ve görüntü listesi oluşturuldu
void init() {
glClearColor(0.1, 0.39, 0.88, 1.0);
//arkaplan rengini değiştirdi bu kısım
glTranslatef(0, 0, -3);
glRotatef(50, 1, 0, 0);
glRotatef(70, 0, 1, 0);
glEnable(GL_DEPTH_TEST);
glLightfv(GL_LIGHT0, GL_DIFFUSE, WHITE);
glLightfv(GL_LIGHT0, GL_SPECULAR, WHITE);
glMaterialfv(GL_FRONT, GL_SPECULAR, WHITE);
glMaterialf(GL_FRONT, GL_SHININESS, 30);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
checkerboard.create();
}
//Mevcut kamera pozisyonundan bir kare, platform ve toplar çizildi
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(camera.getX(), camera.getY(), camera.getZ(),
checkerboard.centerx(), 0.0, checkerboard.centerz(),
0.0, 1.0, 0.0);
checkerboard.draw();
for (int i = 0; i < sizeof balls / sizeof(Ball); i++) {
balls[i].update();
}
glFlush();
glutSwapBuffers();
glFlush();
}
// yeniden şekillendirme kısmı : pencereye tamamen uygun bir kamera oluşturulur
void reshape(GLint w, GLint h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, GLfloat(w) / GLfloat(h), 1.0, 120.0); //ilk bakış
glMatrixMode(GL_MODELVIEW);
}
void timer(int v) {
glutPostRedisplay();
glutTimerFunc(1000/100, timer, v); //toplar hızlanır
}
// Kamera, yön tuşlarına basıldığında hareket eder
void special(int key, int, int) {
switch (key) {
case GLUT_KEY_LEFT: camera.moveLeft(); break;
case GLUT_KEY_RIGHT: camera.moveRight(); break;
case GLUT_KEY_UP: camera.moveUp(); break;
case GLUT_KEY_DOWN: camera.moveDown(); break;
}
glutPostRedisplay();
}
//mouse fonksiyonları kısmı
void mouse(int button, int state, int x, int y) {
switch (button) {
case GLUT_LEFT_BUTTON: camera.moveLeft(); //sol mouse tuşu fonksiyonu -- sola hareket sağlar
break;
case GLUT_RIGHT_BUTTON:camera.moveRight(); //sağ mouse tuşu fonksiyonu -- sağa hareket sağlar
break;
case GLUT_UP:camera.moveUp(); //orta mouse tuşu fonksiyonu -- yukarı hareket sağlar
break;
}
}
// GLUT başlatılır ve asıl döngüye girilir
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_SINGLE);
glutInitWindowPosition(80, 80);
glutInitWindowSize(800, 600);
glutCreateWindow("ZIPLAYAN TOPLAR");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutSpecialFunc(special);
glutMouseFunc(mouse);
glutTimerFunc(100, timer, 0);
init();
glutMainLoop();
}
Yorumlar
Yorum Gönder