Tuesday 4 July 2017

Mover Média Circular Buffer


Capítulo 14 Agora que você sabe Este capítulo não tem objetivos da mesma forma que os capítulos anteriores. É simplesmente uma coleção de tópicos que descrevem idéias que você pode achar úteis para sua aplicação. Alguns tópicos, como o tratamento de erros, não se encaixam em outras categorias, mas são muito curtos para um capítulo inteiro. OpenGL é um tipo de bolsa de ferramentas de baixo nível agora que você conhece essas ferramentas, você pode usá-las para implementar funções de nível superior. Este capítulo apresenta vários exemplos de tais capacidades de nível superior. Este capítulo discute uma variedade de técnicas baseadas em comandos OpenGL que ilustram alguns dos usos não tão óbvios para os quais você pode colocar esses comandos. Os exemplos não estão em ordem particular e não estão relacionados entre si. A idéia é ler os cabeçalhos das seções e saltar para os exemplos que você achou interessantes. Para sua conveniência, os títulos são listados e explicados brevemente aqui. Nota: A maioria dos exemplos no restante deste guia estão completos e podem ser compilados e executados como estão. Neste capítulo, no entanto, não há programas completos, e você tem que fazer um pouco de trabalho por conta própria para executá-los. A Manipulação de Erros diz como verificar as condições de erro do OpenGL. Qual versão eu estou usando descreve como descobrir detalhes sobre a implementação, incluindo o número da versão. Isso pode ser útil para escrever aplicativos que são compatíveis com versões anteriores do OpenGL. Extensões ao Padrão apresentam técnicas para identificar e usar extensões específicas do fornecedor para o padrão OpenGL. Cheesy Translucency explica como usar o estilingue de polígonos para alcançar a translucidez, isso é particularmente útil quando você não possui hardware de mistura disponível. Um efeito Easy Fade mostra como usar o estilingue de polígono para criar o efeito de um desvanecimento no fundo. Seleção de Objeto Usando o Back Buffer descreve como usar o buffer de retorno em um sistema de buffer duplo para lidar com a escolha de objetos simples. Cheap Image Transformation discute como desenhar uma versão distorcida de uma imagem bitmap, desenhando cada pixel como um quadrilateral. A exibição de camadas explica como exibir várias camadas diferentes de materiais e indicar onde os materiais se sobrepõem. Caracteres antialiased descrevem como desenhar fontes mais suaves. Drawing Round Points descreve como desenhar pontos de round round. A interpolação de imagens mostra como misturar suavemente de uma imagem para a outra. Making Decals explica como desenhar duas imagens, onde uma é uma espécie de decalque que sempre deve aparecer em cima do outro. Desenho de preenchimento, polígonos côncavos usando o Stencil Buffer, informa como desenhar polígonos côncavos, polígonos não-soltos e polígonos com furos, usando o tampão do estêncil. Encontrar regiões de interferência descreve como determinar onde as peças tridimensionais se sobrepõem. Shadows descreve como desenhar sombras de objetos iluminados. A remoção da linha oculta discute como desenhar um objeto de wireframe com linhas ocultas removidas usando o buffer do estêncil. Os aplicativos de mapeamento de textura descrevem vários usos inteligentes para mapeamento de textura, como imagens rotativas e deformadas. Desenho Profunda-Buffered Images diz-lhe como combinar imagens em um ambiente com buffer de profundidade. Dirichlet Domains explica como encontrar o domínio Dirichlet de um conjunto de pontos usando o buffer de profundidade. Life in the Stencil Buffer explica como implementar o Game of Life usando o buffer do stencil. Usos alternativos para glDrawPixels () e glCopyPixels () descrevem como usar esses dois comandos para efeitos como o vídeo falso, a aerografia e as imagens transpostas. Gerenciamento de erros A verdade é que seu programa cometerá erros. O uso de rotinas de manipulação de erros é essencial durante o desenvolvimento e é altamente recomendado para aplicativos comercialmente lançados. (A menos que você possa dar uma garantia 100, seu programa nunca gerará uma condição de erro OpenGL. Obter real) O OpenGL possui rotinas simples de manipulação de erros para as bibliotecas GL e GLU básicas. Quando OpenGL detecta um erro (na base GL ou GLU), ele registra um código de erro atual. O comando que causou o erro é ignorado, portanto, não tem efeito no estado OpenGL ou no conteúdo framebuffer. (Se o erro gravado foi GLOUTOFMEMORY, no entanto, os resultados do comando são indefinidos.) Uma vez registrado, o código de erro atual não foi apagado - ou seja, erros adicionais não são registrados - até você chamar o comando de consulta glGetError (). Que retorna o código de erro atual. Depois que você consultou e apagou o código de erro atual, ou se não há nenhum erro para começar, glGetError () retorna o GLNOERROR. GLenum glGetError (void) Retorna o valor do sinalizador de erro. Quando um erro ocorre no GL ou GLU, o sinalizador de erro é definido como o valor do código de erro apropriado. Se GLNOERROR for retornado, não houve nenhum erro detectável desde a última chamada para glGetError (). Ou desde que o GL foi inicializado. Nenhum outro erro é gravado até glGetError (), o código de erro é retornado e o sinalizador é reiniciado para GLNOERROR. É altamente recomendável que você chame glGetError () pelo menos uma vez em cada rotina de exibição (). A Tabela 14-1 lista os códigos básicos de erro OpenGL definidos. Tabela 14-1: Códigos de erro OpenGL Não há memória suficiente para executar o comando Existem também trinta e sete erros de GLU NURBS (com nomes constantes não descritivos, GLUNURBSERROR1, GLUNURBSERROR2 e assim por diante), catorze erros de tesselador (GLUTESSMISSINGBEGINPOLYGON, GLUTESSMISSINGENDPOLYGON, GLUTESSMISSINGBEGINCONTOUR , GLUTESSMISSINGENDCONTOUR, GLUTESSCOORDTOOLARGE, GLUTESSNEEDCOMBINECALLBACK e oito genéricamente nomeados GLUTESSERROR) e GLUINCOMPATIBLEGLVERSION. Além disso, o GLU define os códigos de erro GLUINVALIDENUM, GLUINVALIDVALUE e GLUOUTOFMEMORY, que têm o mesmo significado que os códigos OpenGL relacionados. Para obter uma seqüência descritiva de impressão, que corresponde a um código de erro GL ou GLU, use a rotina GLU gluErrorString (). Const GLubyte gluErrorString (GLenum errorCode) Retorna um ponteiro para uma cadeia descritiva que corresponde ao número de erro OpenGL ou GLU passado no código de erro. No exemplo 14-1, uma simples rotina de tratamento de erros é mostrada. Exemplo 14-1: Consulta e impressão de um erro Nota: A string retornada por gluErrorString () não deve ser alterada ou liberada pelo aplicativo. Qual versão estou usando A portabilidade de aplicativos OpenGL é um dos recursos atraentes do OpenGL. No entanto, as novas versões do OpenGL apresentam novos recursos, que podem introduzir problemas de compatibilidade com versões anteriores. Além disso, você pode querer que sua aplicação seja tão boa em uma variedade de implementações. Por exemplo, você pode fazer mapeamento de textura no modo de renderização padrão em uma máquina, mas apenas tem sombreamento plano em outra. Você pode usar glGetString () para obter informações de versão sobre sua implementação OpenGL. Const GlGetString (nome do GLenum) Retorna um ponteiro para uma seqüência de caracteres que descreve um aspecto da implementação do OpenGL. O nome pode ser um dos seguintes: GLVENDOR, GLRENDERER, GLVERSION ou GLEXTENSIONS. GLVENDOR retorna o nome da empresa responsável pela implementação do OpenGL. GLRENDERER retorna um identificador do renderizador, que geralmente é a plataforma de hardware. Para mais informações sobre GLEXTENSIONS, veja a próxima seção, Extensions to the Standard. GLVERSION retorna uma string que identifica o número da versão desta implementação do OpenGL. A seqüência da versão é apresentada da seguinte forma: ltversion numbergtltspacegtltvendor-specific informationgt O número da versão é do formulário onde os números têm um ou mais dígitos. As informações específicas do fornecedor são opcionais. Por exemplo, se esta implementação OpenGL é da XYZ Corporação fictícia, a cadeia retornada pode ser o que significa que esta implementação é a quarta versão do XYZs de uma biblioteca OpenGL que está em conformidade com a especificação para OpenGL Versão 1.1. Provavelmente também significa que esta é a versão 3.2 do sistema operacional proprietário XYZs. Outra maneira de consultar o número da versão para o OpenGL é procurar a constante simbólica (use a declaração do préprocessador ifdef) chamada GLVERSION11. A ausência da constante GLVERSION11 significa que você tem OpenGL Versão 1.0. Nota: Se estiver executando de cliente para servidor, como, ao executar renderização indireta com a extensão OpenGL para o X Window System, o cliente e o servidor podem ser versões diferentes. Se a sua versão do cliente estiver à frente do seu servidor, seu cliente poderá solicitar uma operação que não seja suportada no seu servidor. Versão da biblioteca de utilidade gluGetString () é uma função de consulta para a biblioteca de utilitários (GLU) e é semelhante a glGetString (). Const GLubyte gluGetString (nome do GLenum) Retorna um ponteiro para uma seqüência de caracteres que descreve um aspecto da implementação do OpenGL. O nome pode ser um dos seguintes: GLUVERSION ou GLUEXTENSIONS. Observe que gluGetString () não estava disponível no GLU 1.0. Outra maneira de consultar o número da versão para GLU é procurar a constante simbólica GLUVERSION11. A ausência da constante GLUVERSION11 significa que você tem GLU 1.0. As extensões do OpenGL padrão possuem uma especificação escrita formal que descreve quais operações compõem a biblioteca. Um fornecedor individual ou um grupo de fornecedores pode decidir incluir funcionalidades adicionais para a implementação lançada. Novos nomes constantes constantes de rotina e simbólica indicam claramente se uma característica faz parte do padrão OpenGL ou uma extensão específica do fornecedor. Para criar um nome específico do fornecedor, o fornecedor anexa um identificador de empresa (em maiúsculas) e, se necessário, informações adicionais, como um nome de máquina. Por exemplo, se a XYZ Corporation quiser adicionar uma nova rotina e constante simbólica, eles podem ser da forma glCommandXYZ () e GLDEFINITIONXYZ. Se a XYZ Corporation quiser ter uma extensão disponível apenas em sua placa gráfica FooBar, os nomes podem ser glCommandXYZfb () e GLDEFINITIONXYZFB. Se dois mais vendedores concordarem em implementar a mesma extensão, os procedimentos e as constantes são sufixados com o EXT mais genérico (glCommandEXT () e GLDEFINITIONEXT). Se você quiser saber se uma extensão específica é suportada em sua implementação, use glGetString (GLEXTENSIONS). Isso retorna uma lista de todas as extensões na implementação, separadas por espaços. Se você quiser descobrir se uma extensão específica é suportada, use o código no Exemplo 14-2 para pesquisar a lista e combinar o nome da extensão. Retorne GLTRUE, se for GLFALSE, se não for. Exemplo 14-2: Saiba se uma extensão é suportada Translucência de queijo Você pode usar o estilingue de polígono para simular um material translúcido. Esta é uma solução especialmente boa para sistemas que não possuem hardware de mistura. Uma vez que os padrões de polígono stipple são 32x32 bits, ou 1024 bits, você pode ir de opaco para transparente em 1023 etapas. (Na prática, isso é muitas mais etapas do que você precisa) Por exemplo, se você quer uma superfície que deixe passar por 29 por cento da luz, simplesmente faça um padrão de stipple onde 29 por cento (aproximadamente 297) dos pixels na máscara são zero E o resto é um. Mesmo que suas superfícies tenham a mesma translucidez, não use o mesmo padrão de stipple para cada um, pois cobrem exatamente os mesmos bits na tela. Faça um padrão diferente para cada um selecionando aleatoriamente o número apropriado de pixels para ser zero. (Consulte Exibição de Pontos, Linhas e Polígonos no Capítulo 2 para obter mais informações sobre o estilingue de polígonos.) Se você não gosta do efeito com pixels aleatórios ativados, você pode usar padrões regulares, mas eles também não funcionam quando as superfícies transparentes são empilhadas. Isso muitas vezes não é um problema porque a maioria das cenas tem relativamente poucas regiões translúcidas que se sobrepõem. Em uma foto de um automóvel com janelas translúcidas, sua linha de visão pode atravessar no máximo duas janelas, e geralmente é única. Um efeito de desbotamento fácil Suponha que você tenha uma imagem que você deseja desaparecer gradualmente em alguma cor de fundo. Defina uma série de padrões de ponta de polígono, cada um dos quais tem mais bits ativados, de modo que eles representam padrões mais densos e mais densos. Em seguida, use esses padrões repetidamente com um polígono grande o suficiente para cobrir a região sobre a qual deseja desvanecer. Por exemplo, suponha que você queira desaparecer em preto em 16 etapas. Primeiro, defina 16 arrays de padrões diferentes: depois carregue-os de tal forma que cada um tenha um décimo sexto dos pixels em um padrão de 32 180 32 splpple ativado e que o OR bit a bit de todos os padrões de stipple seja todos esses. Depois disso, o seguinte código faz o truque: em algumas implementações OpenGL, você pode obter um melhor desempenho, primeiro compilando os padrões de stipple em listas de exibição. Durante a sua inicialização, faça algo como isto: em seguida, substitua esta linha no primeiro fragmento de código Ao compilar o comando para definir o ponto em uma lista de exibição, o OpenGL pode reorganizar os dados na matriz de capas no formulário específico do hardware Necessário para a velocidade máxima de ajuste de stipple. Outra aplicação para esta técnica é se você estiver desenhando uma imagem em mudança e quiser deixar algum borrão por trás, que gradualmente desaparece para dar uma indicação de movimento passado. Por exemplo, suponha que você esteja simulando um sistema planetário e você quer deixar trilhas nos planetas para mostrar uma parcela recente de seu caminho. Mais uma vez, supondo que você queira desvanecer-se em dezesseis etapas, configure os padrões de stipple como antes (usando a versão da lista de exibição, digamos), e tenha o circuito de simulação principal parecido com isto: Cada vez que o loop, você limpa, Décimo décimo dos pixels. Qualquer pixel que não tenha tido um planeta nele para dezesseis quadros é certo para ser limpo para preto. Claro, se o seu sistema suportar a mistura em hardware, é mais fácil misturar-se com uma certa quantidade de cor de fundo com cada quadro. (Consulte Exibição de Pontos, Linhas e Polígonos no Capítulo 2 para obter detalhes de pontilhamento de polígonos, Capítulo 7 para obter mais informações sobre listas de exibição e Combinação no Capítulo 6 para obter informações sobre a mistura.) Seleção de Objeto Usando o Buffer Voltar Embora o mecanismo de seleção OpenGL (veja A seleção no Capítulo 13) é poderosa e flexível, pode ser complicada de usar. Muitas vezes, a situação é simples: sua aplicação desenha uma cena composta por um número substancial de objetos que o usuário aponta para um objeto com o mouse e o aplicativo precisa encontrar o item sob a ponta do cursor. Uma maneira de fazer isso exige que seu aplicativo seja executado no modo de buffer duplo. Quando o usuário escolhe um objeto, o aplicativo redesenha toda a cena no buffer de retorno, mas em vez de usar as cores normais para objetos, ele codifica algum tipo de identificador de objeto para cada cor de objetos. O aplicativo então simplesmente lê o pixel abaixo do cursor e o valor desse pixel codifica o número do objeto escolhido. Se forem esperadas muitas escolhas para uma única imagem estática, você pode ler o buffer de cores inteira uma vez e olhar em sua cópia para cada tentativa de escolha, em vez de ler cada pixel individualmente. Note-se que este esquema tem uma vantagem em relação à seleção padrão, pois ele escolhe o objeto que está na frente se vários objetos aparecem no mesmo pixel, um atrás do outro. Uma vez que a imagem com cores falsas é desenhada no buffer de retorno, o usuário nunca vê que você pode redesenhar o buffer de volta (ou copiá-lo do buffer frontal) antes de trocar os buffers. No modo de índice de cores, a codificação é simples - envie o identificador do objeto como o índice. No modo RGBA, codifique os bits do identificador nos componentes R, G e B. Esteja ciente de que você pode ficar sem identificadores se houver muitos objetos na cena. Por exemplo, suponha que você esteja executando no modo de índice de cores em um sistema que tenha buffers de 4 bits para informações de índice de cores (16 possíveis índices diferentes) em cada um dos buffers de cores, mas a cena tem milhares de itens selecionáveis. Para resolver esta questão, a escolha pode ser feita em algumas passagens. Para pensar sobre isso em termos concretos, suponha que haja menos de 4096 itens, então todos os identificadores de objeto podem ser codificados em 12 bits. Na primeira passagem, desenhe a cena usando índices compostos dos 4 bits de alta ordem, então use as passagens segunda e terceira para desenhar os 4 bits do meio e os 4 bits de baixa ordem. Depois de cada passagem, leia o pixel sob o cursor, extraia os bits e os empacote no final para obter o identificador do objeto. Com este método, a colheita demora três vezes mais, mas isso geralmente é aceitável. Observe que depois de ter os 4 bits de alta ordem, você elimina 1516 de todos os objetos, então você realmente precisa desenhar apenas 116 deles para a segunda passagem. Da mesma forma, após a segunda passagem, 255 dos 256 itens possíveis foram eliminados. A primeira passagem, portanto, demora tanto quanto o desenho de um único quadro faz, mas as passagens segunda e terceira podem ser até 16 e 256 vezes mais rápido. Se você estiver tentando escrever um código portátil que funcione em diferentes sistemas, quebre seus identificadores de objetos em pedaços que se encaixam no menor denominador comum desses sistemas. Além disso, lembre-se de que seu sistema pode executar o dithering automático no modo RGB. Se for esse o caso, desative o dithering. Transformação de imagem barata Se você quiser desenhar uma versão distorcida de uma imagem bitmap (talvez simplesmente esticada ou girada, ou talvez modificada drasticamente por alguma função matemática), existem muitas possibilidades. Você pode usar a imagem como um mapa de textura, o que permite escalar, girar ou distorcer de outra forma a imagem. Se você quiser apenas dimensionar a imagem, você pode usar glPixelZoom (). Em muitos casos, você pode obter bons resultados desenhando a imagem de cada pixel como um quadrilátero. Embora este esquema não produza imagens tão agradáveis ​​quanto as que você obtém aplicando um algoritmo de filtragem sofisticado (e pode não ser suficiente para usuários sofisticados), é muito mais rápido. Para tornar o problema mais concreto, suponha que a imagem original é m pixels por n pixels, com coordenadas escolhidas entre 0, m -1 180 0, n -1. Deixe as funções de distorção serem x (m, n) e y (m, n). Por exemplo, se a distorção é simplesmente um zoom por um fator de 3.2, então x (m, n) 3.2 m e y (m, n) 3.2 n. O código a seguir desenha a imagem distorcida: Este código desenha cada pixel transformado em uma cor sólida igual a essa cor de pixels e dimensiona o tamanho da imagem em 3.2. A rotina setcolor () significa o que quer que o comando OpenGL apropriado seja para definir a cor do pixel da imagem. O seguinte é uma versão um pouco mais complexa que distorce a imagem usando as funções x (i, j) e y (i, j): uma imagem distorcida ainda melhor pode ser desenhada com o seguinte código: Este código interpola suavemente a cor em cada quadrilátero . Observe que esta versão produz um quadrilateral menos em cada dimensão do que as versões de sombra plana, pois a imagem colorida é usada para especificar cores nos vértices quadriláteros. Além disso, você pode antialias os polígonos com a função de mistura apropriada (GLSRCALPHA, GLONE) para obter uma imagem ainda mais agradável. Exibição de camadas Em algumas aplicações, como programas de layout de semicondutores, você deseja exibir várias camadas de materiais diferentes e indicar onde os materiais se sobrepõem. Como um exemplo simples, suponha que você tenha três substâncias diferentes que podem ser em camadas. Em qualquer ponto, podem ocorrer oito possíveis combinações de camadas, conforme mostrado na Tabela 14-2. Tabela 14-2: Oito Combinações de Camadas Você deseja que seu programa exiba oito cores diferentes, dependendo das camadas presentes. Uma possibilidade arbitrária é mostrada na última coluna da tabela. Para usar esse método, use o modo de índice de cores e carregue seu mapa de cores para que a entrada 0 seja preta, a entrada 1 é vermelha, a entrada 2 é verde e assim por diante. Observe que se os números de 0 a 7 forem escritos em binário, o 4 bit será ativado sempre que a camada 3 aparecer, o 2 bit sempre que a camada 2 aparecer e 1 bit sempre que a camada 1 for exibida. Para limpar a janela, defina o writemask como 7 (as três camadas) e defina a cor da limpeza para 0. Para desenhar sua imagem, defina a cor para 7 e, em seguida, quando quiser desenhar algo na camada n. Defina o writemask para n. Em outros tipos de aplicações, pode ser necessário apagar seletivamente em uma camada, caso em que você usaria os writemasks que acabamos de discutir, mas ajuste a cor para 0 em vez de 7. (Consulte o capítulo Mascarados no Capítulo 10 para obter mais informações sobre os dispositivos de reserva .) Caracteres anti-unidos Usando a técnica padrão para desenhar caracteres com glBitmap (). Desenhar cada pixel de um personagem é um caso de tudo ou nada - o pixel está ligado ou não. Se você estiver desenhando caracteres pretos em um fundo branco, por exemplo, os pixels resultantes são negros ou brancos, nunca um som de cinza. Podem ser obtidas imagens muito mais suaves e de maior qualidade se as cores intermediárias forem usadas ao renderizar caracteres (cinzas, neste exemplo). Supondo que você esteja desenhando caracteres pretos em um fundo branco, imagine uma imagem altamente ampliada dos pixels na tela, com um esboço de personagens de alta resolução sobreposto, como mostrado no lado esquerdo da Figura 14-1. Figura 14-1: Caracteres antialiased Observe que alguns dos pixels são completamente fechados pelo esboço dos caracteres e devem ser pintados de preto, alguns pixels estão completamente fora do contorno e devem ser pintados de branco, mas muitos pixels devem ser pintados de alguma forma com cinza, onde A escuridão do cinza corresponde à quantidade de preto no pixel. Se esta técnica for usada, a imagem resultante na tela parece melhor. Se a velocidade eo uso da memória não são preocupantes, cada caractere pode ser desenhado como uma imagem pequena em vez de como um bitmap. Se você estiver usando o modo RGBA, no entanto, esse método pode exigir até 32 bits por pixel do personagem a ser armazenado e desenhado, em vez do 1 bit por pixel em um caractere padrão. Alternativamente, você poderia usar um índice de 8 bits por pixel e converter esses índices para RGBA por pesquisa de tabela durante a transferência. Em muitos casos, é possível um compromisso que permite desenhar o personagem com alguns níveis de cinza entre preto e branco (digamos, dois ou três) e a descrição da fonte resultante requer apenas 2 ou 3 bits por pixel de armazenamento. Os números no lado direito da Figura 14-1 indicam a cobertura percentual aproximada de cada pixel: 0 significa aproximadamente vazio, 1 significa aproximadamente um terço de cobertura, 2 significa dois terços e 3 significa completamente coberto. Se os pixels rotulados com 0 forem pintados de branco, os pixels marcados com 3 são pintados de preto e os pixels identificados 1 e 2 são pintados de um terço e dois terços de preto, respectivamente, o caracter resultante parece muito bom. São necessários apenas 2 bits para armazenar os números 0, 1, 2 e 3, portanto, para 2 bits por pixel, quatro níveis de cinza podem ser salvos. Existem basicamente dois métodos para implementar caracteres antialiased, dependendo se você estiver no modo RGBA ou de índice de cores. No modo RGBA, defina três bitmaps de caracteres diferentes, correspondendo a onde 1, 2 e 3 aparecem na Figura 14-1. Defina a cor para branco e desmarque o plano de fundo. Defina a cor para um terço cinza (RGB (0.666, 0.666, 0.666)) e desenhe todos os pixels com um 1 deles. Em seguida, configure RGB (0.333, 0.333, 0.333), desenhe com o bitmap 2 e use RGB (0.0, 0.0, 0.0) para o bitmap 3. O que você está fazendo é definir três tipos de letra diferentes e redesenhar a corda três vezes, onde cada passagem preenche os bits das densidades de cor apropriadas. No modo de índice de cores, você pode fazer exatamente a mesma coisa, mas se você estiver disposto a configurar corretamente o mapa de cores e usar o writemasks, você pode sair com apenas dois mapas de bits por personagem e duas passagens por string. No exemplo anterior, configure um bitmap que tenha 1 onde 1 ou 3 apareça no personagem. Configure um segundo bitmap que tenha 1 onde seja exibido um 2 ou um 3. Carregue o mapa de cores para que 0 dê branco, 1 dê cinza claro, 2 dê cinza escuro e 3 dá preto. Defina a cor para 3 (11 em binário) eo writemask para 1, e desenhe o primeiro bitmap. Em seguida, mude o writemask para 2, e desenhe o segundo. Onde 0 aparece na Figura 14-1, nada é desenhado no framebuffer. Onde 1, 2 e 3 aparecem, 1, 2 e 3 aparecem no framebuffer. Para este exemplo com apenas quatro níveis de cinza, as economias são pequenas - duas passagens em vez de três. Se oito níveis de cinza fossem usados, o método RGBA exigiria sete passagens, e a técnica de mascaramento de mapa de cores exigiria apenas três. Com dezesseis níveis de cinza, a comparação é de quinze passagens para quatro passes. (Consulte Mascarar Buffers no Capítulo 10 para obter mais informações sobre writemasks e Bitmaps e Fontes no Capítulo 8 para obter mais informações sobre o desenho de mapas de bits.) Você pode ver como fazer a renderização RGBA sem mais imagens do que o caso de índice de cores otimizado. Dica: Como é Os fragmentos RGB normalmente são incorporados ao buffer de cores quando é desejável o anti-alinhamento Desenho de pontos redondos Desenhe pontos redondos e aliados, permitindo o antialiasamento do ponto, transformando a mistura e usando uma função alfa que passa apenas fragmentos com alfa maior que 0,5. (Consulte Antialiasing e Blending no Capítulo 6 para obter mais informações sobre esses tópicos.) Interpolando Imagens Suponha que você tenha um par de imagens (onde a imagem pode significar uma imagem bitmap ou uma imagem gerada usando a geometria da maneira usual) e você quer Misturar sem problemas de um para o outro. Isso pode ser feito facilmente usando o componente alfa e operações de mistura adequadas. Digamos que deseja realizar a mistura em dez passos, onde a imagem A é mostrada na moldura 0 e a imagem B é mostrada no quadro 9. A abordagem óbvia é desenhar a imagem A com alfa igual a (9 ampères) 9 e a imagem B Com um alfa de i 9 no quadro i. O problema com este método é que ambas as imagens devem ser desenhadas em cada quadro. Uma abordagem mais rápida é desenhar a imagem A no quadro 0. Para obter o quadro 1, misture em 19 da imagem B e 89 do que está lá. Para o quadro 2, misture em 18 da imagem B com 78 do que está lá. Para o quadro 3, misture em 17 da imagem B com 67 do que está lá, e assim por diante. Para o último passo, você está apenas desenhando 11 da imagem B misturada com 01 do que está à esquerda, produzindo a imagem B exatamente. Para ver se isso funciona, se for o quadro que você possui e você mistura em B (9 ampères) com (8 ampigr) (9 ampères) do que está lá, você obtém Fazer Decalques Suponha que você esteja desenhando uma imagem tridimensional complexa Usando buffer de profundidade para eliminar as superfícies ocultas. Suponha ainda que uma parte da sua imagem é composta de figuras coplanares A e B, onde B é uma espécie de decalque que sempre deve aparecer no topo da figura A. Sua primeira abordagem pode ser desenhar B depois de desenhar A, definindo a profundidade Função de tampa para substituir maior ou igual. Devido à precisão finita das representações de ponto flutuante dos vértices, no entanto, o erro de arredondamento pode fazer com que o polígono B seja às vezes um pouco na frente e às vezes um pouco atrás da figura A. Essa é uma solução para esse problema. Desative o buffer de profundidade para a escrita e processe A. Ative o buffer de profundidade para a escrita e renderize B. Desative o buffer de cor para gravação e processe A novamente. Ative o buffer de cores para a escrita. Observe que, durante todo o processo, o teste de buffer de profundidade está habilitado. Na etapa 1, A é renderizado onde quer que seja, mas nenhum dos valores do buffer de profundidade são alterados assim, no passo 2, onde B aparece sobre A, B é garantido para ser desenhado. O Passo 3 simplesmente garante que todos os valores de profundidade em A sejam atualizados corretamente, mas, uma vez que as gravações RGBA são desabilitadas, os pixels de cores não são afetados. Finalmente, o passo 4 retorna o sistema ao estado padrão (a gravação é ativada tanto no buffer de profundidade como no buffer de cores). Se um buffer de estêncil estiver disponível, a seguinte técnica mais simples funciona. Configure o buffer de gabarito para escrever um se o teste de profundidade for passada, e zero caso contrário. Render A. Configure o buffer do stencil para não alterar o valor do stencil, mas para renderizar apenas onde os valores do stencil são um. Desative o teste de profundidade-buffer e sua atualização. Render B. Com este método, não é necessário inicializar o conteúdo do buffer do stencil a qualquer momento, porque o valor do estêncil de todos os pixels de interesse (ou seja, aqueles representados por A) é definido quando A é renderizado. Certifique-se de reativar o teste de profundidade e desabilitar o teste do estêncil antes que os polígonos adicionais sejam desenhados. (Consulte Seleção de buffers de cores para escrita e leitura, Teste de profundidade e Teste de estêncil no Capítulo 10). Desenho de polígonos cheios, côncavos usando o tampão de estêncil. Considere o polígono côncavo 1234567 mostrado na Figura 14-2. Imagine que é desenhado como uma série de triângulos: 123, 134, 145, 156, 167, todos os quais são mostrados na figura. A linha mais pesada representa o limite original do polígono. Desenho de todos esses triângulos divide o buffer em nove regiões A, B, C. I, onde a região I está fora de todos os triângulos. Figura 14-2: Polígono côncavo No texto da figura, cada um dos nomes das regiões é seguido por uma lista dos triângulos que o cobrem. As regiões A, D e F compõem a nota de polígono original que essas três regiões são cobertas por um número ímpar de triângulos. Qualquer outra região é coberta por um número par de triângulos (possivelmente zero). Assim, para tornar o interior do polígono côncavo, você precisará renderizar regiões que estão incluídas em um número ímpar de triângulos. Isso pode ser feito usando o buffer stencil, com um algoritmo de duas passagens. Primeiro, limpe o buffer do estêncil e desative a escrita no buffer de cores. Em seguida, desenhe cada um dos triângulos por sua vez, usando a função GLINVERT no buffer do estêncil. (Para o melhor desempenho, use ventiladores triangulares.) Isso alterna o valor entre zero e um valor diferente de zero sempre que um triângulo é desenhado que cobre um pixel. Depois de todos os triângulos serem desenhados, se um pixel for coberto por um número par de vezes, o valor nos buffers do estêncil é zero caso contrário, não é zero. Finalmente, desenhe um grande polígono em toda a região (ou redesenhe os triângulos), mas permita desenhar somente onde o buffer do estêncil é diferente de zero. Nota: Há uma ligeira generalização da técnica anterior, onde você não precisa começar com um vértice de polígono. No exemplo 1234567, deixe P qualquer ponto de ligar ou desligar o polígono. Desenhe os triângulos: P12, P23, P34, P45, P56, P67 e P71. As regiões cobertas por um número ímpar de triângulos estão dentro de outras regiões estão lá fora. Esta é uma generalização na medida em que, se P passa a ser uma das bordas dos polígonos, um dos triângulos está vazio. Esta técnica pode ser usada para encher ambos os polígonos não-simples (polígonos cujas arestas se cruzam) e polígonos com furos. O exemplo a seguir ilustra como lidar com um polígono complicado com duas regiões, um de quatro lados e um de cinco lados. Suponha ainda que há um furo triangular e um furo de quatro lados (não importa em quais regiões estão os orifícios). Deixe as duas regiões abcd e efghi, e os buracos jkl e mnop. Deixe z ser qualquer ponto no avião. Desenhe os seguintes triângulos: zab zbc zcd zda zef zfg zgh zhi zie zjk zkl zlj zmn zno zop zpm Marcar regiões cobertas por um número ímpar de triângulos como em. E aqueles cobertos por um número par como fora. (Consulte o Teste do Estêncil no Capítulo 10 para obter mais informações sobre o buffer do estêncil.) Encontrar regiões de interferência Se você estiver projetando uma peça mecânica feita de peças tridimensionais menores, você geralmente quer mostrar regiões onde as peças se sobrepõem. In many cases, such regions indicate design errors where parts of a machine interfere with each other. In the case of moving parts, it can be even more valuable, since a search for interfering regions can be done through a complete mechanical cycle of the design. The method for doing this is complicated, and the description here might be too brief. Complete details can be found in the paper Interactive Inspection of Solids: Cross-sections and Interferences . by Jarek Rossignac, Abe Megahed, and Bengt-Olaf Schneider (SIGGRAPH 1992 Proceedings). The method is related to the capping algorithm described in Stencil Test in Chapter 10. The idea is to pass an arbitrary clipping plane through the objects that you want to test for interference, and then determine when a portion of the clipping plane is inside more than one object at a time. For a static image, the clipping plane can be moved manually to highlight interfering regions for a dynamic image, it might be easier to use a grid of clipping planes to search for all possible interferences. Draw each of the objects you want to check and clip them against the clipping plane. Note which pixels are inside the object at that clipping plane using an odd-even count in the stencil buffer, as explained in the preceding section. (For properly formed objects, a point is inside the object if a ray drawn from that point to the eye intersects an odd number of surfaces of the object.) To find interferences, you need to find pixels in the framebuffer where the clipping plane is in the interior of two or more regions at once in other words, in the intersection of the interiors of any pair of objects. If multiple objects need to be tested for mutual intersection, store 1 bit every time some intersection appears, and another bit wherever the clipping buffer is inside any of the objects (the union of the objects interiors). For each new object, determine its interior, find the intersection of that interior with the union of the interiors of the objects so far tested, and keep track of the intersection points. Then add the interior points of the new object to the union of the other objects interiors. You can perform the operations described in the preceding paragraph by using different bits in the stencil buffer together with various masking operations. Three bits of stencil buffer are required per pixel - one for the toggling to determine the interior of each object, one for the union of all interiors discovered so far, and one for the regions where interference has occurred so far. To make this discussion more concrete, assume the 1 bit of the stencil buffer is for toggling interiorexterior, the 2 bit is the running union, and the 4 bit is for interferences so far. For each object that youre going to render, clear the 1 bit (using a stencil mask of one and clearing to zero), then toggle the 1 bit by keeping the stencil mask as one and using the GLINVERT stencil operation. You can find intersections and unions of the bits in the stencil buffers using the stenciling operations. For example, to make bits in buffer 2 be the union of the bits in buffers 1 and 2, mask the stencil to those 2 bits, and draw something over the entire object with the stencil function set to pass if anything nonzero occurs. This happens if the bits in buffer 1, buffer 2, or both are turned on. If the comparison succeeds, write a 1 in buffer 2. Also, make sure that drawing in the color buffer is disabled. An intersection calculation is similar - set the function to pass only if the value in the two buffers is equal to 3 (bits turned on in both buffers 1 and 2). Write the result into the correct buffer. (See Stencil Test in Chapter 10 .) Every possible projection of three-dimensional space to three-dimensional space can be achieved with a suitable 4 180 4 invertible matrix and homogeneous coordinates. If the matrix isnt invertible but has rank 3, it projects three-dimensional space onto a two-dimensional plane. Every such possible projection can be achieved with a suitable rank-3 4 180 4 matrix. To find the shadow of an arbitrary object on an arbitrary plane from an arbitrary light source (possibly at infinity), you need to find a matrix representing that projection, multiply it on the matrix stack, and draw the object in the shadow color. Keep in mind that you need to project onto each plane that youre calling the ground. As a simple illustration, assume the light is at the origin, and the equation of the ground plane is ax by c d 0. Given a vertex S( sx, sy, sz ,1), the line from the light through S includes all points ampagr S, where ampagr is an arbitrary real number. The point where this line intersects the plane occurs when ampagr ( asz bsy csz ) d 0, ampagr - ampdgr ( asx bsy csz ). Plugging this back into the line, we get - ampdgr ( ampsgr ampxgr. ampsgr amppsgr. ampsgr ampzgr )( ampagr ampsgr ampxgr ampbgr ampsgr amppsgr ampkhgr ampsgr ampzgr ) for the point of intersection. The matrix that maps S to this point for every S is This matrix can be used if you first translate the world so that the light is at the origin. If the light is from an infinite source, all you have is a point S and a direction D ( dx, dy, dz ). Points along the line are given by Proceeding as before, the intersection of this line with the plane is given by a(sx ampagr dx)b(sy ampagr dy)c(sz ampagr dz)d 0 Solving for ampagr. plugging that back into the equation for a line, and then determining a projection matrix gives This matrix works given the plane and an arbitrary direction vector. Theres no need to translate anything first. (See Chapter 3 and Appendix F .) Hidden-Line Removal If you want to draw a wireframe object with hidden lines removed, one approach is to draw the outlines using lines and then fill the interiors of the polygons making up the surface with polygons having the background color. With depth-buffering enabled, this interior fill covers any outlines that would be obscured by faces closer to the eye. This method would work, except that theres no guarantee that the interior of the object falls entirely inside the polygons outline in fact, it might overlap it in various places. Theres an easy, two-pass solution using either polygon offset or the stencil buffer. Polygon offset is usually the preferred technique, since polygon offset is almost always faster than stencil buffer. Both methods are described here, so you can see how both approaches to the problem work. Hidden-Line Removal with Polygon Offset To use polygon offset to accomplish hidden-line removal, the object is drawn twice. The highlighted edges are drawn in the foreground color, using filled polygons but with the polygon mode GLLINE to rasterize it as a wireframe. Then the filled polygons are drawn with the default polygon mode, which fills the interior of the wireframe, and with enough polygon offset to nudge the filled polygons a little farther from the eye. With the polygon offset, the interior recedes just enough that the highlighted edges are drawn without unpleasant visual artifacts. You may need to adjust the amount of offset needed (for wider lines, for example). (See Polygon Offset in Chapter 6 for more information.) Hidden-Line Removal with the Stencil Buffer Using the stencil buffer for hidden-line removal is a more complicated procedure. For each polygon, youll need to clear the stencil buffer, and then draw the outline both in the framebuffer and in the stencil buffer. Then when you fill the interior, enable drawing only where the stencil buffer is still clear. To avoid doing an entire stencil-buffer clear for each polygon, an easy way to clear it is simply to draw 0s into the buffer using the same polygon outline. In this way, you need to clear the entire stencil buffer only once. For example, the following code represents the inner loop you might use to perform such hidden-line removal. Each polygon is outlined in the foreground color, filled with the background color, and then outlined again in the foreground color. The stencil buffer is used to keep the fill color of each polygon from overwriting its outline. To optimize performance, the stencil and color parameters are changed only twice per loop by using the same values both times the polygon outline is drawn. Texture-Mapping Applications Texture mapping is quite powerful, and it can be used in some interesting ways. Here are a few advanced applications of texture mapping. Antialiased text - Define a texture map for each character at a relatively high resolution, and then map them onto smaller areas using the filtering provided by texturing. This also makes text appear correctly on surfaces that arent aligned with the screen, but are tilted and have some perspective distortion. Antialiased lines - These can be done like antialiased text: Make the line in the texture several pixels wide, and use the texture filtering to antialias the lines. Image scaling and rotation - If you put an image into a texture map and use that texture to map onto a polygon, rotating and scaling the polygon effectively rotates and scales the image. Image warping - As in the preceding example, store the image as a texture map, but map it to some spline-defined surface (use evaluators). As you warp the surface, the image follows the warping. Projecting images - Put the image in a texture map, and project it as a spotlight, creating a slide projector effect. (See The q Coordinate in Chapter 9 for more information about how to model a spotlight using textures.) (See Chapter 3 for information about rotating and scaling, Chapter 9 for more information about creating textures, and Chapter 12 for details on evaluators.) Drawing Depth-Buffered Images For complex static backgrounds, the rendering time for the geometric description of the background can be greater than the time it takes to draw a pixel image of the rendered background. If theres a fixed background and a relatively simple changing foreground, you may want to draw the background and its associated depth-buffered version as an image rather than render it geometrically. The foreground might also consist of items that are time-consuming to render, but whose framebuffer images and depth buffers are available. You can render these items into a depth-buffered environment using a two-pass algorithm. For example, if youre drawing a model of a molecule made of spheres, you might have an image of a beautifully rendered sphere and its associated depth-buffer values that were calculated using Phong shading or ray-tracing or by using some other scheme that isnt directly available through OpenGL. To draw a complex model, you might be required to draw hundreds of such spheres, which should be depth-buffered together. To add a depth-buffered image to the scene, first draw the images depth-buffer values into the depth buffer using glDrawPixels() . Then enable depth-buffering, set the writemask to zero so that no drawing occurs, and enable stenciling such that the stencil buffers get drawn whenever a write to the depth buffer occurs. Then draw the image into the color buffer, masked by the stencil buffer youve just written so that writing occurs only when theres a 1 in the stencil buffer. During this write, set the stenciling function to zero out the stencil buffer so that its automatically cleared when its time to add the next image to the scene. If the objects are to be moved nearer to or farther from the viewer, you need to use an orthographic projection in these cases, you use GLDEPTHBIAS with glPixelTransfer() to move the depth image. (See Coordinate System Survival Kit in Chapter 2. Depth Test and Stencil Test in Chapter 10. and Chapter 8 for details on glDrawPixels() and glPixelTransfer() .) Dirichlet Domains Given a set S of points on a plane, the Dirichlet domain or Voronoi polygon of one of the points is the set of all points in the plane closer to that point than to any other point in the set S. These points provide the solution to many problems in computational geometry. Figure 14-3 shows outlines of the Dirichlet domains for a set of points. Figure 14-3 : Dirichlet Domains If you draw a depth-buffered cone with its apex at the point in a different color than each of the points in S, the Dirichlet domain for each point is drawn in that color. The easiest way to do this is to precompute a cones depth in an image and use the image as the depth-buffer values as described in the preceding section. You dont need an image to draw in the framebuffer as in the case of shaded spheres, however. While youre drawing into the depth buffer, use the stencil buffer to record the pixels where drawing should occur by first clearing it and then writing nonzero values wherever the depth test succeeds. To draw the Dirichlet region, draw a polygon over the entire window, but enable drawing only where the stencil buffers are nonzero. You can do this perhaps more easily by rendering cones of uniform color with a simple depth buffer, but a good cone might require thousands of polygons. The technique described in this section can render much higher-quality cones much more quickly. (See A Hidden-Surface Removal Survival Kit in Chapter 5 and Depth Test in Chapter 10 .) Life in the Stencil Buffer The Game of Life, invented by John Conway, is played on a rectangular grid where each grid location is alive or dead. To calculate the next generation from the current one, count the number of live neighbors for each grid location (the eight adjacent grid locations are neighbors). A grid location is alive in generation n 1 if it was alive in generation n and has exactly two or three live neighbors, or if it was dead in generation n and has exactly three live neighbors. In all other cases, it is dead in generation n 1. This game generates some incredibly interesting patterns given different initial configurations. (See Martin Gardner, Mathematical Games, Scientific American . vol. 223, no. 4, October 1970, p. 120123.) Figure 14-4 shows six generations from a game. Figure 14-4 : Six Generations from the Game of Life One way to create this game using OpenGL is to use a multipass algorithm. Keep the data in the color buffer, one pixel for each grid point. Assume that black (all zeros) is the background color, and the color of a live pixel is nonzero. Initialize by clearing the depth and stencil buffers to zero, set the depth-buffer writemask to zero, and set the depth comparison function so that it passes on not-equal. To iterate, read the image off the screen, enable drawing into the depth buffer, and set the stencil function so that it increments whenever a depth comparison succeeds but leaves the stencil buffer unchanged otherwise. Disable drawing into the color buffer. Next, draw the image eight times, offset one pixel in each vertical, horizontal, and diagonal direction. When youre done, the stencil buffer contains a count of the number of live neighbors for each pixel. Enable drawing to the color buffer, set the color to the color for live cells, and set the stencil function to draw only if the value in the stencil buffer is 3 (three live neighbors). In addition, if this drawing occurs, decrement the value in the stencil buffer. Then draw a rectangle covering the image this paints each cell that has exactly three live neighbors with the alive color. At this point, the stencil buffers contain 0, 1, 2, 4, 5, 6, 7, 8, and the values under the 2s are correct. The values under 0, 1, 4, 5, 6, 7, and 8 must be cleared to the dead color. Set the stencil function to draw whenever the value is not 2, and to zero the stencil values in all cases. Then draw a large polygon of the dead color across the entire image. Youre done. For a usable demonstration program, you might want to zoom the grid up to a size larger than a single pixel its hard to see detailed patterns with a single pixel per grid point. (See Coordinate System Survival Kit in Chapter 2. and Depth Test and Stencil Test in Chapter 10 .) Alternative Uses for glDrawPixels() and glCopyPixels() You might think of glDrawPixels() as a way to draw a rectangular region of pixels to the screen. Although this is often what its used for, some other interesting uses are outlined here. Video - Even if your machine doesnt have special video hardware, you can display short movie clips by repeatedly drawing frames with glDrawPixels() in the same region of the back buffer and then swapping the buffers. The size of the frames you can display with reasonable performance using this method depends on your hardwares drawing speed, so you might be limited to 100 180 100 pixel movies (or smaller) if you want smooth fake video. Airbrush - In a paint program, your airbrush (or paintbrush) shape can be simulated using alpha values. The color of the paint is represented as the color values. To paint with a circular brush in blue, repeatedly draw a blue square with glDrawPixels() where the alpha values are largest in the center and taper to zero at the edges of a circle centered in the square. Draw using a blending function that uses alpha of the incoming color and (1-alpha) of the color already at the pixel. If the alpha values in the brush are all much less than one, you have to paint over an area repeatedly to get a solid color. If the alpha values are near one, each brush stroke pretty much obliterates the colors underneath. Filtered Zooms - If you zoom a pixel image by a nonintegral amount, OpenGL effectively uses a box filter, which can lead to rather severe aliasing effects. To improve the filtering, jitter the resulting image by amounts less than a pixel and redraw it multiple times, using alpha blending to average the resulting pixels. The result is a filtered zoom. Transposing Images - You can swap same-size images in place with glCopyPixels() using the XOR operation. With this method, you can avoid having to read the images back into processor memory. If A and B represent the two images, the operation looks like this:Moving Landscapes Matharoo Associates The idea for moving landscape germinated from stumbling upon a stone, Bidasar Forest, that possesses an impression, as if, of tropical arid landscape fossilized within itself. Suas superfícies polidas contra a vegetação nativa da região de Ahmedabad foram feitas para o cenário perfeito, desfocando as linhas entre realidade e ilusão. Salve esta imagem A economia crescente das nações na última década tornou as casas individuais acessíveis a uma parte maior da sociedade. Juntamente com a demanda por uma independência que protege a individualidade, a antiga tradição da vida familiar comum se desintegrou em pequenas famílias nucleares. Apesar desta mudança de atitude cultural no atual contexto indiano, um grande número de famílias, vinculadas por negócios familiares e obrigadas pelos valores tradicionais enraizados, ainda escolhem viver juntos. Embora isso lhes permita beneficiar de uma responsabilidade compartilhada ao longo das gerações, muitas vezes leva à criação de conjuntos autônomos dentro de uma casa que isola famílias mesmo sob o mesmo teto. O desafio consiste, portanto, em integrar simultaneamente os requisitos desses estilos de vida opostos - tornando igualmente imperativo proporcionar oportunidades de colisão comunal, ao mesmo tempo em que proporciona privacidade. Situado nos arredores de Ahmedabad. A casa destina-se a acomodar um dos desenvolvedores imobiliários mais prolíficos da cidade e sua esposa, juntamente com as famílias de seus dois filhos e membros visitantes estendidos. O cliente também compartilha os motivos com suas duas outras casas de irmãos e suas famílias conjuntas em uma grande parcela de 20000 m2. Salvar esta imagem O plano da casa é interpretado como um pavilhão linear, garantindo que todo espaço na casa seja revestido com vidro nos lados opostos do primeiro recinto. O resto da estrutura está em paredes finas de 200 mm de concreto, eliminando a necessidade de qualquer viga e colunas e fazendo volumes internos mais limpos. Além disso, isso economiza espaço morto construído em cerca de 3 e para a área coberta total de 18.000, isso equivale a 540 pés quadrados ou o tamanho de uma sala de tamanho médio. Este pavilhão é orientado em torno da margem do site como três asas. Os flancos mantêm as casas espaços privados com suítes para cada família dos filhos, enquanto o central hospeda o espaço vital para todas as atividades comunitárias. Os vazios de canto residual pelo giro dos blocos, são protegidos confortavelmente por paredes circulares altas para formar espaços abrigados menores enquanto um acumula o espaço útil das casas, o outro atua como um tribunal distante do olhar das famílias conjuntas. Eles também carregam as escadas e levantam, tornando os espaços exteriores livres de todos os encargos para que o drama de Bidasar se desenrolle. A composição como uma pegada total define um grande pátio multifamiliar no coração do site. Salvar esta imagem O segundo recinto é uma camada de maciça 15 de altura, 9 de largura e 16 milímetros de espessura paredes de pedra Bidaser ao longo de todo o perímetro um invólucro inexpugnável. À semelhança do amethysts duro exterior quebrando aberto para revelar seu coração cristalino, pressionando um botão, esta parede de pedra impetuamente pesada se quebra, quando se torna uma série de painéis girando suavemente sobre seus centros ou deslizando para revelar um interior de cassete transparente . Pode ser empregado na vontade quando desejado e dissolvido quando não. Salvar esta imagem Esta camada de painéis de pedra ajuda a criar um amortecedor entre o interior e o exterior, protegendo a camada interna de concreto e vidro de luz solar intensa e 45 calor, reduzindo assim o ganho de calor total no ar-condicionado. Além disso, este espaço se dobra como passagens, varandas, vestíbulo de entrada e espaço de circulação, e também como proteção contra a chuva, eliminando a necessidade de ar condicionado em 8000sq. ft de um total de 18000 espaços habitáveis. Esta economia é substituída por uma vida melhorada e contato direto com a natureza no que chamamos de arquitetura de valor. Salve esta imagem Economias do ar-condicionado e selagem da casa, é canalizada para criar pivôs motorizados personalizados e sistemas deslizantes gigantes. Arquitetural e estruturalmente, esta camada inteira é mantida completamente separada da estrutura interna, quase como um tampão de calor, e só é suportada em estruturas ocultas dentro dos sistemas deslizantes e giratórios, fazendo com que as espessas lajes de concreto flutuem em movimento Pedras. Salvar esta foto As luzes são usinadas fora de pedra de alabastro proporcionando o ambiente mais natural. A maioria dos móveis é comprada a partir de várias casas de design na Itália e uma única mesa de bar é um personalizado projetado pelos Arquitetos. É uma tira mobius de 3 dimensões em aço inoxidável, fabricada localmente, que pode ser objeto de discussão e discurso intelectual após um par de bebidas. As luzes e a água sob as paredes móveis acendem a água para que as pedras pesadas aparecem flutuando na água. Os banheiros também estão abertos nas extremidades opostas e no armário de água, no chuveiro e na bacia, os três estão posicionados em 3 lados do duto, o quarto lado esquerdo para fácil acesso ao serviço e ventilação do duto de fora. Para continuar com o material Apoio de peso do amplificador ainda mais, o contador de bacia de concreto grosso é em voladuría do espelho do chão ao teto. Em consonância com a mesma filosofia da manutenção fácil e manutenção, as unidades de CA foram mantidas no telhado com apenas furos cortados em laje para o ventilador. Esta abordagem de integrar os serviços e os interiores na própria construção não só facilita o atendimento, mas também economizou muito tempo fora da construção. Todo o edifício estava pronto em 18 meses desde o início até o mobiliário. Salve esta imagem Respondendo com os aspectos mais duros da natureza, em movimento, essas paredes se misturam com o vidro dentro e a paisagem selvagem do lado de fora, o terceiro recinto, para às vezes permitir um glimado ao ar livre, às vezes refletem-lo e às vezes se refletem. É nessa camada de espaço e tela, o envelope inteiro de casas se torna uma interface para mediar entre o artifício do interior e o site verdejante no exterior. Salve esta imagem Os arredores das casas parecem profundos dentro de seu interior, já que a casa se funde em uma ilusão de paisagem constantemente em movimento, às vezes nos atrapalhamos refletindo entre eles, refletindo sobre a natureza, tanto dentro como fora de nós. O caráter de sua experiência é encontrado na passagem da entrada da casa, onde todas essas reflexões encontram a superfície da água para tornar a paisagem verdadeiramente em movimento. Texto: Robert Taylor amp Trisha Patel O melhor do ArchDaily, diretamente na sua caixa de entrada

No comments:

Post a Comment