Programação com OpenGL/Modern OpenGL Tutorial 04: diferenças entre revisões

Origem: Wikilivros, livros abertos por um mundo aberto.
[edição não verificada][edição não verificada]
Conteúdo apagado Conteúdo adicionado
Linha 96: Linha 96:


== Passando para matriz de transformação ==
== Passando para matriz de transformação ==

== Experimentando ==

Revisão das 20h53min de 9 de maio de 2013

Neste tutorial nśo vamos mergulhar no mundo da transformação de matrizes, assim nós poderemos movimentar, rotacionar e mudar a escala do nosso triangulo.

Configurando as matrizes

Predefinição:Wikibook Aqui estão algumas dicas para se lembrar quando se trabalha com matrizes:

  • Transformações são aplicados pela multiplicação de matrizes 4X4 na ordem inversa. O M = M_translation * M_rotation diz para rodar primeiro, e depois movimentar.
  • A Matriz é a matriz de identidade que não faz nada - absolutamente nenhuma movimentação.
  • Para transformar um vertex, nós multiplicaremos ele pela matriz: v' = M * v
  • As matrizes 4x4 pode ser aplicadas somente para vetores 4X1, que obtemos usando uma das quatro dimensões da vertice: (x, y, z, 1).

Para estas multiplicações, nós vamos precisar de bibliotecas aritmética(math). os Shader já possuem inclusas, um facil suporte para operações de matrizes, mas nós precisaremos manipular-las na linguaguem C. é também mais eficiente, porque os shaders são executados em cada vertice, então é melhor cacularmos as matrizes de antemão.

Neste tutorial nós usaremos OpenGL Mathematics A biblioteca GLM, que esta escrita em C++. A GLM usa algumas convenções da GLSL, e então será facil nós começarmos. Esta documentação tambem mostrar substitutos para a defassada OpenGL 1.x e funções da GLU, como o glRotate, glFrustum ou gluLookAt, que vem a calhar se você já usou eles.

Existem alternativas, como libSIMDx86 (que também trabalham em processador que não são da familia x86). você pode também escrever seus próprio códigos de matrizes, desde que não seja muito grande, veja o exemplo mesa-demos-8.0.1/src/egl/opengles2/tri.c no demos que vem no Mesa3D.

Nota: a partir de agora usaremos C++, vamos precisar mudar nosso programa para C++ - desculpe por isto, vamos então editar nosso primeiro tutorial para iniciarmos. Na verdade você só precisa mudar o nome triangle.c para triangle.cpp

O GLM é uma biblioteca header-only, então você não precisa modificar o Makefile, contando que os header esteja configurado no standard path. Para instalar o GLM no Debian ou no Ubuntu:

apt-get install libglm-dev

Agora nós podemos adicionar os cabeçalhos da GLM:

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

Usando 3D Points

Nossa matriz de transformação são para vertices em 3D. Mesmo que nós estejamos em 2D, vamos descrever nosso triângulo com um ponto 3D com Z = 0. de qualquer maneiro vamos mudar nosso objeto para 3D no próximo tutorial :)

Vamos definir ele (3 elementos por verticés) para OpenGL no triangle.cpp:

struct attributes {
  GLfloat coord3d[3];
  GLfloat v_color[3];
};

Agora, no init_resources()

  struct attributes triangle_attributes[] = {
    {{ 0.0,  0.8, 0.0}, {1.0, 1.0, 0.0}},
    {{-0.8, -0.8, 0.0}, {0.0, 0.0, 1.0}},
    {{ 0.8, -0.8, 0.0}, {1.0, 0.0, 0.0}}
  };

...

  attribute_name = "coord3d";
  attribute_coord3d = glGetAttribLocation(program, attribute_name);
  if (attribute_coord3d == -1) {
    fprintf(stderr, "Could not bind attribute %s\n", attribute_name);
    return 0;
  }

Mudaremos a configuração do array de vértices em onDisplay()

  glVertexAttribPointer(
    attribute_coord3d,   // atributo
    3,                   // numero de elementos por vértice, que é (x,y,z)
    GL_FLOAT,            // o tipo de elemento
    GL_FALSE,            // o valor que ele está
    sizeof(struct attributes),  // o próximo coord3d aparecerá a cada 6 flots.
    0                    // deslocamento do primeiro elemento.
  );

substitua as outras ocorrências de 'attribute_coord2d' correspondente e chame o shader usando a nova coordenada.

attribute vec3 coord3d;
[...]
void main(void) {
  gl_Position = vec4(coord3d, 1.0);

Criando uma matriz de transformação

No GLM vem inclusivo funções para calcular rotações, movimentação e escalas das matrizes. Vamos colocar nossa matriz de transformação em onIdle(), que calculará uma rotação progressiva combinado com movimentos:

void onIdle() {
  float move = sinf(glutGet(GLUT_ELAPSED_TIME) / 1000.0 * (2*3.14) / 5); // -1<->+1 a cada 5 segundos
  float angle = glutGet(GLUT_ELAPSED_TIME) / 1000.0 * 45;  // 45° por segundo
  glm::vec3 axis_z(0, 0, 1);
  glm::mat4 m_transform = glm::translate(glm::mat4(1.0f), glm::vec3(move, 0.0, 0.0))
    * glm::rotate(glm::mat4(1.0f), angle, axis_z);
  [...]

Passando para matriz de transformação

Experimentando