5.4 Fluxo de processamento
5.4.2 Interface de entrada (CPU-GPU)
Para iniciar o processamento de atributos na GPU, a arquitetura requer que a aplicação forneça a seguinte seqüência de dados de entrada para cada modelo geométrico a ser processado:
• Buffer de vértices da geometria original, idêntico ao buffer de vértices utilizado na renderização do modelo para visualização, porém com um atributo adicional contendo o índice do vértice no buffer. Esse índice é utilizado pela arquitetura durante os estágios de processamento 1, 2 e 3 para calcular o índice 2D de acesso das texturas que contém dados da geometria e topologia do modelo. O procedimento de conversão do índice 1D para 2D é detalhado na seção 4.1.1. Cada vértice deve conter também os atributos definidos na aplicação (atributos de entrada) necessários para calcular os atributos que serão processados na GPU e armazenados nos buffers de renderização não visíveis (atributos de saída). Esses dados podem ser fornecidos através do comando SetVertexBuffer() que recebe o ponteiro do buffer de vértices. Internamente, a arquitetura utiliza esse buffer de vértices para criar as texturas que serão utilizadas nos estágios 1, 2 e 3.
Os atributos de entrada exigidos para o cálculo de cada atributo de saída são citados na seção 5.3. Por exemplo, o cálculo do valor de profundidade requer apenas a existência da posição 3D como atributo de entrada de cada vértice no buffer de vértices. O cálculo dos pesos das coordenadas baricêntricas requer, como atributo de entrada, os valores 0, 1 e 2 designados para cada um dos
5.4 Fluxo de processamento 115 três vértices de cada face. Esses valores devem ser definidos pela aplicação e acrescentados ao bufferde vértices da geometria original.
• Buffer de índices da geometria original, idêntico ao buffer de índices aos vértices utilizado na renderização do modelo para visualização. Esses dados podem ser fornecidos através do comando SetIndexBuffer() que recebe o ponteiro do buffer de índices. Cada seqüência de três índices do buffer deve corresponder a um triângulo. Internamente, a arquitetura utiliza esses dados para determinar a vizinhança de 1-anel de cada vértice, e armazenar esses dados em texturas que serão utilizadas no estágio 2.
• Relação dos atributos que devem ser processados pela GPU e armazenados para cada pixel do modelo renderizado. Essa relação pode ser qualquer combinação dos atributos citados na seção 5.3, e pode ser fornecida à arquitetura através do comando SetAttributes(). • Mapeamento da semântica dos atributos de entrada, entre a API gráfica e a arquitetura de in-
teração. Nas APIs gráficas, os atributos de cada vértice da geometria original possuem uma semântica pré-definida, necessária para a correta interpretação de cada atributo na entrada do processador de vértices ou no fluxo de função fixa de visualização. Por exemplo, um vértice pode ser composto de valores cuja semântica, do ponto de vista da API gráfica, é uma posição 3D, coordenadas de textura 2D, um valor de cor difusa ou tamanho do ponto. Do ponto de vista da arquitetura proposta, tais atributos podem ter outra semântica. Por exemplo, valores numéricos designados aos vértices com semântica de tamanho do ponto (do ponto de vista da API), podem ser interpretados pela arquitetura de interação como um identificador de vértice, ou como um valor genérico com semântica definida pela aplicação.
Esse mapeamento pode ser fornecido à arquitetura através do comando BindSemantics() que recebe duas listas cujos valores são mapeados biunivocamente. A primeira lista contém as semânticas dos atributos dos vértices segundo a API gráfica. A segunda lista contém as semânticas dos atributos dos vértices segundo a arquitetura de interação.
• Coordenadas da região de interesse. A extensão espacial da codificação dos atributos das ge- ometrias processadas é configurada de acordo com a definição de uma região retangular de interesse, especificada em coordenadas da janela. Para tarefas simples de interação como se- leção e posicionamento restrito à superfície mais próxima, essa região pode envolver apenas o pixelapontado pelo cursor 2D controlado pelo dispositivo apontador. Nessas tarefas, as primiti- vas sob interação são apenas as primitivas apontadas pelo cursor 2D. Primitivas situadas fora da região de interesse são descartadas e o processamento de fragmentos é reduzido a fragmentos dentro dessa região. Em tarefas de posicionamento com restrição a vértices, arestas, ou caracte-
rísticas da imagem, a região de interesse pode determinar a extensão do “campo de gravidade”, pois a aplicação pode fazer com que o cursor 2D seja atraído à característica mais próxima dentro da região de interesse.
Esses dados podem ser fornecidos à arquitetura através do comando SetROI() que recebe como parâmetros as coordenadas 2D do canto superior esquerdo e canto inferior direito da região de interesse.
• Shaders de deformação de vértices, definidos pela aplicação. Aplicam-se apenas quando há modificação dos atributos de vértices de entrada, ou dos atributos produzidos pelo estágio de cálculo de atributos geométricos. Quando utilizado no primeiro estágio, o shader de defor- mação de vértices recebe como parâmetro de entrada os atributos da geometria original (com os tipos de dados e semântica definidas anteriormente) e produz como saída a mesma lista de atributos, mas com valores possivelmente alterados segundo o processamento definido pela aplicação. A entrada do shader de deformação de vértices utilizado no terceiro estágio inclui não só todos os parâmetros do primeiro estágio, como também os novos atributos correspon- dentes às propriedades de geometria diferencial estimadas no segundo estágio.
Esses dados podem ser fornecidos à arquitetura através de dois comandos, SetPreVertex- Deform() e SetPostVertexDeform(), que recebem como parâmetro uma string de texto contendo o código do shader de modificação de atributos de vértices. O comando Set- PreVertexDeform() recebe o shader a ser executado antes da etapa de estimativa de propriedades de geometria diferencial. O comando SetPostVertexDeform() recebe o shadera ser executado após a etapa de estimativa de propriedades de geometria diferencial.
• Shader de deformação de fragmentos, definido pela aplicação. Aplica-se apenas quando há mo- dificação dos atributos de entrada interpolados ao longo de cada fragmento produzido durante a rasterização. A entrada do shader de deformação de fragmentos recebe como parâmetros os atributos de entrada (com os tipos de dados e semântica definidas anteriormente) interpolados linearmente pelo rasterizador, e produz como saída a mesma lista de atributos, mas com valores possivelmente alterados segundo o processamento definido pela aplicação.
Esses dados podem ser fornecidos à arquitetura através do comando SetPixelDeform() que recebe como parâmetro uma string de texto contendo o código do shader de modificação de atributos de fragmentos.
• Função de chamada de retorno a ser utilizada pela arquitetura quando a atualização dos atri- butos de vértices (estágio 1) e estimativa das propriedades de geometria diferencial (estágio 2)
5.4 Fluxo de processamento 117 forem realizadas. Tal função deve conter a chamada do comando de renderização das primitivas construídas com os buffers de vértices da geometria original indexada.
A função de chamada de retorno não deve chamar nenhuma função de modificação do estado de renderização relacionado ao preenchimento das primitivas, como modificação do estado GL_POLYGON_MODE do OpenGL ou D3DFILLMODE do Direct3D, pois isso pode interferir na execução dos shaders internos chamados pela arquitetura. Também não é permitido modifi- car os shaders dentro desta função, mas é possível atribuir valores aos registradores constantes e texturas utilizadas pelo shader de modificação de atributos de vértices do estágio 1.
Essa função de chamada de retorno pode ser informada à arquitetura através do comando SetUpdateCallback()que recebe como parâmetro o ponteiro da função.
• Função de chamada de retorno a ser utilizada pela arquitetura quando os estágios 3, 4 e 5 forem executados. Assim como na função de chamada de retorno dos estágios 1 e 2, tal função deve conter a chamada do comando de renderização das primitivas construídas com os buffers de vértices da geometria original. Essas funções podem modificar quaisquer estados de renderiza- ção, com exceção da modificação dos shaders que estão sendo utilizados, pois isto é definido internamente pela arquitetura.
Duas funções de chamada de retorno podem ser utilizadas: uma para renderizar geometria indexada e outra para renderizar geometria não indexada. Essas funções podem ser informadas à arquitetura através de um comando SetRenderCallback() que recebe como parâmetros os ponteiros das funções.
A definição das primitivas construídas com os atributos de vértices e a decisão sobre o uso de geometria indexada são obtidas diretamente através do uso das funções de renderização da API nas funções de chamada de retorno. Outros dados de entrada utilizados na renderização dos atributos, tais como os registradores constantes contendo os parâmetros das funções de deformação, e conjuntos de texturas contendo dados para modificação dos atributos de fragmentos, têm seu uso definido pela própria aplicação dentro dos shaders de deformação de vértices ou fragmentos.