Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdlib.h>
- #include <stdio.h>
- #include <math.h>
- #include <time.h>
- #ifdef __APPLE__
- #include <GLUT/glut.h>
- #else
- #include <GL/glut.h>
- #endif
- // Tamanho da box (centrada na origem) onde as figuras são desenhadas.
- #define CELL_SIZE 2.0
- // Tamanho (número de casas) do tabuleiro quadrado.
- // Cada casa do tabuleiro tem tamanho CELL_SIZE.
- // TAB_SIZE tem que ser par (facilita o alinhamento).
- #define TAB_SIZE 10
- GLfloat vertices[][3] = { {-1.0,-1.0,-1.0}, {1.0,-1.0,-1.0},
- {1.0,1.0,-1.0}, {-1.0,1.0,-1.0}, {-1.0,-1.0,1.0},
- {1.0,-1.0,1.0}, {1.0,1.0,1.0}, {-1.0,1.0,1.0} };
- GLfloat normals[][3] = { {-1.0,-1.0,-1.0}, {1.0,-1.0,-1.0},
- {1.0,1.0,-1.0}, {-1.0,1.0,-1.0}, {-1.0,-1.0,1.0},
- {1.0,-1.0,1.0}, {1.0,1.0,1.0}, {-1.0,1.0,1.0} };
- GLfloat colors[][3] = { {0.0,0.0,0.0}, {1.0,0.0,0.0},
- {1.0,1.0,0.0}, {0.0,1.0,0.0}, {0.0,0.0,1.0},
- {1.0,0.0,1.0}, {1.0,1.0,1.0}, {0.0,1.0,1.0} };
- typedef struct cubo* Cubo;
- struct cubo {
- int xTab, yTab; // Posição do cubo nas casas do tabuleiro.
- float scale;
- float xPos, yPos;
- float xRot, yRot; // Rotação necessária em x e em y em graus multiplos de 90.
- float xRoti, yRoti; // Rotação actual em x e em y até atingir xRot e yRot, respectivamente.
- int posicao;
- // Matriz de rotação que define a posição actual do cubo.
- GLfloat m[16];
- float r, g, b;
- };
- Cubo cubo; // cubo actual
- Cubo* aCubos; // array de cubos
- int nCubos = 5; // 1..9
- int ox[10][10];
- float distCamara = 5;
- float dDistCamara = 0.2;
- float alfaLongitude = 0;
- float alfaLatitude = 0;
- float dAlfa = 2;
- float xRato, yRato; // guarda a última posição do rato (para calcular o deslocamento na Lat. e Long.)
- float angRato = 0.25; // precisão do rato: número de angulos por pixel.
- int timeUpdate = 20; // intervalo de tempo (ms) para o update
- float velRot = 200.0; // velocidade de rotação dos cubos em graus/s
- float angRotMax = 90;
- void polygon(int a, int b, int c, int d)
- {
- glBegin(GL_POLYGON);
- glNormal3fv(normals[a]);
- glVertex3fv(vertices[a]);
- glNormal3fv(normals[b]);
- glVertex3fv(vertices[b]);
- glNormal3fv(normals[c]);
- glVertex3fv(vertices[c]);
- glNormal3fv(normals[d]);
- glVertex3fv(vertices[d]);
- glEnd();
- }
- void lineloop(int a, int b, int c, int d)
- {
- glColor3f(1.0, 1.0, 1.0);
- glBegin(GL_LINE_LOOP);
- glVertex3fv(vertices[a]);
- glVertex3fv(vertices[b]);
- glVertex3fv(vertices[c]);
- glVertex3fv(vertices[d]);
- glEnd();
- }
- void colorcube(void)
- {
- polygon(0, 3, 2, 1);
- polygon(2, 3, 7, 6);
- polygon(0, 4, 7, 3);
- polygon(1, 2, 6, 5);
- polygon(4, 5, 6, 7);
- polygon(0, 1, 5, 4);
- lineloop(0, 3, 2, 1);
- lineloop(2, 3, 7, 6);
- lineloop(0, 4, 7, 3);
- lineloop(1, 2, 6, 5);
- lineloop(4, 5, 6, 7);
- lineloop(0, 1, 5, 4);
- }
- // Desenha um cubo com diferentes cores nos lados.
- void colorcubeWithColor(float r, float g, float b)
- {
- // Um dos lados começa com uma cor e os outros lados são variações dessa cor.
- float cor[3] = { r, g, b };
- glColor3fv(cor);
- polygon(0, 3, 2, 1);
- glColor3fv(cor);
- polygon(2, 3, 7, 6);
- glColor3fv(cor);
- polygon(0, 4, 7, 3);
- glColor3fv(cor);
- polygon(1, 2, 6, 5);
- glColor3fv(cor);
- polygon(4, 5, 6, 7);
- glColor3fv(cor);
- polygon(0, 1, 5, 4);
- lineloop(0, 3, 2, 1);
- lineloop(2, 3, 7, 6);
- lineloop(0, 4, 7, 3);
- lineloop(1, 2, 6, 5);
- lineloop(4, 5, 6, 7);
- lineloop(0, 1, 5, 4);
- }
- void TabuleiroA()
- {
- //int ox[12], oy[12];
- float color[3] = { 0.0, 0.0, 1.0 };
- for (int i = 2; i <= 4; i++) {
- ox[i][3] = 1;
- }
- }
- // Desenha um tabuleiro no plano XY e centrado na origem dos eixos;
- // é quadrado, de tamanho TAB_SIZE x TAB_SIZE posições (casas do tabuleiro);
- // cada posição que tem lado de tamanho CELL_SIZE.
- void desenhaTabuleiro()
- {
- int i, j;
- TabuleiroA();
- glPushMatrix();
- // Centrar o tabuleiro no eixo XY e colocar o topo do tabuleiro no eixo dos Z (Z = 0).
- glTranslatef(-(TAB_SIZE * CELL_SIZE) / 2, -(TAB_SIZE * CELL_SIZE) / 2, -CELL_SIZE / 2);
- for (i = 0; i < TAB_SIZE; i++) //i = Y, j= X
- for (j = 0; j < TAB_SIZE; j++) {
- if (ox[j][i] != 1) {
- glPushMatrix();
- glTranslatef(j * CELL_SIZE + CELL_SIZE / 2, i * CELL_SIZE + CELL_SIZE / 2, 0);
- glScalef(0.90, 0.90, 0.30);
- glColor3f(1.0, 0.0, 0.0);
- colorcube(); // Este cubo tem que ser desenhado dentro do CELL_SIZE.
- // É o que acontece porque o cubo tem o tamanho do CELL_SIZE.
- glPopMatrix();
- }
- }
- glPopMatrix();
- //glutPostRedisplay();
- }
- // Faz os translates necessários para colocar uma forma gráfica (desenhada
- // numa box de tamanho CELL_SIZE) em cima de uma posição do tabuleiro.
- void translateFormaTabuleiro(int x, int y) {
- glTranslatef(-(TAB_SIZE * CELL_SIZE) / 2, -(TAB_SIZE * CELL_SIZE) / 2, CELL_SIZE / 6);
- glTranslatef(x * CELL_SIZE + CELL_SIZE / 2, y * CELL_SIZE + CELL_SIZE / 2, 0);
- }
- // aloca a memória para a struct cubo
- Cubo criaCubo(int xTab, int yTab, float scale)
- {
- Cubo c = (Cubo)malloc(sizeof(*c));
- c->xTab = xTab;
- c->yTab = yTab;
- c->scale = scale;
- c->xPos = xTab;
- c->yPos = yTab;
- c->xRot = c->yRot = c->xRoti = c->yRoti = 0.0;
- c->r = 0;
- c->g = 1;
- c->b = 0;
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
- glGetFloatv(GL_MODELVIEW_MATRIX, c->m);
- glPopMatrix();
- return c;
- }
- // Liberta a memória ocupada pelo Cubo c
- void apagaCubo(Cubo c)
- {
- free(c);
- }
- void actualizaRotCubo(Cubo c, GLfloat ang, GLfloat x, GLfloat y, GLfloat z)
- {
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
- glRotatef(ang, x, y, z);
- glMultMatrixf(c->m);
- glGetFloatv(GL_MODELVIEW_MATRIX, c->m);
- glPopMatrix();
- }
- void rodaCuboCima(Cubo c)
- {
- if (c->yRot == c->yRoti) // não está a rodar em Y
- c->xRot += -angRotMax;
- }
- void rodaCuboBaixo(Cubo c)
- {
- if (c->yRot == c->yRoti) // não está a rodar em Y
- c->xRot += angRotMax;
- }
- void rodaCuboEsq(Cubo c)
- {
- if (c->xRot == c->xRoti) // não está a rodar em X
- c->yRot += -angRotMax;
- }
- void rodaCuboDir(Cubo c)
- {
- if (c->xRot == c->xRoti) // não está a rodar em X
- c->yRot += angRotMax;
- }
- void select(Cubo c)
- {
- c->scale *= 1.1;
- }
- void unselect(Cubo c)
- {
- c->scale /= 1.1;
- }
- void desenhaCubo(Cubo c)
- {
- if (c == NULL) return;
- glPushMatrix();
- translateFormaTabuleiro(c->xTab, c->yTab);
- glScalef(c->scale, c->scale, 1);
- glMultMatrixf(c->m);
- colorcubeWithColor(c->r, c->g, c->b);
- glPopMatrix();
- }
- void updateCubo(Cubo c, int t)
- { // ToDo: colocar aqui uma condição para só fazer isto se for preciso...
- float angMov = velRot * (t / 1000.0);
- if (c->xRot != 0 || c->xRoti != 0) {
- if (c->xRot > c->xRoti) c->xRoti += angMov;
- if (c->xRot < c->xRoti) c->xRoti -= angMov;
- if (fabs(c->xRot - c->xRoti) < angMov) {
- actualizaRotCubo(c, c->xRot, 1, 0, 0);
- c->xRot = c->xRoti = 0.0;
- }
- }
- if (c->yRot != 0 || c->yRoti != 0) {
- if (c->yRot > c->yRoti) c->yRoti += angMov;
- if (c->yRot < c->yRoti) c->yRoti -= angMov;
- if (fabs(c->yRot - c->yRoti) < angMov) {
- actualizaRotCubo(c, c->yRot, 0, 1, 0);
- c->yRot = c->yRoti = 0.0;
- }
- }
- }
- void display(void)
- {
- int i;
- float x, y, z;
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- //glShadeModel(GL_FLAT);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- // Camara
- x = distCamara * sin(alfaLongitude * 3.14 / 180) * cos(alfaLatitude * 3.14 / 180);
- z = distCamara * cos(alfaLongitude * 3.14 / 180) * cos(alfaLatitude * 3.14 / 180);
- y = distCamara * sin(alfaLatitude * 3.14 / 180);
- gluLookAt(x, y, z, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
- // Redimensiona a mundo para caber na janela.
- glScalef(0.2, 0.2, 0.2);
- // Desenha o tabuleiro e os cubos.
- desenhaTabuleiro();
- for (i = 0; i < nCubos; i++)
- desenhaCubo(aCubos[i]);
- printf("xTAB: %d, yTAB: %d\n", cubo->xTab, cubo->yTab);
- //Pinta Cubos
- glFlush();
- glutSwapBuffers();
- }
- void myReshape(int w, int h)
- {
- glViewport(0, 0, w, h);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- if (w <= h)
- glFrustum(-2.0, 2.0, -2.0 * (GLfloat)h / (GLfloat)w,
- 2.0 * (GLfloat)h / (GLfloat)w, 3.0, 20.0);
- else
- glFrustum(-2.0 * (GLfloat)w / (GLfloat)h,
- 2.0 * (GLfloat)w / (GLfloat)h, -2.0, 2.0, 3.0, 20.0);
- glMatrixMode(GL_MODELVIEW);
- }
- // timer callback
- void update(int v)
- {
- int i;
- for (i = 0; i < nCubos; i++)
- updateCubo(aCubos[i], v);
- glutPostRedisplay();
- glutTimerFunc(v, update, v);
- }
- void selectCubo(int i)
- {
- printf("Cubo %i seleccionado!!!\n", i);
- if (i <= 0 || i > nCubos) return;
- unselect(cubo);
- cubo = aCubos[i - 1];
- select(cubo);
- }
- void teclas(unsigned char key, int x, int y)
- {
- switch (key) {
- case 'q':
- case 'Q':
- exit(0);
- break;
- }
- selectCubo(key - '0');
- glutPostRedisplay();
- }
- void rato(GLint button, GLint state, GLint x, GLint y)
- {
- xRato = x;
- yRato = y;
- }
- // mouse motion callback
- void moveRatoPress(int x, int y)
- {
- alfaLongitude += (x - xRato) * angRato;
- alfaLatitude -= (y - yRato) * angRato;
- xRato = x;
- yRato = y;
- if (alfaLongitude >= 360) alfaLongitude == 360;
- if (alfaLongitude < 0) alfaLongitude == 360;
- if (alfaLatitude >= 360) alfaLatitude == 360;
- if (alfaLatitude < 0) alfaLatitude == 360;
- printf("R(Lon,Lat)=(%6.2f,%6.2f)\n", alfaLongitude, alfaLatitude);
- glutPostRedisplay();
- }
- void VerificaLimites() {
- if (GLUT_KEY_UP) {
- if (cubo->yTab == TAB_SIZE )
- cubo->yTab -= 1;
- }
- if (GLUT_KEY_DOWN) {
- if (cubo->yTab == -1)
- cubo->yTab += 1;
- }
- if (GLUT_KEY_LEFT) {
- if (cubo->xTab == -1)
- cubo->xTab += 1;
- }
- if (GLUT_KEY_RIGHT) {
- if (cubo->xTab == TAB_SIZE)
- cubo->xTab -= 1;
- }
- }
- void teclasEspeciais(int key, int x, int y)
- {
- switch (key) {
- case GLUT_KEY_UP:
- cubo->yTab += 1;
- if (cubo->xTab == 4 && cubo->yTab == 3 || cubo->xTab == 3 && cubo->yTab == 3 || cubo->xTab == 2 && cubo->yTab == 3)
- cubo->yTab -= 1;
- VerificaLimites();
- break;
- case GLUT_KEY_DOWN:
- cubo->yTab -= 1;
- if (cubo->xTab == 4 && cubo->yTab == 3 || cubo->xTab == 3 && cubo->yTab == 3 || cubo->xTab == 2 && cubo->yTab == 3)
- cubo->yTab += 1;
- VerificaLimites();
- break;
- case GLUT_KEY_LEFT:
- cubo->xTab -= 1;
- if (cubo->xTab == 4 && cubo->yTab == 3)
- cubo->xTab += 1;
- VerificaLimites();
- break;
- case GLUT_KEY_RIGHT:
- cubo->xTab += 1;
- if (cubo->xTab == 2 && cubo->yTab == 3)
- cubo->xTab -= 1;
- VerificaLimites();
- break;
- }
- glutPostRedisplay();
- }
- void myInit()
- {
- int i;
- // Para que as linhas sejam bem desenhadas à volta dos cubos
- glPolygonOffset(1.0, 1.0);
- glEnable(GL_POLYGON_OFFSET_FILL);
- srand(time(0));
- // Cria cubos em posições aleatórias.
- aCubos = (Cubo*)malloc(sizeof(Cubo) * nCubos);
- for (i = 0; i < nCubos; i++) {
- aCubos[i] = criaCubo(rand() % TAB_SIZE, rand() % TAB_SIZE, 0.8);
- aCubos[i]->r = ((float)rand()) / RAND_MAX;
- aCubos[i]->g = ((float)rand()) / RAND_MAX;
- aCubos[i]->b = ((float)rand()) / RAND_MAX;
- }
- cubo = aCubos[0]; // o primeiro cubo é o selecionado
- select(cubo);
- }
- void main(int argc, char** argv)
- {
- glutInit(&argc, argv);
- /* need both double buffering and z buffer */
- glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
- glutInitWindowSize(500, 500);
- glutCreateWindow("TP2");
- myInit();
- glutReshapeFunc(myReshape);
- glutDisplayFunc(display);
- glutMouseFunc(rato);
- glutMotionFunc(moveRatoPress);
- glutKeyboardFunc(teclas);
- glutSpecialFunc(teclasEspeciais);
- glEnable(GL_DEPTH_TEST); /* Enable hidden--surface--removal */
- glutTimerFunc(timeUpdate, update, timeUpdate);
- glutMainLoop();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement