Академический Документы
Профессиональный Документы
Культура Документы
Tpicos do Curso
C++, Algoritmos e Estruturas de Dados (36) Computao Grfica (36) Programao Distribuda (6) Fsica (6) Inteligncia Artificial (6) Fundamentos de Programao de Jogos (6) Projeto Final (24)
Variveis, Ponteiros, Referncia, Alocao e Liberao de Memria Testes de condies Loops Funes Mdulos, Compilao e Link-Edio Orientao a Objetos Classes e Structs Encapsulamento, Herana e Polimorfismo Construtores e Destrutores Excees Funes e Variveis estticas Recurso Lista Encadeada, Fila e Pilha rvore Binria Grafo Hashtable Templates Operator Overloading Lendo e Gravando Arquivos Multithreading
Variveis
Ponteiros
Variveis de referncia
Referncias servem como um segundo nome para um objeto. Elas permitem acesso indireto de forma semelhante a ponteiros.
Alocao de Memria
Liberando memria
Vetores
Vetores so agregaes de elementos de um mesmo tipo que ocupam a memria de forma sequencial e adjacente.
Vetores
Uma varivel vetor armazena na realidade o endereo de memria do primeiro elemento do vetor.
Vetores
Testes de Condies
Testes de Condies
Loops
Loops
Exerccio
Crie um programa que gera um buffer de inteiros de 10 posies. Cujos valores sofrem um decremento de 10 at 1. Adicione um trecho de cdigo que busca pelo numero 4 no vetor e salva o endereo da posio do vetor em um ponteiro.
Exerccio
Crie um programa que crie uma matriz 4x4 identidade usando um buffer bidimensional.
Funes
Funes so subprogramas que realizam operaes definidas por usurios. Ferramenta fundamental para reduo de complexidade e reuso de cdigo. Em qualquer projeto, funes sero utilizadas sem que se conhea suas implementaes internas.
Funes
Exerccio
Crie uma funo que adiciona dois vetores de 4 elementos e retorna o resultado em um terceiro vetor
Mdulos permitem a diviso de um sistema em diferentes partes, cada uma responsvel por uma tarefa especfica. Um mdulo para ns ser definido como um .h e um .cpp. O arquivo .h possui declaraes. O arquivo .cpp possui implementaes.
Exemplo de um modulo
Vector3.h
Vector3.cpp
Usando um mdulo
Usando Mdulos
Compilao
Ao compilar um arquivo de implementao .cpp gerado um arquivo .obj com cdigo binrio e tabelas com referncias externas ainda no resolvidas e smbolos pblicos.
Link-Edio
A link edio resolve referncias externas e junta todo o cdigo em um s cdigo binrio gerando assim o arquivo executvel.
Exerccio
Implemente um mdulo Vector4.h e Vector4.cpp que possui as funes de adio, subtrao e multiplicao de vetores de 4 elementos e salvando o resultado em um outro vetor. Crie um arquivo .cpp com a main e inclua o header do Vector4.h. Compile ambos arquivos .cpp e gere o executvel.
Orientao a Objeto
Um objeto uma entidade(podendo se basear em algo concreto ou abstrato) que possui um comportamento ou representa algo. Voc interage com um objeto atravs de uma interface formada por funes. Isso permite uma interao bem comportada. A diviso de um sistema em objetos permite uma enorme reduo em complexidade e aumento em reusabilidade.
Classes
Encapsulamento
Apenas os membros pblicos de uma funo podem ser acessados por outros objetos.
Encapsulamento
Fundamental para reduo de complexidade. Voc chama um mtodo de uma classe e um problema resolvido para voc. No h necessidade de saber como o problema foi resolvido. Permite interao comportada. Como voc controla o acesso s variveis atravs de funes no possvel partes externas do programa agirem de forma errada com suas variveis.
Exerccio
Implemente a classe AIManager. Essa classe possui duas funes. AddObject e Think. A funo AddObject recebe uma string com um nome, uma posio x e uma posio y. A funo Think mostra na tela os objetos adicionados.
Herana
Certos objetos compartilham caractersticas porm possuem particularidades suficientes de forma que precisam de novos objetos para serem apropriadamente representados.
Herana
Herana
O objeto Person e o objeto Stone so ambos objetos de cena que podem ser desenhados na tela. Ento ambos podem pertencer mesma classe de objetos SceneObject. Se por exemplo um SceneObject possuir uma posio 3d. Tanto Person quanto Stone possuiro essa varivel de posio pois a posio uma varivel que existe em todo objeto da classe SceneObject.
Herana
Exerccio
Reimplemente o exerccio anterior fazendo o AIManager ter funes para adicionar Dragon e Orc que so classes derivadas de AIEntity. A classe AIEntity possui membros pblicos para armazenar um nome e uma posio x e y. A classe Dragon tem uma string com o tipo de baforada do drago e a classe Orc possui um inteiro que indica a arma sendo usada. Implemente a funo Think para tratar dos tipos especficos e desenhar suas partes especficas.
Polimorfismo
Quando um conjunto de classes deriva de uma mesma classe base, todo o conjunto compartilha uma interface. possvel escrever partes de cdigo levando em considerao apenas classes base de determinados objetos. Isso vantajoso para aumentar o reso no cdigo.
Polimorfismo
Polimorfismo
Exerccio
Reimplemente o AIManager para receber objetos AIEntity. Crie uma funo virtual pura em AIEntity chamada Think que imprime os dados da entidade. Faa a classe Orc e Dragon implementarem a funo Think. Mude o AIManager para fazer uso das funes Think dos objetos.
Construtores e Destrutores
Construtores so mtodos de uma classe chamada para construir a classe. Todo objeto criado tem seu construtor chamado.
Construtores e Destrutores
Construtores e Destrutores
Destrutores fazem o trabalho inverso dos construtores. Eles fazem a destruio do objeto, liberando recursos adquiridos como memria alocada, arquivos abertos, etc.
Construtores e Destrutores
Em classes base use destrutores virtuais. Ao deletar um objeto usando um ponteiro base o comportamento indefinido caso o destrutor da classe base no seja virtual.
Excees
Eventos anormais so normais. Programas executam normalmente at que algum problema ocorra como falta de memria, acesso uma rea de memria ilegal, etc etc etc etc etc etc etc etc etc etc..... possvel testar esses problemas ou excees usando ifs ou fazendo uso de ferramentas de C++ criadas especficamente para tratar de excees.
Excees
Ao detectar uma anomalia, voc gera uma exceo atravs da operao throw.
Excees
Excees
Exerccio
Implemente uma classe chamada Buffer que cria um buffer de ints. A classe possui um construtor que recebe o nmero de elementos, e um destrutor que destroi os elementos. A classe possui tambm um funo Add que recebe um vetor de ints pra adicionar ao buffer e uma funo Remove que recebe n e remove n elementos de buffer. Jogue excees caso sejam adicionados mais elementos do que o Buffer suporta ou sejam removidos mais elementos do que existem no buffer.
Apesar de todo o perigo, s vezes acesso informaes globais necessrio e at simplifica designs. Todos os objetos com um membro esttico compartilham a mesma instncia desse membro. Ou seja, se um objeto altera a varivel esttica, isso ser visvel por todos os outros objetos da mesma classe.
Exerccio
Implemente uma classe que possui internamente uma varivel esttica ponteiro do tipo da prpria classe. Inicialize essa varivel para NULL Implemente uma funo esttica da classe chamada GetInstance que retorna a varivel quando o ponteiro diferente de NULL, se o ponteiro for NULL alocada memria para a varivel e seu endereo armazenado no ponteiro.
Recurso
A recurso uma forma de solucionar certos problemas que envolve fazer uma funo chamar a si mesma para resolver o problema.
Exemplo
Exerccio
Implemente uma funo recursiva que busque em um vetor de inteiros ordenado crescentemente por um determinado valor. A funo deve retornar o ndice do valor ou , -1 caso o valor no seja encontrado.
Busca Binria
Complexidade de Algoritmos
Complexidade no de difcil de entender ... de difcil de computar. nossa misso encontrar os algoritmos mais eficientes para resolver algum problema. Os algoritmos mais eficientes para resolver algum problema so chamados de algoritmos timos.
No pior caso, necessrio realizar n testes para achar (ou no) um valor. usada uma notao O(n) para representar o algoritmo busca linear. O(n) ~= se voc colocar n elementos como input, o custo da funo uma funo linear.
Teste 1 = n elementos Teste 2 = n / 2 elementos Teste 3 = n / 4 elementos Teste final quando voc tem 1 elemento. Dado n elementos, quantos testes so feitos? Temos que achar i quando n/2^i = 1. n/2^i = 1 -> n = 2^i log n = log 2^i Log n = i Complexidade = O(log n) Busca binria melhor que busca linear.
As vezes, no possvel saber o nmero mximo de elementos que sero adicionados uma classe. Quando isso acontece necessrio criar uma estrutura capaz de crescer de acordo com a necessidade. Lista Encadeada, Fila e Pilha so estruturas de dados fundamentais usadas em diversos algoritmos.
Lista Encadeada
A lista encadeada uma lista criada dinamicamente que se liga atravs de ponteiros.
Uma classe consiste na lista em si. A classe da lista usa outra classe que representa os ns da lista. Cada n armazena os dados e o ponteiro para o prximo n da lista. O ltimo n aponta para NULL. A classe da lista aponta para o primeiro elemento da lista.
Exerccio
Implemente uma lista encadeada cujos ns armazenam posies x,y e z em floats e possuem tambm um id inteiro. Crie um mtodo na classe para adicionar elementos no final da lista. Crie mtodo na classe para buscar um n dado um inteiro, o mtodo deve retornar as posies x, y e z. Crie um mtodo para imprimir toda a lista.
Lista Encadeada
Lista Encadeada
Fila
Implementada de maneira semelhante lista encadeada, porm elementos s podem ser inseridos no final e removidos na frente. Funciona em forma FIFO (First In First Out). Imagine uma fila de cinema!
Pilha
Tambm implementada de maneira parecida com a lista encadeada porm sua operao LIFO (Last In First Out). A pilha mantm um ponteiro para o seu topo. Quando se deseja adicionar um elemento realiza-se um push adicionando um elemento ao topo da lista, quando se deseja remover um elemento, faz-se um pop, removendo o elemento do topo.
Exerccio
Implemente uma pilha. A pilha possui um ponteiro chamado top que aponta para o topo da pilha. Crie o mtodo push que adiciona um elemento ao topo da pilha. Crie o mtodo pop que remove o elemento do topo da pilha. Crie o mtodo print para imprimir a pilha.
Estrutura de dados semelhante uma arvore invertida onde cada n possui at 2 filhos. Cada n possui um id, um ponteiro para o filho esquerdo e um ponteiro para o filho direito. Cada n possui a seguinte caracterstica, o filho a esquerda possui um id menor que o id do n e o filho a direita possui um id maior que o id do n.
A busca por um valor possui um custo O(h). Se a rvore estiver desbalanceada isso pode representar O(n) Se a rvore estiver balanceada isso pode representar O(log n) Uma rvore balanceada uma rvore em que para todo n, suas subrvores esquerda e direita diferem no mximo em 1 na altura. Considere uma subrvore vazia como de altura -1. Folha um n sem filhos.
Atravs de uma rvore balanceada possvel achar uma rvore perfeita de mesma altura. rvore perfeita uma rvore em que todas as folhas possuem a mesma altura e todos os ns possuem 2 ou 0 filhos. Nmero de elementos da rvore completa = Somatrio(2^i, i varia de 0 at a altura). n = 1 * (2^(h+1) 1) / 2 1 (somatrio de progresso geomtrica) n = 2^(h+1) 1 n + 1 = 2^(h+1) log(n+1) = h + 1 log(n+1) 1 = h Logo a altura de uma rvore balanceada um logaritmo de n ... O que muito bom!!!!
Exerccio
Implemente uma rvore binria onde os ns possuem um id inteiro e armazenam um valor inteiro. Implemente o mtodo de busca por um id. Implemente o mtodo de busca pelo maior elemento. Implemente o mtodo de adio de elementos. Implemente o mtodo que desenha na tela os valores dos ns de maneira ordenada crescentemente por id.
Grafo
Grafos so uma estrutura de dados onde um n pode apontar para um nmero qualquer de outros ns. Grafos podem ser cclicos se possuirem referncias que faam um ciclo (como um filho apontando para um pai). Caso no existam referncias cclicas, o grafo definido acclico e se assemelha uma rvore nria, onde cada n possui n filhos.
Cada grafo possui um ponteiro para o pai e uma estrutura de dados(lista encadeada, vetor) que armazena os ponteiros para os filhos. Se assemelha a uma rvore n-ria.
Exerccio
Implemente um grafo acclico que armazena seus filhos em uma lista encadeada. Para isso implemente uma classe GraphNode que possui os mtodos AddChild e Print. Coloque os GraphNodes possuindo um inteiro internamente. AddChild adiciona um filho ao n. Print imprime os ns do grafo. Construa um grafo e o imprima.
Hash Table
uma estrutura de dados que permite acessos em O(1) .... Ou seja ... Muito rpidos. Para adicionar um elemento, utilizada uma chave que identifica o elemento. Atravs dessa chave, calculada a posio do elemento (essa posio geralmente um ndice de um vetor). A funo que pega essa chave e calcula uma posio chamada de funo de hash.
Para armazenar objetos usado um vetor onde cada elemento desse vetor um ponteiro para um objeto. A chave um inteiro. A posio calculada achando o resto da diviso da chave pelo tamanho do vetor de ponteiros. ( index = chave % tam_vec; ) Quando uma chave gerar uma posio que j contm um objeto, outra estrutura de dados utilizada para salvar os objetos (lista encadeada, arvore binria de busca, outra lista encadeada).
Exerccio
Implemente uma hash table com as mesmas caractersticas do exemplo anterior. Para salvar objetos na mesma posio do vetor de ponteiros utilize uma lista encadeada. Crie uma funo de insero que recebe a chave e o objeto e o salva na hash table. Crie uma funo de search que procura pelo objeto dada uma chave.
Template
Templates so como receitas para criar classes que recebem um ou mais tipos como parmetros. So teis para reaproveitar algoritmos em diferentes tipos de dados.
Template
Template
Toda vez que um template utilizado para um determinado tipo, criado o cdigo da classe para fazer uso daquele tipo. Ento no exemplo anterior, so criadas 2 classes com a mesma lgica porm s com os tipos int e float diferentes. Como as classes so geradas em tempo de compilao, necessrio saber a implementao de todos os mtodos de cada template. Se um template define seus mtodos em um .cpp, outras classes no sero capazes de ver essa implementao e criar as novas classes (voc provavelmente ter problemas de link-edio). Por esse motivo, geralmente os templates so criados completamente no .h (incluindo a implementao das funes).
Exerccio
Crie uma lista encadeada que consegue armazenar qualquer tipo usando um template.
Operator Overloading
Operadores como +, - , [] , == , etc, podem ter seu comportamento redefinido nas classes. Isso facilita a programao usando determinados tipos (ex: vetores 3d, strings).
Exerccio
Implemente uma classe String. Faa overload do operador = que recebe um vetor de caracteres e armazena na string. Faa overload do operador += que recebe um vetor de caracteres e adiciona os caracteres ao final da string. Faa overload do operador == que recebe um ponteiro para caracteres constantes (const char*)
Para ler ou gravar arquivos necessrio criar uma varivel ponteiro para FILE. preciso incluir o stdio.h. Para abrir um arquivo, usa-se a funo fopen da seguinte forma
O tipo de abertura de fopen pode definir diferentes formas de abertura do arquivo: r : abre o arquivo para leitura. w: abre o arquivo para escrita. Se o arquivo j existir, seu contedo destrudo. a: abre o arquivo permitindo a escrita ao final do arquivo. Esses tipos de abertura, abrem os arquivos como arquivos texto. Para abri-los como arquivos binrios, adicione b ao tipo de abertura.
Para a escrita de arquivos, usa-se a funo fwrite que possui o seguinte prottipo:
size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream)
Exerccio
Crie um programa que salve as seguintes informaes do jogador: Estgio atual Nome do personagem Nvel do Personagem Posio x, y e z do personagem E depois crie um outro programa que l esses dados e mostra na tela!
Multithreading
Multithreading permite a criao de trechos de cdigo que executam paralelamente. Se houver um nico processador na mquina, as threads concorrem pelo processador. O sistema operacional d um time slice para cada thread. Ao trmino do time slice, o SO interrompe a execuo da thread e coloca outra thread para processar.
Multithreading
Isso til em mquinas com mltiplos processadores por permitir processamento paralelo. til tambm quando existem operaes que podem bloquear e no desejvel que o sistema bloqueie por essas operaes (ex: bloqueio enquanto uma leitura de um arquivo grande realizada).
Multithreading
Multithreading
Multithreading
Variveis que so acessadas por diferentes threads correm o risco de se tornarem corrompidas. Imagine um programa onde existe uma lista de jogadores. Uma thread est adicionando um jogador na lista e outra thread est removendo outro jogador da lista. Pode acontecer da lista acabar com um dos jogadores apontando para lixo e at coisas piores. Por isso necessrio usar funes que permite acesso regies crticas.
Multithreading
Para proteger regies acessadas por mltiplas threads utilize CRITICAL_SECTION (inclua windows.h) Use a API InitializeCriticalSection, EnterCriticalSection, LeaveCriticalSection e DeleteCriticalSection para usar regies crticas.
Multithreading
Exerccio
Crie uma aplicao com 2 threads adicionais. 1 thread incrementa um contador e o imprime na tela 1 thread decrementa esse mesmo contador e o imprime na tela. Cada thread repete esse processo 50 vezes. A main thread fica em espera ocupada esperando as threads terminarem. No final ela imprime THE END. Faa testes usando critical sections e sem usar critical sections.
Aplicaes Win32 Pipeline grfico do Direct3D e Dispositivo Direct3D Buffer de Vrtices e ndices Effect Files, Vertex Shaders e Pixel Shaders com Cg Renderizando tringulos Matrizes e Transformaes Sistemas de Coordenadas e o Processo de Visualizao Renderizando tringulos com perspectiva Renderizando tringulos texturizados Produto Escalar Iluminao Renderizando Objetos com Iluminao por pixel Exportando e carregando modelos de arquivos .X (e renderizando!) Animao usando interpolao entre Key Frames Alpha Blending Volumes de Sombras Bump Mapping Grafos de Cena Culling em cenrios usando Octrees
Para criar uma aplicao Win32 preciso incluir o windows.h O processamento em aplicaes Win32 comea na WinMain.
hinstance um handle. Um handle simplesmente um nmero que identifica alguma coisa. hinstance um identificador da aplicao. Esse parmetro necessrio para alguma funes. hprevinstance um parmetro no mais utilizado e definido como 0. cmdline a linha de comando usada para rodar o programa. cmdshow indica como o programa deveria ser inicialmente mostrado.
Para criar a janela da aplicao preciso instanciar e preencher a struct WNDCLASS que possui a seguinte cara.
style: define propriedades da janela. CS_VREDRAW fazem com que a janela seja redesenhada caso haja uma mudana na altura da janela. lpfnWndProc: recebe a funo que trata os eventos enviados para a janela de sua aplicao. cbClsExtra: nmero de bytes extras para alocar para a windows class struct. cbWndExtra: nmero de bytes extras alm das instncia da janela. hInstance: handle da aplicao. hIcon: handle do cone usado. hCursor: handle do cursor usado. hbhBackground: handle do pincel usado para pintar o background da janela. lpszMenuName: um nome que identifica o recurso de menu usado na aplicao. lpszClassName: especifica o nome dessa classe de janela.
Aps criar a janela necessrio entrar no loop de captura e envio de mensagens. Nesse loop tambm so colocadas funes para executar o jogo.
Exerccio
Junte todo o cdigo mostrado e crie uma aplicao win32. Implemente a aplicao para mostrar a posio x e y do mouse quando o boto esquerdo pressionado. Quando a tecla pra cima pressionada mostrar tambm.
Dispositivo Direct3D
API Grfica do DirectX Permite acesso placas de acelerao grfica de maneira nica e independente do dispositivo.
Vertex Data: Dados geomtricos dos objetos 3D do cenrio. Por exemplo, as posies dos vrtices do objeto 3D. Fixed Function Pipeline: Uma sequncia de processamento fixa do Vertex Data. As alteraes nessa sequncia de processamento so pouco flexveis. Programable Pipeline: Se usado, permite a implementao de um programa que processa os vrtices. Permite muita mais flexibilidade de processamento dos vrtices.
Clipping: Esse estgio recorta todas as partes dos tringulos que esto para fora da tela.
Back Face Culling: Elimina os tringulos que esto de costas para a cmera. Esse estgio elimina tringulos no visveis em objetos fechados.
Pixel Shader: Se usado, permite ao programador criar um processamento que executa a cada pixel desenhado. Permite grande flexilidade sobre a forma como os pixels so renderizados. Texture Sampler: Esse estgio, se usado, captura amostras das textura para serem usadas no Pixel Shader.
Alpha Test: Esse estgio permite configurar a aceitao de um pixel de acordo com o seu alpha. Depth Test: Esse estgio permite configurar a aceitao de um pixel de acordo com a sua profundidade. Stencil Test: Esse estgio permite configurar a aceitao de um pixel de acordo com o Stencil Buffer.
Fogging: Esse estgio permite configurar fumaa na cena a medida que os objetos se distanciam. Alpha Blending: Esse estgio permite que o pixel sendo renderizado seja combinado com o pixel j desenhado no buffer de cor que ser apresentado na tela.
A geometria dos modelos e cenrios passa pelo pipeline do Direct3D e ao final gerada uma imagem 2D do objeto 3D, que mostrada na tela.
Integrao de Sistemas
Sistemas de Coordenadas
O objeto Direct3D
O dispositivo Direct3D
Objeto principal de renderizao. com esse objeto que passamos a geometria de modelos para a placa grfica.
Preencher D3DPRESENT_PARAMETERS
BackBufferWidth, BackBufferHeight: Largura e altura do Backbuffer. BackBufferFormat: Formato do backbuffer. BackBufferCount: Nmero de Backbuffers. MultiSampleType e MultiSampleQuality: Parmetros usados para antialiasing. SwapEffect: Maneira como o backbuffer vira o front buffer. hDeviceWindow: handle da janela Windowed: Se a aplicao vai rodar em janela ou full screen. EnableAutoDepthStencil: Permisso se o Direct3D pode gerenciar o seu buffer de depth e stencil. AutoDepthStencilFormat: O formato do buffer de depth e stencil. Flags: ... FullScreen_RefreshRateInHz: A taxa com que o monitor atualizado. PresentationInterval: A taxa com que o backbuffer pode ser apresentado na tela.
Adapter: nmero que identifica a placa grfica usada. DeviceType: O tipo de dispositivo a ser usado (Ex. HAL ou Ref). hFocusWindow: handle para a janela BehaviorFlags: flags pPresentationParameters: a estrutura PRESENT_PARAMETERS preenchida anteriormente. ppReturnedDeviceInterface: retorna o dispositivo Direct3D criado.
Criando um dispositivo
Exerccio
Crie um dispositivo Direct3D em 800x600 fullscreen. Experimente com outros tamanhos. Crie um dispositivo para verso Windowed. Para isso coloque Windowed = TRUE, e o fullscreen refresh rate = 0.
Cores
As cores no Direct3D so definidas geralmente pela combinao de vermelho, verde e azul. Um componente chamado alpha tambm usado eventualmente e representa o grau de transparncia da cor.
Cores
Em Direct3D, cores de vrtices so geralmente definidas como nmeros hexadecimais com o seguinte formato:
0xalpharedgreenblue
0x00ff0000 = vermelho puro 0x0000ff00 = verde puro 0x000000ff = azul puro 0x00000000 = preto 0x00ffffff = branco
Limpando Buffers
Toda vez que se deseja renderizar um frame, necessrio limpar os buffers de cor e profundidade. Caso o buffer de cor no seja limpo, partes das cenas de renderizaes passadas sero mostradas na tela, j que os backbuffers so reutilizados. Caso um jogo no entando sempre desenha na tela toda, no necessrio limpar esse buffer. O buffer de profundidade usado para desenhar corretamente os objetos 3D com relao distncia para a cmera. Basicamente esse buffer garante que objetos 3D que esto na frente de outros objetos, so renderizados corretamente na frente desses objetos. Esse buffer sempre precisa ser limpo a cada nova renderizao.
Limpando Buffers
Para limpar os buffers de cor e profundidade necessrio usar a funo Clear do dispositivo Direct3D.
Limpando Buffers
Count: Nmero de retngulos em pRects. pRects: Buffer de retngulos que especificam as regies que iro sofrer limpeza. Flags: flags que especificam os buffers que sero limpos. Color: cor usada para limpar o buffer de cor. Z: valor de profundidade usado para limpar o buffer de profundidade. Stencil: valor de stencil usado para limpar o buffer de stencil.
Limpando Buffers
Toda a renderizao por default feita no backbuffer. Aps a renderizao necessrio apresentar o backbuffer, fazendo seus dados serem copiados para o front buffer, que o buffer sendo mostrado na tela.
Para apresentar o back buffer deve ser usada a funo Present do dispositivo Direct3D.
pSourceRect: Um retngulo que define a parte que ser apresentada do Back Buffer. pDestRect: Um retngulo que define o local onde ser apresentado o back buffer. hDestWindowOverride: handle da janela onde ser apresentado o back buffer. pDirtyRegion: Define a regio que precisa ser atualizada.
Exerccio
Crie uma aplicao que limpa o buffer de cor para a cor vermelha (0x00ff0000).
Objetos 3D
Objetos 3D
Objetos 3D
Objetos 3D podem usar texturas(imagens) para dar detalhe seus tringulos. Coordenadas de textura podem ser usadas para aplicar imagens um objeto 3D.
Objetos 3D
Normais tambm podem ser usadas para clculos de iluminao por exemplo.
Objetos 3D (Resumo)
Posies dos vrtices ndices das faces Coordenadas de textura Normais dos vrtices
Objetos 3D so renderizados passando sua informao geomtrica para a placa grfica. A informao geomtrica dos objetos armazenada em VertexBuffers e IndexBuffers. Os vrtices dos objetos podem possuir variaes em seu contedo. Nos VertexBuffers ficam armazenadas informaes tipo posio x,y,z, coordenadas de textura u, v, normal, etc.
Length: tamanho do vertex buffer em bytes. Usage: Flags que indicam usos especiais. FVF: Flags que indicam o contedo do vertex buffer. Pool: Memria onde esse buffer ficar armazenado (Memria de Vdeo, AGP ou RAM normal). ppVertexBuffer: Retorna o vertex buffer. pSharedHandle: colocar NULL. (bacalhau M$)
Para carregar dados em um vertex buffer deve-se usar a funo Lock do vertex buffer. Aps carregar os dados, deve-se usar a funo Unlock.
OffsetToLock: Distncia do incio do vertex buffer onde o carregamento comear. SizeToLock: Tamanho da regio no vertex buffer onde os dados sero carregados. ppbData: Ponteiro retornado que aponta para o contedo do vertex buffer. Flags: ...
Vertex Buffers
Exerccio
Crie um vertex buffer e carregue dados x,y,z de um tringulo. Leia esses dados em outro buffer usando o mesmo vertex buffer.
As informaes de renderizao (x,y,z, u, v, ...) do objeto so armazenadas em vertex buffers. Esses buffers so colocados em uso atravs da funo SetStreamSource do dispositivo Direct3D. A funo DrawPrimitive faz as informaes dos buffers serem carregadas juntando a informao completa de um vrtice. Quem define como os vertex buffers so combinados formando um vrtice a declarao do vrtice ...
Para colocar em uso um vertex buffer, devese usar a funo SetStreamSource do dispositivo Direct3D.
StreamNumber: define o nmero do vertex buffer, comea em 0. pStreamData: o vertex buffer OffsetInBytes: a distncia em bytes no buffer onde comea a informao dos vrtices. Stride: A distncia entre cada componente do vertex buffer.
Exerccio
Coloque o vertex buffer criado no exerccio anterior para ser usado como o vertex buffer 0. Crie um vertex buffer para armazenar uma cor para cada um dos vrtices do tringulo. Use D3DCOLOR. Colocar esse vertex buffer com as cores como o vertex buffer 1.
Declaraes de Vrtices
Os vertex buffers podem conter diferentes informaes sobre o vrtice. A declarao do vrtice informa ao Direct3D como ele deve processar os vertex buffers usados para adquirir a informao de um vrtice. Declaraes de vrtices dizem coisas do tipo: O vertex buffer 0 tem a informao x,y,z do objeto, j o vertex buffer 1 tem a informao u,v do objeto.
Uma declarao de vrtices feita atravs da criao de um buffer onde cada elemento um D3DVERTEXELEMENT9.
Stream: o nmero do vertex buffer. Offset: a distncia no vertex buffer onde comea a informao. Type: O tipo de dado armazenado no buffer. Method: Define como o tesselator vai operar na informao do vertex buffer. Usage: Define o objetivo do uso do vertex buffer. UsageIndex: Dado adicional ao objetivo do vertex buffer.
Aps criar o buffer de D3DVERTEXELEMENT9, uma declarao criada chamando a funo CreateVertexDeclaration do dispositivo Direct3D.
Para usar uma declarao de vrtices usase a funo SetVertexDeclaration do dispositivo Direct3D.
Exerccio
Effect Files
Effect files so arquivos que estabelecem uma configurao do pipeline grfico para renderizar alguma coisa. Eles armazenam o vertex e o pixel shader.
Vertex Shader
responsvel pelo processamento dos vrtices. um programa que executa para cada vrtice passado para o pipeline. Recebe como parmetro as informaes dadas pelos vertex buffers. O pipeline espera obrigatoriamente pela posio do vrtice. Opcionalmente, possvel enviar outras informaes como coordenadas de textura e cores. Essas informaes sero interpoladas por toda a face do tringulo sendo desenhado.
Vertex Shader
Ao final do processamento do Vertex Shader, o vrtice passado para o estgio de clipping. O vrtice estar na tela, se estiver entre as coordenadas (-1, -1, 0, 1) e (1, 1, 1, 1). Se o vrtice estiver fora do volume mostrado na imagem, ele far com que o tringulo a que ele pertence seja clipado.
Vertex Shader
Vertex Shader
Dados de input:
POSITION: define que a varivel receber a informao de posio dos vertex buffers. TEXCOORD0: define que a varivel receber a informao de coordenadas de textura 0 do vertex buffers. POSITION: parmetro de retorno obrigatrio. Recebe uma posio no espao de clip homogneo. TEXCOORD0: recebe uma coordenada de textura que ser interpolada linearmente pela face do tringulo.
Dados de output:
Pixel Shader
Pixel Shader
Parmetros de input:
TEXCOORD0: coordenada de textura interpolada.[ COLOR: a cor final do pixel. (no exemplo estamos colocando a cor branca)
Parmetros de output:
pDevice: o dispositivo Direct3D pSrcFile: path do effect file pDefine: permite a definio de macros do arquivo de efeitos. pInclude: permite a definio de includes no arquivo de efeitos. Flags: ... pPool: Usado para permitir o uso compartilhado de parmetros em mltiplos efeitos. ppEffect: retorna o objeto efeito. ppCompilationErrors: retorna uma lista de erros de compilao do efeito.
Renderizando Tringulos
Renderizando Tringulos
PrimitiveType: Define o tipo de primitiva para renderizar. (lista de ponto, de linhas, de triangulos, etc ...) StartVertex: ndice do primeiro vrtice a ser carregado para renderizao. PrimitiveCount: nmero de primitivas a serem renderizadas.
Renderizando Tringulos
Antes de qualquer DrawPrimitive deve ser chamada a funo BeginScene do dispositivo Direct3D. Depois de todas as chamadas de DrawPrimitive deve ser chamada a EndScene do dispositivo Direct3D.
Definir os vertex buffers usados pelo objeto 3d. Definir a declarao de vrtice do objeto 3d. Com isso o Direct3D consegue entender a informao que existe dentro dos buffers. Renderizar o objeto 3d com a funo DrawPrimitive.
Renderizando tringulos
Exerccio
Use os vertex buffers e o vertex declaration dos exerccios anteriores e renderize um tringulo. Para isso necessrio alterar o vertex shader para receber um float4 color : COLOR0 e retornar tambm um COLOR0. Altere tambm o pixel shader para receber esse COLOR0 e coloc-lo na tela. Implemente um cdigo que mexe o tringulo em x e y baseado nas teclas recebidas.
Matrizes e Transformaes
Posicionar objetos 3D no mundo. Posicionar cmeras no mundo. Projetar o cenrio 3D em um plano permitindo a visualizao em monitores.
O que so matrizes?
Operaes Bsicas
Multiplicao No Comutativa
Vetores
Podem ser representados por matrizes 1xN ou Nx1. Consistem em uma entidade matemtica que possui direo e tamanho. Representado por uma linha com uma ponta de flecha.
Transformaes
Transformaes
So operaes realizadas em pontos que permitem at alterar o sistema de coordenadas do ponto. (Ex: um ponto 3D vira um ponto 2D).
Transformaes
Transformaes Simples
Transformaes Simples
Matriz Identidade
Matriz de Rotao 2D
Coordenadas Homogneas
Coordenadas homogneas permitem que translaes sejam realizadas com multiplicaes de matrizes. As coordenadas homogneas de um ponto de n dimenses possuem n+1 dimenses. A coordenada adicional um escalar que multiplica todas as outras coordenadas. (x,y,z) = (wx, wy, wz, w)
Coordenadas Homogneas
Adicionando Translao
O pipeline grfico pega a geometria dos objetos em 3D e cria uma imagem em 2D a partir dela. Para gerar uma imagem 2D de um cenrio 3D visto de um determinado ngulo necessrio fazer com que os vrtices de um objeto passem por vrios sistemas de coordenadas.
Quando um objeto est sendo modelado, seus vrtices em 3D so especificados com relao a alguma origem. Geralmente essa origem fica em alguma regio prxima ao objeto ou no centro do objeto.
Os vrtices do objeto no espao precisam ser transformados para que o objeto possa ser posicionado no mundo. Essa transformao quem permite posicionar um objeto em cima de uma mesa, ou dois orcs lado a lado. Isso se d atravs da matriz de mundo. Aps a transformao os vrtices esto no espao do mundo. Todas as transformaes so feitas baseadas em uma mesma origem de mundo, por isso elas permitem posicionar os objetos no mundo. A transformao que transforma uma posio do espao do objeto para o espao do mundo chamada de transformao de mundo.
Aps transformar os vrtices para o espao de mundo, eles devem ser transformado para o espao do olho. Isso se d com a matriz de viso. O espao do olho transforma o mundo de acordo com a posio e orientao da cmera. Ao final da transformao a cmera est na posio 0,0,0 olhando para +z. O mundo transformado de maneira que a cmera continue a ver o que ela deveria ver em sua posio original. Na imagem, mostrado como a cmera posicionada no OpenGL. Em Direct3D a cmera aponta para +z. No existe um objeto cmera que transformado. A posio e orientao da cmera so utilizadas apenas para transformar o mundo de maneira que a cmera fique na posio 0,0,0 e olhando para +z. Essa transformao faz esse reposicionamento do mundo para permitir que a prxima etapa de visualizao acontea de maneira rpida e eficiente.
Aps os vrtices serem reposicionados levando em considerao a cmera, hora de projet-los na tela. Os vrtices so transformados pela matriz de projeo. Aps a transformao eles esto num espao chamado espao de clipping homogneo que permite o pipeline grfico executar o algoritmo de clipping que remove as partes das primitivas que no so visveis.
Aps o clipping os vrtices tm seu x,y e z divididos por w, o que os deixa no espao normalizado de dispositivo.
A ltima transformao a transformao de viewport. Essa transformao quem coloca os vrtices na posio correta na tela e permite que os tringulos sejam rasterizados.
Transformaes principais
Matrizes de Mundo
Essas matrizes variam dependendo da forma como se deseja posicionar os objetos no mundo.
Matrizes de Viso
Matrizes de Projeo
Aps as matrizes de mundo, viso e projeo serem definidas, preciso multiplic-las na ordem World * View * Proj e depois passar a matriz resultando para o vertex shader. No vertex shader, a matriz tem que ser usada para multiplicar as posies dos vrtices.
Exerccio
Renderize 3 tringulos, um atrs do outro. Utilize 1 nico vertex buffer para os 3 tringulos. (Dica: Use uma matriz de mundo para cada tringulo). Posicione a cmera em um ngulo que permita ver os 3 tringulos Trate o input do teclado e faa a cmera se mover.
Exerccio
1 tringulo rotaciona no eixo y fixo na posio 0, 0, 0 1 tringulo rotaciona no eixo y fixo na posio 10, 0, 0. 1 tringulo rotaciona no eixo y na posio 20, 0, 0
Texturas so um dos principais elementos que do realismo um cenrio 3D. Texturas so imagens que so colocadas nos modelos 3d que do detalhes aos modelos.
Temos que definir as coordenadas de textura, carregar o vertex buffer e definir o vertex declaration.
Exerccio
Coloque os tringulos do exerccio anterior usando texturas. Use texturas diferentes para cada tringulo.
Produto Escalar
Vamos achar o tamanho de b, usando os lados a e c e o ngulo entre a e c? a^2 = h^2 + c1^2 .... b^2 = h^2 + c2^2 ... h^2 = a^2 c1^2 b^2 = a^2 c1^2 + c2^2 .... c = c1 + c2 b^2 = a^2 c1^2 + (c-c1)^2 b^2 = a^2 c1^2 + c^2 2cc1 + c1^2 ... cos theta = c1/a b^2 = a^2 + c^2 2cc1 ... b^2 = a^2 + c^2 2ca cos theta
A frmula achada a lei dos cosenos. Ela permite achar o tamanho de b usando os lados a e c e o ngulo entre eles. b^2 = a^2 + c^2 2*a*c*cos(ab)
Usando vetores
|b-a|^2 = |a|^2 + |b|^2 2*|a|*|b|*cos (ab) |b-a|^2 - |a|^2 - |b|^2 = -2*|a|*|b|*cos(ab) (bx-ax)^2 + (by-ay)^2 + (bz-az)^2 ax^2 ay^2 az^2 bx^2 by^2 bz^2 bx^2 2bxax + ax2 + by^2 2byay + ay^2 + bz^2 2bzaz + az^2 - ... -2bxax - 2byay 2bzaz = -2*|a|*|b|*cos(ab) axbx + ayby + azbz = |a|*|b|*cos(ab) Produto escalar: a * b = axbx + ayby + azbz. Ou seja, o produto escalar entre 2 vetores calcula uma informao de ngulo entre os vetores. Se os 2 vetores tiverem tamanho 1, o produto escalar d o coseno entre os vetores.
O que acontece quando um dos vetores possui tamanho 1? a * b = |a| * cos (ab) Nesse caso a * b d o tamanho do vetor a projetado no vetor b. Ento para achar o vetor projetado de a em b basta achar o a * b e multiplicar pelo vetor b .... a * b = t .... proj_a = multiplicar(b, t)
Exerccio
Crie uma classe Vector3d com x,y e z como floats. Crie a funo Length que acha o tamanho do vetor Crie a funo Normalize que normaliza esse vetor (Basta dividir os componentes pelo tamanho do vetor) Crie a funo Dot que acha o produto escalar entre 2 vetores Ache o vetor projetado de um vetor em outro normalizado.
Produto Vetorial
Outra ferramenta extremamente importante para programadores grficos o produto vetorial. O produto vetorial entre dois vetores no paralelos outro vetor perpendicular aos dois vetores. O produto vetorial escrito como:
axb=c
Abaixo a * b significa o produto escalar entre os vetores a e b. a * (a x b) = 0 b * (a x b) = 0 Ou seja: axcx + aycy + azcz = 0 bxcx + bycy + bzcz = 0
bxcx + bxaycy/ax + bxazcz/ax = 0 bxcx + bycy + bzcz bxcx bxaycy/ax bxazcz/ax = 0 bycy + bzcz = bxaycy/ax + bxazcz/ax axbycy + axbzcz = bxaycy + bxazcz axbycy bxaycy = bxazcz axbzcz (axby bxay)cy = (bxaz axbz)cz
byaxcx/ay + bycy + byazcz/ay = 0 bxcx + bycy + bzcz byaxcx/ay bycy byazcz/ay = 0 bxcx + bzcz = byaxcx/ay + byazcz/ay aybxcx + aybzcz = byaxcx + byazcz aybxcx byaxcx = byazcz aybzcz (aybx byax)cx = (byaz aybz)cz
Logo...
(axby bxay)cy = (bxaz axbz)cz (aybx byax)cx = (byaz aybz)cz Vamos alterar a segunda linha: -1*(axby bxay)cx = (byaz aybz)cz (axby bxay)cx = (aybz byaz)cz
(axby bxay)cy = (bxaz axbz)cz (axby bxay)cx = (aybz byaz)cz Queremos encontrar cx, cy e cz que so nossas incgnitas. Que valores cx, cy e cz possuem? Ele podem possuir infinitos valores ... Porm se voc selecionar um valor qualquer ... Coisas ruins podem acontecer ... como diviso por zero ... ouch.
(axby bxay)cy = (bxaz axbz)cz (axby bxay)cx = (aybz byaz)cz E se selecionarmos cz = axby bxay? Nesse caso:
Para achar as incgnitas no precisa de nenhuma diviso ... o que bom. Portanto, o produto vetorial entre vetores a x b:
Exerccio
Iluminao
Iluminao permite a gerao de cenas mais interessantes e realistas. Existem diversas formas de calcular a iluminao de uma cena. Ns utilizaremos um modelo de iluminao semelhante ao Direct3D e OpenGL, porm usaremos o clculo de iluminao por pixel.
Iluminao
A cor de um pixel calculada da seguinte forma: Cor = Contribuio Emissiva + Contribuio Ambiente + Contribuio Diffusa + Contribuio Especular.
Contribuio Emissiva
Contribuio Ambiente
Consiste no quanto o objeto reflete a iluminao espalhada pelo ambiente. A contribuio ambiente calculada da seguinte forma:
Material Ambiente * Iluminao Ambiente Material Ambiente representa o quanto da iluminao ambiente o objeto reflete.
Contribuio Difusa
Essa contribuio representa o quanto o objeto reflete para todos os lados a iluminao direta das luzes. A contribuio difusa calculada da seguinte forma:
Max((N * L),0) * Material Diffuso * Iluminao Diffusa N = Normal normalizada do ponto em que est sendo calculada a iluminao. L = Vetor para luz normalizado. Material Diffuso representa o quanto da iluminao diffusa o objeto reflete.
Contribuio Especular
A contribuio especular representa o quanto de luz direta refletida na direo principal de reflexo de uma luz. A contribuio especular calculada da seguinte forma:
Max((H * N),0)^shininess * Material Especular * Iluminao Especular H = vetor da luz + vetor do olho shininess define o quo brilhoso o objeto. Material Especular define o quanto o objeto reflete a iluminao especular.
Transformando Normais
Para transformar normais necessrio multiplic-las pela inversa da transposta da matriz de mundo. Ou seja: n = n * (world^t)^-1
Primeiro: Estudar equao do plano (ver parte do ppt de fsica) [nx ny nz nP0] * [px py pz 1]^t = 0 q * p^t = 0 q * M * (p * R)^t = 0 q * M * R^t * p^t = 0 M * R^t = Identidade M = (R^t)^-1
Exerccio
Criar objetos 3D no cdigo relativamente extraordinariamente complexo de se fazer quando algo sofisticado desejado. A maneira correta de se criar cenrios e objetos 3d modelando-os em programas como o 3D Studio Max. O problema que o 3D Studio Max pode exportar em qualquer formato desejado (Se voc implementar plugins). Logo precisamos definir um formato com o qual trabalharemos.
Arquivos .X so interessantes porque a micro$oft j se deu o trabalho de implementar um carregador. Ns precisamos no entanto achar um plugin para o 3ds que exporte arquivos .X. (Procure no google por Panda DirectX Exporter). Ns iremos carregar o modelo usando a API do DirectX e depois extrairemos a informao geomtrica, e com isso, iremos renderizar na tela modelos realmente interessantes...
Exerccio
Exporte um modelo no 3D Studio Max e carregue-o e renderize-o usando pipeline fixo. (Para casa) Exporte um arquivo .ASE e tente escrever um parser dele.
Aps carregar a malha, ns criamos uma nova malha com um formato compatvel com o nosso vertex shader. Nesse formato apenas um vertex buffer deve ser usado. (tentei com mais de 1 e no deu).
Exerccio
Nesse tipo de animao, um personagem modelado em diferentes posies (como as imagens de desenhos animados) e para renderizar uma posio intermediria entre 2 key frames feita uma interpolao linear entre 2 frames:
Frame1.pos * (1-t) + Frame2.pos * t t define a posio intermediria da animao. 0 representa o frame 1 e 1 representa o frame 2. Um t = 0.5 representa uma posio no meio do caminho entre os frames 1 e 2.
Para conseguirmos fazer a interpolao de maneira rpida (na GPU) precisamos enviar as posies dos dois keyframes para o vertex shader interpolar. Para isso usaremos coordenadas de texturas.
Exerccio
Alpha Blending
Usado para renderizar objetos com transparncia. Quando o alpha blending est habilitado, a cor final de um pixel aps renderizar uma primitiva calculada da seguinte maneira: Final Color = (New Color * SourceBlendFactor) + (Pixel Color * DestBlendFactor)
Alpha Blending
O resultado do pixel shader uma cor. Essa cor possui os componentes rgba. Ns trabalhos com os componentes rgb at agora para dar a cor aos objetos. O componente alpha permite definir um nvel de transparncia quando alpha blending est habilitado. Geralmente 1 representar um pixel totalmente opaco, e 0 um pixel totalmente transparente. Para definir o componente alpha da cor gerada pelo pixel shader use:
Alpha Blending
Alpha Blending
Exerccio
Renderize o tringulo da cena de forma transparente (enigma) Se o tringulo transparente for renderizado antes do cho e do objeto .x ele ter sua cor calculada com o fundo preto, como fazer a cena aparecer transparente atrs do tringulo? (dica) Utilize um nico float para definir o alpha do tringulo.
Volumes de sombras
Sombras so muito importantes para posicionar objetos em um ambiente 3d. Atravs das sombras possvel saber a relao espacial entre os objetos. A tcnica de volume de sombras gera sombras atravs da criao de um volume de sombras gerado atravs da malha do objeto e o stencil buffer.
Volume de sombras
Stencil Buffer
necessrio usar o stencil buffer para a tcnica de volumes de sombra. O stencil buffer um buffer que permite um controle nvel de pixel sobre o que renderizado na tela. Quando o stencil buffer est habilitado, um pixel s renderizado quando ele passa na seguinte operao: (StencilRef & StencilMask) CompFunc (StencilBufferValue & StencilMask) Todos esses elementos so customizveis e o StencilBufferValue o valor do stencil buffer.
O Algoritmo
Limpar o Stencil Buffer para 0 Gerar o volume de sombras atravs da malha do objeto e da posio da luz. Renderizar o volume de sombra sem back face culling e sem zwriting. Por toda a regio de todas as faces de frente do volume de sombra, adicionar 1 ao stencil buffer. Por toda a regio de todas as faces de trs do volume de sombras, remover 1 do stencil buffer. Se um determinado pixel falhar em z, no alterar o stencil buffer. Renderizar um Quad ocupando toda a tela, naquelas regies do stencil que forem diferentes de 0, escurecer.
O Algoritmo
O Algoritmo
Gerar o volume de sombras atravs da malha e da posio da luz. Para isso, usaremos uma malha especial.
O Algoritmo
Durante a criao do vertex buffer do volume de sombras para cada aresta do objeto definir tringulos da seguinte forma: (triangulos da aresta v1v2) = {v1,~v2, ~v1, v1, v2, ~v2} . ~v1 igual a v1 s que com o w = 0. ~v2 tem a mesma relao com v2.
O Algoritmo
Durante a renderizao do volume de sombras, todos os vrtices com w = 0 so afastados da luz uma certa distncia e depois transformados. Os vrtices com w != 0 so transformados normalmente.
O Algoritmo
O Algoritmo
Para permitir que o stencil buffer faa uma operao com as faces da frente e outra operao com as faces de trs.
O Algoritmo
Para definir a adio no stencil buffer para todas as faces de frente e subtrao para todas as faces de trs.
O Algoritmo
O Algoritmo
Nesse momento o stencil buffer s possui valores diferentes de zero nas regies de sombra. Para renderizar apenas nessas regies:
Exerccio
Bump Mapping
Bump mapping uma tcnica que aumenta o realismo das cenas ao dar a aparncia de mais detalhe em malhas geomtricas. Para implementar a tcnica, deve ser usada uma textura especial que define como a superfcie de um determinado tringulo de uma malha. Essa informao de superfcie usada na hora de calcular iluminao, e com isso o objeto parece ter muito mais detalhe do que ele possui.
Bump Mapping
Bump Mapping
A textura de bump mapping que ns utilizaremos armazenar as normais da superfcie dos tringulos. Quando ns calcularmos a iluminao por pixel, ns usaremos a normal adquirida pelo bump map e com isso daremos riqueza de detalhe superfcie.
Um problemo no entanto
As normais da textura esto num espao prprio delas. Chamado de espao tangente. Ou ns convertemos a normal para o espao de mundo, ou ns convertemos os outros vetores para o espao tangente. Vamos converter todos os vetores para o espao tangente.
A matriz de mudana de base quem vai converter do espao do mundo (onde a gente tem calculado a iluminao at agora) para o espao tangente. Ela composta por 3 componentes:
Vetor normal: A normal do tringulo. Vetor tangente: um vetor novo, que deve vir em cada vrtice, e deve ser tangente face do tringulo. O vetor tangente perpendicular normal. Vetor Binormal: calculado usando um produto vetorial entre a normal e a tangente.
Os vetores (da luz, do olho etc) so multiplicados por essa matriz da seguinte forma:
(tx, nx, bx) (ty, ny, by) (lx, ly, lz) * (tz, nz, bz)
O exemplo acima multiplicou o vetor da luz no espao de mundo pela matriz. O resultado o vetor da luz no espao tangente que ns podemos usar para calcular a iluminao normalmente. Mas porque essa matriz faz isso?
Lembra que ao fazer o dot de 2 vetores sendo que 1 normalizado, voc acha a projeo do outro vetor no vetor normalizado? (T, N e B so normalizados...) dot(L,T) calcula a projeo de L no vetor tangente. dot(L,N) calcula a projeo de L no vetor normal. dot(L,B) calcula a projeo de L no vetor binormal. Essas projees geram um vetor nos eixos x, y e z se a tangente representar o eixo x, a normal representar o eixo y e a binormal representar o eixo z.
O mapa est deitado no eixo x,z As normais sem inclinao apontam para o eixo y. Esse o espao tangente.
Os vetores Tangente, Normal e Binormal representam os vetores x,y e z porm no espao de mundo. Ao projetar L no vetor tangente, voc acha um valor que representa o tamanho de L no vetor tangente. Esse tamanho o mesmo no eixo x. Logo ao projetar L em T, voc acha L em x. Repetindo, T,N e B TEM QUE ESTAR NORMALIZADOS.
Vrtices
Alm da posio, da normal, e da coordenada de textura, voc agora precisa adicionar a tangente e, caso desejado, mais uma coordenada de textura para o bump map.
Vertex Shader
Pixel Shader
Exerccio
Implementar um tringulo com bump mapping. Experimente gerar proceduralmente um mapa normal com algum formato.
Grafos de Cena
Grafos de cena so estruturas de dados muito importantes que so utilizadas para diferentes propsitos. O propsito mais importantes do grafo de cena hierarquia de transformaes. Um grafo de cena geralmente tem o formato de uma rvore n-ria.
Grafo de Cena
Por exemplo, digamos que voc queira colocar uma arma no brao de um guerreiro. Para colocar o guerreiro no ambiente 3d, ele transformado por sua matriz de mundo. Para colocar a arma no mundo, primeiro a arma tranformada para a posio do guerreiro, e depois transformada para a posio da mo do guerreiro.
Grafo de Cena
Grafo de Cena
Grafo de Cena
Node: a classe que permite implementar a hierarquia de transformaes. Possui uma transformao como membro e uma lista de filhos. Mesh: uma classe que implementa a renderizao de algum objeto.
Grafo de Cena
No exemplo da arma, poderamos ter 2 malhas, uma representando o torso do guerreiro e outra representando a arma. A transformao da arma poderia ser uma translao +5 em x. Aps definir a transformao de mundo do guerreiro, renderizada a malha do guerreiro. Depois essa transformao usada para calcular a transformao de mundo da arma.
Os cenrios dos jogos de hoje so complexos e detalhados. Logo, so pesados para renderizar. Porque enviar todo o cenrio para a placa grfica a cada frame, se na maioria das vezes voc s consegue ver parte do cenrio? A octree uma estrutura de dados que permite reduzir o custo de renderizao pois com ela possvel clcular as regies do cenrio que so visveis. A octree uma rvore onde cada n possui 8 filhos.
Equao do plano
A equao de um plano definida geralmente de duas formas: (P P0) * n = 0. Nesse caso P um ponto qualquer, P0 um ponto no plano e n a normal normalizada do plano. Se P P0 (que gera um vetor) dot n resultar em 0 porque o ponto est no plano. Essa equao aps distribuir os dots vira:
P * n P0 * n = 0
Ax + By + Cz + D = 0. Nesse caso A, B, C e D definem o plano. Se voc colocar um ponto (x,y,z) nessa frmula e ela der zero porque o ponto est no plano. A,B,C correspondem aos componentes da normal e D = - P0 * n.
P0 * n = | P0 | * cos (theta) | P0 | * cos (theta) = tamanho de P0 projetado na normal = distncia do plano origem. P * n = | P | * cos (theta) | P | * cos (theta) = tamanho de P projetado na normal. P * n P0 * n = Distncia de P ao plano. Logo se essa distncia for 0, o ponto est no plano. Se essa distncia for positiva, o ponto est no lado do plano em que aponta a normal. Se essa distncia for negativa, o ponto est no lado oposto ao qual a normal aponta.
A idia do algoritmo calcular na AABB um mnimo e um mximo baseado na posio do plano e a seguir verificar as distncias dos pontos min e max com relao ao plano.
Calculando um frustum
Calculando um frustum
Criando a Octree
Criando a octree
Criando a Octree
Criando a octree
Exerccio
Implemente um cdigo que calcula uma AABB em um objeto e s renderiza esse objeto se sua AABB estiver interceptando o frustum. Implemente uma octree e adicione esse objeto octree. Renderize usando a octree.
Quaternions
Quaternions so ferramentas importantes para realizar rotaes. Com multiplicao de quaternions voc pode realizar rotaes. Realizar uma interpolao entre duas rotaes relativamente simples com quaternions.
Quaternions
Para entender quaternions, precisamos primeiro aprender sobre nmeros complexos. Com o conjunto dos nmeros reais d pra representar uma quantidade considervel de nmeros. Ns no entanto no conseguimos representar a raiz de -4. Porque nenhum nmero vezes ele mesmo d um nmero negativo.
Nmeros complexos
Nmeros complexos possuem uma parte real e uma parte imaginria como escrito abaixo: a + bi a = parte real. bi = parte imaginria. Ento os nmeros abaixo so todos nmeros complexos: 4 + 2i 1 + 10i 5 4i
Nmeros complexos
A parte imaginria possui uma peculiaridade: i^2 = -1 Ou seja: 2i * 2i = 4i^2 = -4 Com isso ns podemos encontrar a raiz de nmeros negativos: raiz de -4 = raiz de 4 * i^2 = 2i raiz de -1 = raiz de i^2 = i
Quaternions
Quaternions so nmeros hiper-complexos (srio!). Eles possuem 3 partes imaginrias e so escritos como: a + bi + cj + dk Ento o nmero abaixo um quaternion: 2 + 3i + 4j + 5k
Quaternions
Assim como nmeros complexos: i^2 = j^2 = k^2 = -1 Porm nmeros complexos possuem algumas definies adicionais (aqui comea a loucura). i*j=k j * i = -k j*k=i k * j = -i k*i=j i * k = -j i * j * k = (i * j) * k = i * (j * k) = -1
q0*q1 = (w0 + x0*i + y0*j + z0*k) * (w1 + x1*i + y1*j + z1*k). Vamos aplicar multiplicao distributiva: w0*w1 + w0*x1*i + w0*y1*j + w0*z1*k + x0*i*w1 + x0*i*x1*i + x0*i*y1*j + x0*i*z1*k + y0*j*w1 + y0*j*x1*i + y0*j*y1*j + y0*j*z1*k + z0*k*w1 + z0*k*x1*i + z0*k*y1*j + z0*k*z1*k (w0*w1 x0*x1 y0*y1 z0*z1) + w0*(x1*i + y1*j + z1*k) + w1*(x0*i + y0*j + z0*k) + x0*y1*k - x0*z1*j y0*x1*k + y0*z1*i + z0*x1*j z0*y1*i
Um quaternion: q0 = (w0 + x0*i + y0*j + z0*k) = (w0 + v0) Ou seja: v0 = (x0*i + y0*j + z0*k) Outro quaternion: q1 = (w1 + x1*i + y1*j + z1*k) = (w1 + v1) Produto escalar: v0 * v1 = (x0*x1 + y0*y1 + z0*z1) Produto vetorial: v0 x v1 = (y0*z1*i z0*y1*i + z0*x1*j x0*z1*j + x0*y1*k y0*x1*k) Escala: a * v0 = (a*x0*i + a*y0*j + a*z0*k)
q0*q1 = (w0*w1 x0*x1 y0*y1 z0*z1) + w0*(x1*i + y1*j + z1*k) + w1*(x0*i + y0*j + z0*k) + x0*y1*k - x0*z1*j y0*x1*k + y0*z1*i + z0*x1*j - z0*y1*i Torna-se: q0*q1 = w0*w1 v0*v1 + w0*v1 + w1*v0 + v0 x v1
O conjugado de um quaternion
Rotacionando vetores
Crie 1 quaternion com w = 0 e com os componentes x,y e z do prprio vetor que voc quer rotacionar:
Crie outro quaternion onde w = cos(theta/2), o x,y,z o eixo de rotao normalizado e escalado por sin(theta/2):
q = (cos(theta/2) + sin(theta/2)d)
A multiplicao qvq* gera um quaternion cujos elementos x,y,z so o vetor 3D rotacionado pelo eixo d do quaternion q por theta graus.
Rotacionando vetores
Ou seja, digamos que queremos rotacionar o vetor (1, 0, 0) no sentido anti-horrio do eixo (0, 0, 1). Queremos rotacionar 90 graus gerando o vetor (0, 1, 0). Vamos criar dois quaternions v e q: v = (0, 1, 0, 0) q = (cos(45) + sin(45)(0, 0, 1)) = (cos(45), 0, 0, sin(45)) Logo: qvq* = (0, 0, 1, 0) = Rotacionamos o vetor!
Para entender porque quaternions funcionam precisamos primeiro aprender como criar uma matriz que rotaciona um vetor dado um eixo qualquer.
Para rotacionar um vetor em xy usando o eixo z usamos a matriz: (cos(theta) sin(theta) 0) (-sin(theta) cos(theta) 0) (vx vy vz) * (0 0 1) Como podemos fazer para rotacionar um vetor por um eixo qualquer?
Assim como no bump mapping vamos criar uma matriz que projeta o vetor em 3 outros vetores normalizados que formam uma base orthonormal. Um desses vetores base o eixo de rotao. Os outros dois vetores podem ser dois vetores quaisquer ortogonais entre si.
O Algoritmo
Criar a matriz de vetores base sendo que o vetor base que representa o eixo de rotao precisa ser a ltima coluna gerando o valor em z. A matriz abaixo mostra os vetores base a, b e rot, todos normalizados e rot o eixo de rotao. (ax bx rotx) (ay by roty) (vx vy vz) * (az bz rotz) = (v*a v*b v*rot) Com essas projees possvel achar o vetor em nosso espao x,y,z padro. Sendo que o eixo de rotao passa a representar o eixo z. Depois de multiplicar o vetor pela matriz acima, ns o multiplicamos pela matriz de rotao no eixo z mostrada anteriormente. Com isso o vetor rotaciona no eixo z que representa o eixo de rotao rot. Depois de rotacionar nosso vetor no eixos x,y,z padro, devemos calcular como fica esse vetor rotacionado usando como vetores base os vetores a, b e rot. Para achar isso podemos calcular na mo, multiplicando os vetores a, b e rot pelos valores achados em x, y e z aps a rotao:
vfinal = vx * a + vy * b + vz * rot
Ou podemos multiplicar o vetor rotacionado pela matriz inversa da matriz formada por a,b e rot.
O Algoritmo (Resumidamente)
V = vetor que queremos rotacionar RV = vetor rotacionado MB = Matriz criada a partir de A, B e Rot RotZ = Matriz que rotaciona pelo eixo Z MB^t = Matriz transposta da MB. Matriz Transposta = Inversa para rotaes. O Algoritmo aplica a seguinte frmula: RV = V * MB * RotZ * MB^t
Cdigo
cos(theta) = c sin(theta) = s
R = (ax bx rotx) (c s 0) (ax ay az) (ay by roty) (-s c 0) (bx by bz) (az bz rotz) (0 0 1) (rotx roty rotz) R = (a^t b^t rot^t) (c s 0) (a) (-s c 0) (b) (0 0 1) (rot) R = (a^t b^t rot^t) (c*a+s*b) (-s*a+c*b) (rot) R = a^t(c*a+s*b) + b^t(-s*a+c*b) + rot^t*rot R = c*(a^t*a + b^t*b) + s*(a^t*b b^t*a) + rot^t*rot
Algumas frmulas
v = (a*v)*a + (b*v)*b + (rot*v)*rot = x0*a + x1*b + x2*rot rot x v = rot x (x0*a + x1*b + x2*rot) = x0*(rot x a) + x1*(rot x b) + x2*(rot x rot) rot x v = x0*(rot x a) + x1*(rot x b) = x0*b x1*a rot x v = x0*b x1*a = (a*v)*b - (b*v)*a rot x v = (v*a^t)*b (v*b^t)*a rot x v = v*(a^t*b b^t*a)
Algumas Frmulas
v*I=v v * I = (a*v)a + (b*v)b + (rot*v)rot v * I = (v*a^t)a + (v*b^t)b + (v*rot^t)rot v * I = v*(a^t*a + b^t*b + rot^t*rot) I = a^t*a + b^t*b + rot^t*rot Voltando a nossa frmula original:
R = c*(a^t*a + b^t*b) + s*(a^t*b b^t*a) + rot^t*rot R = c*(I rot^t*rot) + s*(a^t*b b^t*a) + rot^t*rot R = cI c*rot^*rot + s*(a^t*b b^t*a) + rot^t*rot R = cI + s*(a^t*b b^t*a) + (1 c)rot^t*rot
Algumas frmulas
-x*a x1*b = x2*rot v = (rot*v)*rot - v rot x (rot x v) = (rot*v)*rot v = v*(rot^t*rot) v rot x (rot x v) + v = v*(rot^t*rot) Voltando formula:
R = cI + s*(a^t*b b^t*a) + (1 c)rot^t*rot Se a gente multiplicar um vetor por essa matriz: vR = cv*I + sv*(a^t*b b^t*a) + (1 c)*v*(rot^t*rot) vR = cv*I + s*(rot x v) + (1 c)*(rot x (rot x v) + v) vR = cv + s*(rot x v) + (1 c)*(rot x (rot x v)) + (1 c)v vR = cv + s*(rot x v) + (1 c)*(rot x (rot x v)) + v cv vR = v + sin(theta)*(rot x v) + (1 cos(theta))*(rot x (rot x v))
Ou Seja
Quando voc multiplica um vetor pela matriz RV abaixo: RV = V * MB * RotZ * MB^t Voc est fazendo na realidade o seguinte clculo:
vR = v + sin(theta)*(rot x v) + (1 cos(theta))*(rot x (rot x v))
dado um vetor v = (x, y, z) armazenado em um quaternion q0 = (0 + v) Um eixo de rotao normalizado r = (rx, ry, rz) armazenado em um quaternion da seguinte forma: q1 = (cos(theta/2) + sin(theta/2)*r) A multiplicao: q1q0q1* gera um quaternion cujos componente x, y, z consistem no vetor v rotacionado pelo eixo r por theta graus.
Vamos considerar:
Lembrando:
q1q0q1* = (c + s*d)(0 + v)(c s*d) q1q0q1* = (-s*d*v + c*v + s*d x v)(c s*d) q1q0q1* = [-s*c*d*v (c*v + s*d x v)*(-s*d)] + (-s*d*v)*(-s*d) + c*(c*v + s*d x v) + (c*v + s*d x v) x (-s*d) -s*c*d*v + s*c*d*v + s^2*(d x v)*d + s^2*(d*v)*d + c^2*v + s*c*(d x v) s*c*(v x d) - s^2*(d x v) x d s^2*(d*v)*d + c^2*v + s*c*(d x v) + s*c*(d x v) - s^2*(d x v) x d s^2*(d*v)*d + c^2*v + 2*s*c*(d x v) - s^2*(d x v) x d s^2*(d*v)*d + c^2*v + 2*s*c*(d x v) + s^2*d x (d x v)
Continuando a anlise
s^2*(d*v)*d + c^2*v + 2*s*c*(d x v) + s^2*d x (d x v) (1 s^2)*v + 2*s*c*(d x v) + s^2*[(d*v)*d + d x (d x v)] v s^2*v + 2*s*c*(d x v) + s^2[(d*v)*d + d x (d x v)] v + 2*s*c*(d x v) + s^2[(d*v)*d v + d x (d x v)] Porm: d x (d x v) = (d*v)*d (d*d)*v = (d*v)*d v. Logo: q1q0q1* = v + 2*s*c*(d x v) + 2*s^2*d x (d x v)
Continuando
2*s*c = 2*sen(theta/2)*cos(theta/2) = ? Para resolver essa frmula vamos provar a seguinte frmula: sin(a + b) = sin(a)cos(b) + sin(b)cos(a)
RPQ = pi/2 RQP = pi/2 (pi/2 RQO) = RQO = a OP = 1 PQ = sin(b) OQ = cos(b) AQ/OQ = sin(a). AQ = sin(a)cos(b). AQ = RB. PR/PQ = cos(a). PR = cos(a)sin(b) sin(a + b) = PB = RB + PR = sin(a)cos(b) + cos(a)sin(b) Logo: sin(theta) = sin(theta/2)cos(theta/2) + cos(theta/2)sin(theta/2) sin(theta) = 2sin(theta/2)cos(theta/2)
Outra Prova
OP = 1 PQ = sin(b) OQ = cos(b) OA/OQ = cos(a). OA = cos(a)cos(b). RQ/PQ = sin(a). RQ = sin(a)sin(b). RQ = BA. cos(a + b) = OB = OA BA = cos(a)cos(b) sin(a)sin(b) Logo cos(theta) = cos(theta/2)cos(theta/2) sin(theta/2)sin(theta/2) cos(theta) = cos^2(theta/2) sin^2(theta/2) E Ainda: cos(theta) = (1 sin^2(theta/2)) sin^2(theta/2) cos(theta) = 1 2*sin^2(theta/2) 1 cos(theta) = 2*sin^2(theta/2)
q1q0q1* = v + 2*s*c*(d x v) + 2*s^2*d x (d x v) q1q0q1*= v + sin(theta)*(d x v) + (1 cos(theta))*d x (d x v) Comparando frmula de rotao por um eixo qualquer:
vR = v + sin(theta)*(rot x v) + (1 cos(theta))*(rot x (rot x v)) Podemos ver ento que a multiplicao de quaternions q1q0q1* resulta na mesma equao da rotao de vetores por um eixo qualquer mostrada anteriormente.
Exerccio
Modelos de Distribuio
Cliente / Servidor
Modelos de Distribuio
Peer to Peer
Cliente / Servidor
Capaz de manter milhares de jogadores no mesmo jogo (Utilizado em Massively Multiplayer Games). H necessidade de manter um servidor (Custos podem ser elevados).
Armazena (geralmente) menos jogadores por instncia de jogo. No requer servidor de grande poder computacional.
Protocolo complexo que implementa a comunicao como um fluxo de bytes que trafega entre dois pontos (Circuito Virtual). Garante a chegada das mensagens As mensagens chegam de forma ordenada Algoritmos para reduo do nmero de mensagens Comunicao 1 x 1
TCP - Conexo
Garantia de chegada
Protocolo simples que implementa comunicao como um envio de mensagens de forma atmica. No h garantia de chegada Mensagens podem chegar desordenada ou duplicadas Permite realizao de broadcasts ou multicast (comunicao 1 x N) No h necessidade de se conectar.
Sockets
API criada para abstrair a conexo entre computadores em diferentes sistemas operacionais. Um socket formado pela unio IP + Porta, que define unicamente uma parte de uma conexo.
Funo socket()
Funo que cria um socket. SOCKET socket(int family, int type, int protocol) family: Define a famlia de protocolos utilizados. AF_INET = Protocolos convencionais da internet. type: Define o tipo de socket. SOCK_STREAM ou SOCK_DGRAM. protocol: Define o tipo de protocolo dentro da famlia. IPPROTO_TCP = TCP, IPPROTO_UDP = UDP.
Funo socket()
Exemplo:
Funo connect()
Estabelece conexo int connect(SOCKET socket, const struct sockaddr *serveraddr, int addrlen) socket: O socket do cliente serveraddr: O endereo (IP+Porta) do servidor. addrlen: O tamanho da estrutura serveraddr.
Estrutura sockaddr_in
Estrutura passada para a funo connect. struct sockaddr_in { short sin_family; //AF_INET unsigned short sin_port; struct in_addr sin_addr; char sin_zero[8]; }; Define o endereo de um socket remoto
Estrutura in_addr
Funo connect()
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); sockaddr_in addr = {0}; addr.sin_family = AF_INET; addr.sin_port = htons(SERVER_PORT); addr.sin_addr.s_addr = inet_addr(127.0.0.1); connect(s, (const sockaddr*)&addr, sizeof(addr));
Funo bind()
Funo usada pelo servidor para definir um socket local int bind(SOCKET s, const sockaddr *localaddr, int addrlen); s: o socket do servidor localaddr: o endereo local addrlen: o tamanho do endereo
Funo bind()
SOCKET server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); sockaddr_in addr = {0}; addr.sin_family = AF_INET; addr.sin_port = htons(LIST_PORT); addr.sin_addr.s_addr = htonl(INADDR_ANY); bind(server, (const serveraddr*)&addr, sizeof(addr));
Funo listen()
Define um socket como passivo. Informa o S.O. que deve aceitar conexes direcionadas esse socket. int listen(SOCKET s, int backlog); s: o socket do servidor backlog: O nmero de conexes que podem ficar pendentes para esse socket.
Funo listen()
//continuao do cdigo da bind() listen(server, 8);
Funo accept()
Chamada por um servidor TCP para retornar a prxima conexo completa do nicio da fila de conexes completas. SOCKET accept(SOCKET s, struct sockaddr * addr, int * addrlen); s: o socket do servidor addr: o endereo do novo cliente addrlen: o tamanho do endereo Essa funo retorna o socket do novo cliente e bloqueia quando no h conexes terminadas.
Funo accept()
while(true) { addrlen = sizeof(addr); cli_socket = accept(server, (...)&addr, &addrlen); ProcessClientSocket(cli_socket); }
Funo closesocket()
Funo send()
funo que envia bytes usando um socket conectado. int send(SOCKET s, const char * buffer, int len, int flags); s: o socket conectado por onde enviar os dados buffer: os bytes a serem enviados len: o nmero de bytes a serem enviados flags: Flags
Funo send()
//continuando o cdigo da connect
Funo recv()
Funo usada para receber dados de uma conexo. int recv(SOCKET s, char * buffer, int len, int flags);
Funo recv()
//continuando o codigo da send()
Funo sendto()
Usada com sockets UDP no conectados int sendto(SOCKET s, const char *buf, int len, int flags, const struct *destaddr, int addrlen);
Funo recvfrom()
Funo usada em servidores UDP sem conexes. int recvfrom(SOCKET s, char * buffer, int len, int flags, sockaddr *addr, int *addrlen);
Exerccio
Implementar uma aplicao cliente / servidor usando TCP onde o cliente envia uma string para o servidor e o servidor escreve na tela aquilo que recebeu. O servidor s aceita 1 cliente de cada vez.
Exerccio
Implementar uma aplicao cliente / servidor semelhante ao exerccio 1 porm usando UDP.
Livros Importantes
TCP/IP Illustrated, Vol 1 Unix Network Programming, Vol 1 (Ambos do W. Richard Stevens!)
Multithreading (Reviso)
Conhecimento fundamental (Xbox 360). Thread = Parte de um programa que executa concorrentemente ou paralelamente a outras partes do programa. Comunicao entre partes feita atravs de variveis compartilhadas. Um game = Thread Principal (Main) + Outras Threads
Multithreading
Mltiplas threads parecem executar paralelamente mesmo em um nico processador devido ao time slicing.
Multithreading (Exemplo)
uintptr_t
_beginthread( void( *start_address )( void * ), unsigned stack_size, void *arglist ); start_address: endereo de uma funo que inicia a execuo da thread. stack_size: tamanho da pilha da nova thread. arglist: ponteiro para parmetro passado para thread.
0 1
1
2 0 1
Texture decompression
XAudio
Exerccio
Evolua o exerccio 1 de forma que o servidor se torne capaz de processar mltiplos clientes simultaneamente. Utilize 1 thread por cliente.
Entendendo TCP
Desligando o algoritmo
BOOL b = TRUE; setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char*)&b, sizeof(bool));
sendto() em alguns sistemas operacionais realiza conexo, envio e desconexo. Permite receber mensagens ICMP.
Levar em considerao o tempo estimado de round trip time (SRTT) e a variao estimada dos tempos de round trip time (VARRTT).
delta = RTT SRTT SRTT = SRTT + (delta / RTTINF) VARRTT = VARRTT + ((| delta | - VARRTT) / VARRTTINF) RTO = SRTT + VARRTT * VARINC
Calculando RTO:
Dead-Reckoning
Com Dead-Reckoning baseado a objetivos h a possibilidade de reduo ainda maior no nmero de mensagens trocadas.
T 0s
T 2s
Balanceamento
Para conseguir processar um MMORPG necessrio quebrar o processamento entre diversos servidores.
Outras tcnicas
Diagrama de Classes
Outras caractersticas
IOCP Culling usando Grid Balanceamento usando retngulos Reliable UDP + Last Update Sincronizao por Tempo de Comando Dead Reckoning baseado em objetivos
Resultados
Exerccio
Implemente uma demo onde existem 2 retngulos e cada retngulo sobre movimentao de um cliente diferente. Ao mover um retngulo, o outro cliente deve ver a movimentao. Implemente dead reckoning para reduzir o nmero de mensagens trocadas.
Teste de Interseo Raio Plano Teste de Interseo Raio - Tringulo Teste de Interseo Esfera Esfera Teste de Interseo Elipside - Elipside Teste de Interseo AABB AABB Deteco de Coliso em cenrio esttico usando elipsides Resposta Coliso Picking Otimizando a coliso com Binary Space Partition Trees. Dinmica Linear Dinmica Rotacional
N dot (P P0) = 0
Onde N a normal do plano, P um ponto qualquer e P0 um ponto no plano. Qualquer P colocado na frmula que d zero como resultado est no plano.
O + tD
Onde O a origem do raio, D a direo normalizada e t um valor que permite achar qualquer ponto na extenso do raio.
Devemos achar um t que gere um ponto que quando utilizado na frmula do plano resulte em zero. Ou seja, devemos achar um t que resulte em um ponto no plano. t vai indicar a distncia percorrida da origem ao local de interseo.
O + tD = P N dot (P P0) = 0 N dot (O + tD P0) = 0 N*O + tN*D N*P0 = 0 tN*D = N*P0 N*O t = (N*P0 N*O) / N*D t = N*(P0 O) / N*D Quando N*D for igual a zero, o raio paralelo ao plano.
Ache a interseo do raio com o plano do tringulo. Ache uma componente na normal diferente de zero, projete em um plano do eixo alinhado de acordo com a componente isso transforma nosso problema em 2D. Utilizando o clculo da rea do palalelograma, verifique se o ponto est dentro ou fora do tringulo.
rea do Paralelograma
Para achar a rea do paralelograma usando o ponto sendo testado e 2 posies de uma aresta do tringulo: Area = (v2x-v1x)*(py-v1y) - (v2y-v1y)*(px-v1x) Caso a aresta v1-v2 represente o lado (0,0)-(c,d) e v1-p o lado (0,0)(a,b) a rea calculada negativa pois:
Logo se todos os clculos de rea forem positivos ou negativos o ponto est dentro do tringulo.
Um esfera representada computacionalmente atravs de uma posio C que define o centro da esfera e um tamanho r que define o raio da esfera. Duas esferas esto colidindo se a distncia entre os centros for menor que a soma dos raios das esferas, ou seja: Est colidindo se:
| C1 C2 | < r1 + r2
A deteco de coliso de cilindros apresentada aqui funciona apenas para cilindros alinhados ao eixo y. Para representarmos um cilindro precisamos de:
AABB significa Axis Aligned Bounding Box, ou seja, representa uma caixa com os alinhada aos eixos x,y e z.
AABBs so representadas por um ponto mnimo e um ponto mximo. Duas AABBs esto colidindo se em nenhum momento algum dos testes triviais de rejeio retornam sucesso.
Exerccio
Implemente uma aplicao que renderiza dois cubos. Coloque duas AABBs envolvendo cada um dos cubos. Faa um dos cubos se moverem com o uso de setas. Implemente a deteco de coliso entre os cubos e impea que os cubos entrem um no outro.
Para detectar coliso: Lance um raio do centro da elipside na direo do tringulo usando a normal negativa do tringulo como direo.
Calcule o tamanho do raio nessa direo usada. Se o raio acerta o tringulo e sua distncia para o plano menor que o raio da elipside na direo usada, a elipside colide com o tringulo.
Resposta coliso
Aps detectar a coliso temos que tratar a resposta coliso. Uma resposta normalmente dada empurrar o objeto para fora da geometria em que ele colidiu. Como vamos empurrar a elipside para fora do tringulo?
Resposta a coliso
Ns empurramos o centro da elipside para fora na direo da normal do plano. A distncia empurrada = Tamanho raio Distncia centro-plano.
Resposta coliso
Exerccio
Implemente uma aplicao onde no cenrio h um tringulo. Coloque um elipside como BV da cmera. Faa a cmera se mover e colidir com o tringulo.
Picking
Algo bastante utilizado em games a seleo de algum objeto 3d com o uso do mouse. Para conseguirmos descobrir o objeto selecionado, precisamos lanar um raio no espao de mundo. Para descobrirmos esse raio precisamos saber onde no mundo se encontra a posio selecionada na tela. Com essa informao podemos lanar o raio partindo da cmera e passando por essa posio 3D no mundo.
Picking
Para achar a posio no espao 3D usaremos as informaes para a criao do frustum de viso. Para achar a metade da altura da tela em espao de mundo voc calcula(usando os valores da imagem como exemplo): tg(15) = x / near tg(15) * near = x; Para achar a metade da largura basta fazer: half_width = x * aspect; aspect a diviso da largura da tela pela altura. Na prtica, o valor 15 da figura ser FOVy / 2 (FOVy o mesmo valor passado na funo de criao de matriz de perspectiva).
Picking
Exercicio
Implemente uma aplicao que quando voc clica em um tringulo com o mouse aparece o message box click.
BSPs so rvores binrias muito parecidas com as rvores binrias de busca. (Na realidade, a rvore binria de busca pode ser vista como uma BSP de 1 dimenso). BSPs so teis para acelerar a deteco de coliso.
Uma BSP uma rvore onde cada n representa um plano. Esse plano corta o espao em 2. Os planos dos filhos a direita e esquerda cortam os espaos resultantes da direita e da esquerda.
Para detectar a coliso de um objeto com outros: Adicione todos os objetos BSP. Os objetos terminam em listas nas folhas da rvore. Detectar coliso de cada objeto com todos os outros objetos da mesma folha.
Implementar uma BSP. Adicionar objetos usando AABBs. Implemente a deteco de coliso de cada objeto com os outros da mesma folha.
Dinmica Linear
Como podemos mover objetos linearmente de maneira fisicamente realista? Aplicamos a segunda lei de Newton:
F=M*A
F/M=A
Dessa forma:
O tempo e a posio
Acelerao = variao de velocidade / variao de tempo Velocidade = variao de posio / variao de tempo Posio = rea da funo da velocidade em uma faixa de tempo Velocidade = rea da funo da acelerao em uma faixa de tempo
Um problema complicado
Dada uma acelerao, temos que achar a variao da velocidade e depois a variao da posio. O problema que isso envolve uma integrao de uma funo (e ns no sabemos a funo previamente ).
Mtodo de Euler
Consiste no mtodo mais simples para achar as reas. Nele voc adquire o valor no incio do intervalo e considera ele constante durante todo o intervalo.
Mtodo de Euler
Acelerao = fora / massa Posio = posio + velocidade * variao de tempo Velocidade = velocidade + acelerao * variao de tempo
Dinmica Rotacional
Ns aprendemos a mexer linearmente um objeto. Mas e quanto a rotao? Torque o equivalente da fora para o movimento rotacional. Para achar o torque de um corpo rgido, ache o produto vetorial entre o vetor que vai do centro de massa do objeto at o local onde est sendo aplicada uma fora e o vetor da fora.
Descobrindo a rotao
Torque = Cross(R, F) Acelerao Angular = Torque / Inrcia Rotao = Rotao + Velocidade Angular * variao de tempo. Velocidade Angular = Velocidade Angular + Acelerao Angular * variao de tempo.
Descobrindo a rotao
Exerccio
Implemente um demo que renderiza uma caixa. Implemente fsica linear aplicando uma fora constante na caixa. Implemente fsica rotacional causando a caixa rotacional dependendo do lugar onde se aplica a fora.
Mquinas de Estado
Mquinas de Estado so uma das principais tcnicas de inteligncia artificial usadas desde o primrdio dos tempos (~1980). Mquinas de Estado so mquinas abstratas compostas por estados e eventos que geram transies nesses estados. Elas so teis pois permitem a criao de seres que possuem comportamento dependendo do estado e que variam esse comportamento dependendo de eventos que ocorrem no jogo.
Mquinas de Estado
Maquinas de estado
Maquina de estado
Quando uma determinada entidade exige um comportamento sofisticado sua mquina de estado tende a ficar complexa demais. A soluo pra isso fazer uma mesma entidade usar mltiplas mquinas paralelas para resolver diferentes problemas. Por exemplo: Digamos que aquele inimigo do exemplo anterior passe a usar uma metralhadora e 2 mquinas de estado, uma para movimentao e outra para atacar.
Implemente da mesma forma que a mquina de estado normal, porm use 1 varivel de estado por mquina e 1 switch por mquina.
interessante s vezes fazer com que mquinas de estado faam interaes. Half-life fez isso com seus soldados que se coordenavam ao combater o player. Para fazer essa comunicao basta usar variveis compartilhadas como variveis estticas.
Digamos que ns queremos que um inimigo ao avistar o player avise aos outros inimigos da localizao do player e todos os outros inimigos a seguir se movem para a regio avisada.
Exerccio
Implemente um demo com 2 caixas. Uma caixa o inimigo e se move pela tela seguindo por 4 posies pr-definidas. A outra controlada pelo jogador. Quando a caixa do jogador se aproxima uma certa distncia. O inimigo comea a se aproximar at que ele chega uma distncia e pra. Se o jogador se afastar depois do inimigo, o inimigo volta a caminhar no seu caminho pr-definido. Implemente esse demo usando uma mquina de estados.
Scripting uma adio fundamental qualquer engine. Scripting fornece uma ambiente sandbox para programadores de gameplay e de inteligncia artificial onde eles podem criar lgica e contedo sem se preocupar em quebrar nada interno da engine. Ou seja, Scripting fornece permite que um trabalho puramente criativo seja realizado. Scripting tambm necessrio se voc deseja que seus jogos sejam modable.
Embedding Lua
Embedding Lua
A primeira linha cria o objeto de estado lua que usado em todas as funes. A funo dofile quem executa scripts. No final lua_close deve ser chamado para liberar recursos.
Script em lua:
Resultado: x = 7 e y = 9
Lua utiliza de uma pilha para trocar valores com o cdigo em C++. A funo setglobal define o nome de uma varivel e a pushnumber seu valor. A funo getglobal coloca uma varivel no topo da pilha que pode ser capturada com a funo tonumber que recebe o estado lua e o ndice que se deseja usar para pegar um valor.
Scripts so teis para customizao de comportamentos, implementao de lgica de jogo e AI. Porm scripts so mais lentos que cdigo compilado em C++, portanto para certas computaes custosas valido implementlas em C++ e adicionar a funo Lua.
A funo register registra uma funo em lua. Dentro da funo faz-se uso da pilha normalmente para acessar valores. Para retornar valores usa-se push e o valor retornado define o numero de valores a serem retornados ( possvel retornar mais de um valor).
Exerccio
Reimplemente o exemplo anterior executando a mquina de estados em Lua ao invs de execut-la em C++. Adicione lua a funo de distncia implementada em C++.
Path Finding
Um problema muito comum em diversos jogos a necessidade de calcular o caminho para se mover de um ponto a outro do mapa. Para resolver esse problema ns usaremos o algoritmo A*.
A*
O algoritmo A* um algoritmo que implementa uma busca heurstica. Uma busca heurstica leva em considerao alguma informao antes de tomar uma deciso. No nosso caso, o A* levar em considerao informaes geomtricas para tomar decises.
Min-Heap
O algoritmo do A* precisa de uma estrutura de dados que implemente uma fila de prioridade. Uma fila de prioridade implementa uma funo para retornar o elemento mais prioritrio de forma eficiente. Uma forma de implementar uma fila de prioridade usar a estrutura Min-Heap.
Min-Heap
Uma Min-Heap semelhante uma rvore binria que possui a seguinte regra:
PriorityQueue
PriorityQueue
PriorityQueue
PriorityQueue
PriorityQueue
A*
Essas prioridades fazem o algoritmo selecionar os ns que se aproximam mais rapidamente do n destino.
A*
A*
Exerccio
Implemente um PathFinder usando A* que recebe uma matriz de inteiros onde 1 lugar passvel e 0 parede, e a partir dessa matriz criado uma estrutura de dados onde cada n possui norte, sul, leste e oeste. Faa o PathFinder calcular o caminho entre duas posies. Imprima as posies numa console application.
Jogos 3D possuem a vantagem de poderem compartilhar muita tecnologia. Isso aumenta a recompensa em implementar uma engine de jogos. Engines de jogos podem possuir designs completamente diferentes, logo o design mostrado aqui no deve ser considerado o design supremo e fundamental de engines.
Implementando um Jogo
Uma forma interessante de dividir os diferentes momentos de um jogo implementando-o como uma mquina de estados. Cada estado implementado em uma classe diferente.
Implementando um Jogo
Loop Principal
Renderiza a cena (Sem dar Present) Adquire e Processa Input do Player Processa AI Processamento fsica, testa coliso e resposta Processamentos extras, especficos do estado atual Present
1 Level Loader que carrega o arquivo com a configurao do level. Esse arquivo aponta para outros arquivos que deve ser carregados para a execuo do level. 1 engine 3d para carregar e renderizar o cenrio com efeitos especiais de maneira rpida. 1 engine de fsica/coliso com estruturas otimizadas para deteco de coliso. Esse engine move objetos e detecta coliso e repassa o tratamento da resposta para o game. 1 engine de input para aquisio do input. 1 engine de AI que carrega dados em um cenrio especficos para AI e processa as entidades AI do game. Todos so Singletons.
Level Loader
Tem como misso carregar o arquivo que representa o level. Esse arquivo possui os nomes de todos os outros arquivos que sero usados no level. Ex: O arquivo da octree do cenrio. O arquivo que armazena os waypoints do cenrio. O arquivo que armazena a estrutura usada para processar a coliso. Os modelos, os scripts. O level loader repassa todos esses nomes para as respectivas engines carregarem.
Engine 3D
Responsvel pela parte grfica do jogo. Carrega o cenrio e os modelos 3D. Pode carregar uma estrutura especial como uma Octree. Carrega tambm a parte grfica dos elementos do cenrio. Renderiza o cenrio 3D e os modelos usando tcnicas de acelerao e efeitos especiais.
Engine 3D
Engine 3D (Extras)
interessante criar plugins para 3DS Max para exportar cenrio e modelos. importantssimo implementar um level editor onde as fases so feitas a la wysiwyg onde voc define locais onde ficam as entidades, triggers e scripts especiais. Voc tambm configura caractersticas grficas especficas da engine e v em tempo real as alteraes.
Carrega a estrutura de coliso e a parte fsica dos elementos da cena. Pode carregar por exemplo uma BSP. Processa a fsica das entidades e usa tcnicas de acelerao para os testes de coliso. Delega a resposta de coliso ao game. Isso pode ser feito com ponteiros para funo ou funes virtuais.
Engine de Input
Engine de AI
Carrega a estrutura de dados necessria para executar a AI. Como exemplo, carregar os caminhos possveis pela AI. Carrega a parte de AI das entidades da cena. Processa movimentao e inteligncia usando C++ e delegando para Lua partes do processamento.
Engine de AI
Problema
O AI Engine decide mover um NPC para alguma regio. Ele ento requisita a movimentao para o Engine de Fsica. O Engine de fsica o move normalmente. Como o engine grfico recebe essa alterao? Uma soluo fazer uso de IDs. Um elemento identificado nas 3 engines atravs do uso de um mesmo ID. Logo se o engine de AI decidir mover um personagem, ele identifica o personagem atravs de seu ID. O engine grfico antes da renderizao requisita todos os elementos que se moveram para atualizar suas posies.
Elementos e IDs
Exerccio Final
Implementar um Jogo 3D