Skip to content

Instantly share code, notes, and snippets.

@ynurmahomed
Created August 14, 2013 19:21
Show Gist options
  • Save ynurmahomed/6234561 to your computer and use it in GitHub Desktop.
Save ynurmahomed/6234561 to your computer and use it in GitHub Desktop.
Programa openGL que desenha um diamante
#include <GL/glut.h>
#include <math.h>
#include <stdio.h>
#define WINDOW_WIDTH 1080
#define WINDOW_HEIGHT 520
GLfloat angle, fAspect;
// Angulo de rotação da camera
GLdouble alfa = 0.02;
GLdouble eyeX = 0.0;
GLdouble eyeY = 80.0;
GLdouble eyeZ = 200.0;
GLdouble upY = 1;
// Retorna um vetor unitário
GLfloat* normaliza (GLfloat x, GLfloat y, GLfloat z) {
GLfloat *v = (GLfloat*) malloc(3 * sizeof(GLfloat));
float comp = sqrt((x * x) + (y * y) + (z * z));
v[0] = x / comp;
v[1] = y / comp;
v[2] = z / comp;
return v;
}
GLfloat* determinante (GLfloat* v1, GLfloat *v2) {
GLfloat *v1xv2 = (GLfloat*) malloc(sizeof(GLfloat));
v1xv2[0] = v1[1] * v2[2] - v1[2] * v2[1];
v1xv2[1] = -(v1[0] * v2[2] - v1[2] * v2[0]);
v1xv2[2] = v1[0] * v2[1] - v1[2] * v2[0];
return v1xv2;
}
void Desenha (void) {
GLfloat TOPO = 40.0, PI = 3.14159, x1, x2, x3, x4, z1, z2, z3, z4, y1, y2, y3, y4, teta1, teta2;
GLfloat r1 = 40, r2 = r1 + 10;
GLfloat *v1, *v2, *d;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor4f(0.1f, 0.1f, 0.4f, 0.7f);
// Desenha o octógono do topo
glBegin(GL_TRIANGLE_FAN);
glNormal3f(0.0, 1.0, 0.0); // Normal da face
for (int i = 0; i < 8; ++i) {
teta1 = i * 2.0 * PI / 8.0; // radianos
x1 = r1 * cos(teta1);
z1 = r1 * sin(teta1);
glVertex3f(x1, TOPO, z1);
}
glEnd();
// Desenha a segunda secção
// teta2 é o angulo em radianos do circulo de baixo dos triangle_strip
// teta1 é o angulo em radianos do cirvulo de cima dos triagle_strip
glBegin(GL_TRIANGLE_STRIP);
// A cada iteração são desenhados 4 pontos, formando 2 triangulos
// 9 iterações para tapar o vazio criado na primeira
for (int i = 0; i < 9; ++i) {
teta2 = (2 * i) * 2.0 * PI / 16.0; // radianos
x1 = r2 * cos(teta2);
y1 = TOPO - 10;
z1 = r2 * sin(teta2);
teta1 = i * 2.0 * PI / 8.0; // radianos
x2 = r1 * cos(teta1);
y2 = TOPO;
z2 = r1 * sin(teta1);
teta2 = (2 * i + 1) * 2.0 * PI / 16.0; // radianos
x3 = r2 * cos(teta2);
y3 = TOPO - 10;
z3 = r2 * sin(teta2);
teta1 = (i + 1) * 2.0 * PI / 8.0; // radianos
x4 = r1 * cos(teta1);
y4 = TOPO;
z4 = r1 * sin(teta1);
glVertex3f(x1, y1, z1);
// Determina a normal do primeiro triangulo
v1 = normaliza(x2 - x1, y2 - y1, z2 - z1);
v2 = normaliza(x3 - x1, y3 - y1, z3 - z1);
d = determinante(v1, v2);
glNormal3fv(d);
glVertex3f(x2, y2, z2);
glVertex3f(x3, y3, z3);
// Determina a normal do segundo triangulo
v1 = normaliza(x3 - x2, y3 - y2, z3 - z2);
v2 = normaliza(x4 - x2, y4 - y2, z4 - z2);
d = determinante(v1, v2);
glNormal3fv(d);
glVertex3f(x4, y4, z4);
}
glEnd();
// Desenha a segunda secção
glBegin(GL_TRIANGLES);
x1 = 0.0; y1 = TOPO - 80; z1 = 0.0;
glNormal3f(0.0, -1.0, 0.0);
for (int i = 0; i < 17; i += 1) {
teta2 = i * 2.0 * PI / 16.0;
x2 = r2 * cos(teta2);
y2 = TOPO - 10;
z2 = r2 * sin(teta2);
teta2 = (i + 1) * 2.0 * PI / 16.0;
x3 = r2 * cos(teta2);
y3 = TOPO - 10;
z3 = r2 * sin(teta2);
v1 = normaliza(x2 - x1, y2 - y1, z2 - z1);
v2 = normaliza(x3 - x1, y3 - y1, z3 - z1);
glNormal3fv(determinante(v1, v2));
glVertex3f(x1, y1, z1);
glVertex3f(x2, y2, z2);
glVertex3f(x3, y3, z3);
}
glEnd();
free(d);
free(v1);
free(v2);
glutSwapBuffers();
}
// Inicializa parâmetros de rendering
void Inicializa (void) {
GLfloat luzAmbiente[4]={0.7, 0.7, 0.7, 1.0};
GLfloat luzDifusa[4]={1.0,1.0,0.7,1.0}; // "cor"
GLfloat luzEspecular[4]={1.0, 0.0, 0.0, 1.0};// "brilho"
GLfloat posicaoLuz[4]={0.0, -40.0, 0.0, 1.0};
// Capacidade de brilho do material
GLfloat especularidade[4]={1.0,1.0,1.0,1.0};
GLint especMaterial = 1;
// Especifica que a cor de fundo da janela será preta
glClearColor(0.02f, 0.0f, 0.0f, 1.0f);
// Habilita o modelo de colorização de Gouraud
glShadeModel(GL_SMOOTH);
// Define a refletância do material
glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR, especularidade);
// Define a concentração do brilho
glMateriali(GL_FRONT_AND_BACK,GL_SHININESS,especMaterial);
// Ativa o uso da luz ambiente
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, luzAmbiente);
// Define os parâmetros da luz de número 0
glLightfv(GL_LIGHT0, GL_AMBIENT, luzAmbiente);
glLightfv(GL_LIGHT0, GL_DIFFUSE, luzDifusa );
glLightfv(GL_LIGHT0, GL_SPECULAR, luzEspecular );
glLightfv(GL_LIGHT0, GL_POSITION, posicaoLuz );
// Spot
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 90.0);
GLfloat spot_direction[] = { 0.0, 1.0, 0.0 };
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spot_direction);
// Habilita a definição da cor do material a partir da cor
// corrente
glEnable(GL_COLOR_MATERIAL);
//Habilita o uso de iluminação
glEnable(GL_LIGHTING);
// Habilita a luz de número 0
glEnable(GL_LIGHT0);
// Habilita o depth-buffering
glEnable(GL_DEPTH_TEST);
angle=45;
// para transparencia
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
// Função usada para especificar o volume de visualização
void EspecificaParametrosVisualizacao(void) {
// Especifica sistema de coordenadas de projeção
glMatrixMode(GL_PROJECTION);
// Inicializa sistema de coordenadas de projeção
glLoadIdentity();
// Especifica a projeção perspectiva
gluPerspective(angle,fAspect,0.4,500);
// Especifica sistema de coordenadas do modelo
glMatrixMode(GL_MODELVIEW);
// Inicializa sistema de coordenadas do modelo
glLoadIdentity();
// Especifica posição do observador e do alvo
gluLookAt(eyeX, eyeY, eyeZ, 0,0,0, 0,upY,0);
}
// Função callback chamada quando o tamanho da janela é alterado
void AlteraTamanhoJanela(GLsizei w, GLsizei h) {
// Para previnir uma divisão por zero
if ( h == 0 ) h = 1;
// Especifica o tamanho da viewport
glViewport(0, 0, w, h);
// Calcula a correção de aspecto
fAspect = (GLfloat)w/(GLfloat)h;
EspecificaParametrosVisualizacao();
}
// Função callback chamada para gerenciar eventos do mouse
void GerenciaMouse(int button, int state, int x, int y) {
if (button == GLUT_LEFT_BUTTON)
if (state == GLUT_DOWN) { // Zoom-in
if (angle >= 10) angle -= 5;
}
if (button == GLUT_RIGHT_BUTTON)
if (state == GLUT_DOWN) { // Zoom-out
if (angle <= 130) angle += 5;
}
EspecificaParametrosVisualizacao();
glutPostRedisplay();
}
void GerenciaTeclado (int key, int x, int y) {
switch (key) {
// rotação da camera sobre o eixoY no sentido anti-horário
case GLUT_KEY_RIGHT:
eyeX = eyeZ * sin(alfa) + eyeX * cos(alfa);
// eyeY = eyeY :)
eyeZ = eyeZ * cos(alfa) - eyeX * sin(alfa);
EspecificaParametrosVisualizacao();
break;
// rotação da camera sobre o eixoY no sentido horário
case GLUT_KEY_LEFT:
eyeX = eyeZ * sin(-alfa) + eyeX * cos(-alfa);
eyeZ = eyeZ * cos(-alfa) - eyeX * sin(-alfa);
EspecificaParametrosVisualizacao();
break;
// rotação da camera sobre o eixoX no sentido horário
case GLUT_KEY_UP:
eyeY = eyeY * cos(-alfa) - eyeZ * sin(-alfa);
eyeZ = eyeY * sin(-alfa) + eyeZ * cos(-alfa);
if ((int)eyeZ < 0)
upY = -1;
else
upY = 1;
EspecificaParametrosVisualizacao();
break;
// rotação da camera sobre o eixoX no sentido anti-horário
case GLUT_KEY_DOWN:
eyeY = eyeY * cos(alfa) - eyeZ * sin(alfa);
eyeZ = eyeY * sin(alfa) + eyeZ * cos(alfa);
if ((int)eyeZ < 0)
upY = -1;
else
upY = 1;
EspecificaParametrosVisualizacao();
break;
}
glutPostRedisplay();
}
// Programa Principal
int main(int argc, char *argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(WINDOW_WIDTH,WINDOW_HEIGHT);
glutInitWindowPosition((glutGet(GLUT_SCREEN_WIDTH)-WINDOW_WIDTH)/2,(glutGet(GLUT_SCREEN_HEIGHT)-WINDOW_HEIGHT)/2);
glutCreateWindow("Visualizacao 3D");
glutDisplayFunc(Desenha);
glutReshapeFunc(AlteraTamanhoJanela);
glutMouseFunc(GerenciaMouse);
glutSpecialFunc(GerenciaTeclado);
Inicializa();
glutMainLoop();
}
// gcc -Wall diamante.c -std=c99 -o diamante -lm -lGLU -lGL -lglut
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment