2
INF2610 – Renderização em Tempo Real Trabalho 2: Programação em shaders Usando novamente o código exemplo para visualização de um conjunto de esferas sobre um plano como base, implemente: 1. Uma abstração para a definição de shaders. 2. Shaders de vértice e fragmento para tratar iluminação por vértice, obtendo o mesmo resultado visual do programa com o pipeline convencional. 3. Shaders de vértice e fragmento para tratar iluminação por fragmento. Compare a qualidade e o desempenho das duas abordagens. Descrição: 1. Crie uma classe para facilitar o uso das funções do OpenGL responsáveis por criar, compilar, linkar, validar e habilitar shaders e afins. Uma sugestão de interface é apresentada a seguir. Nesta interface, os métodos VertexShader e FragmentShader criam os shaders e os compilam. Se ocorrer erro de compilação, os métodos sinalizam retornando false, e a mensagem de erro correspondente pode ser acessada via o método GetMessage. O método Link também retorna um valor booleano indicando sucesso ou erro, e disponibiliza uma mensagem no caso de erro. O método Validate adota a mesma estratégia; esse método valida o programa em função do estado corrente do OpenGL; pode ser muito útil para identificar erros de programação (veja glValidateProgram). Os métodos Load/Unload ativam/desativam o programa como parte do pipeline gráfico. class Shader { Shader (); ~Shader (); bool VertexShader (const char* source); bool FragmentShader (const char* source); bool Link (); bool Validate (); const char* GetMessage (); void Load (); void Unload (); void SetUniform (const char* name, float x); void SetUniform (const char* name, float x, float y); void SetUniform (const char* name, float x, float y, float z); void SetUniform (const char* name, float x, float y, float z, float w); void SetUniform (const char* name, int size, int count, float* v) ; void SetUniformI (const char* name, int x); void SetUniformI (const char* name, int x, int y); void SetUniformI (const char* name, int x, int y, int z); void SetUniformI (const char* name, int x, int y, int z, int w); void SetUniformI (const char* name, int size, int count, int* v) ; void SetUniformMatrix (const char* name, int row, int col, int count, float* v); }; 2. Usando a abstração do item anterior, escreva shaders para fazer a iluminação por vértice da cena. A aplicação deve fazer uso apenas do novo padrão do OpenGL (v. 3.3 ou posterior). Assim, a API de array utilizada para especificar coordenadas e normais do pipeline convencional (glVertexPointer e glNormalPointer) devem ser substituídas pelas funções de atributo sem semântica (glVertexAttribPointer). Similarmente, não se pode usar as funções de transformação como glLoadMatrix. O resultado deve ser o mesmo que o obtido pelo programa usando o pipeline convencional. Utilize os mesmos parâmetros de iluminação (posição da fonte de luz, componentes dos materiais, etc.) para poder validar o resultado alcançado.

Trabalho 2: Programação em shaders

  • Upload
    others

  • View
    4

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Trabalho 2: Programação em shaders

INF2610 – Renderização em Tempo Real

Trabalho 2: Programação em shaders Usando novamente o código exemplo para visualização de um conjunto de esferas sobre um plano como base, implemente:

1. Uma abstração para a definição de shaders. 2. Shaders de vértice e fragmento para tratar iluminação por

vértice, obtendo o mesmo resultado visual do programa com o pipeline convencional.

3. Shaders de vértice e fragmento para tratar iluminação por fragmento. Compare a qualidade e o desempenho das duas abordagens.

Descrição:

1. Crie uma classe para facilitar o uso das funções do OpenGL responsáveis por criar, compilar, linkar, validar e habilitar shaders e afins. Uma sugestão de interface é apresentada a seguir. Nesta interface, os métodos VertexShader e FragmentShader criam os shaders e os compilam. Se ocorrer erro de compilação, os métodos sinalizam retornando false, e a mensagem de erro correspondente pode ser acessada via o método GetMessage. O método Link também retorna um valor booleano indicando sucesso ou erro, e disponibiliza uma mensagem no caso de erro. O método Validate adota a mesma estratégia; esse método valida o programa em função do estado corrente do OpenGL; pode ser muito útil para identificar erros de programação (veja glValidateProgram). Os métodos Load/Unload ativam/desativam o programa como parte do pipeline gráfico.

class Shader { Shader (); ~Shader (); bool VertexShader (const char* source); bool FragmentShader (const char* source); bool Link (); bool Validate (); const char* GetMessage (); void Load (); void Unload (); void SetUniform (const char* name, float x); void SetUniform (const char* name, float x, float y); void SetUniform (const char* name, float x, float y, float z); void SetUniform (const char* name, float x, float y, float z, float w); void SetUniform (const char* name, int size, int count, float* v) ; void SetUniformI (const char* name, int x); void SetUniformI (const char* name, int x, int y); void SetUniformI (const char* name, int x, int y, int z); void SetUniformI (const char* name, int x, int y, int z, int w); void SetUniformI (const char* name, int size, int count, int* v) ; void SetUniformMatrix (const char* name, int row, int col, int count, float* v); };

2. Usando a abstração do item anterior, escreva shaders para fazer a iluminação por vértice da cena. A aplicação deve fazer uso apenas do novo padrão do OpenGL (v. 3.3 ou posterior). Assim, a API de array utilizada para especificar coordenadas e normais do pipeline convencional (glVertexPointer e glNormalPointer) devem ser substituídas pelas funções de atributo sem semântica (glVertexAttribPointer). Similarmente, não se pode usar as funções de transformação como glLoadMatrix. O resultado deve ser o mesmo que o obtido pelo programa usando o pipeline convencional. Utilize os mesmos parâmetros de iluminação (posição da fonte de luz, componentes dos materiais, etc.) para poder validar o resultado alcançado.

Page 2: Trabalho 2: Programação em shaders

3. Usando a mesma abstração, re-escreva os shaders para fazer a iluminação por pixel. Compare a qualidade da imagem. Faça uma medição de tempo das duas estratégias e verifique se seu computador perdeu desempenho as fazer a iluminação por pixel. Utilize os mesmo parâmetros de iluminação.

Entrega: O aluno deve enviar por e-mail apenas o código fonte (arquivos .cpp, .h e shaders), incluindo as classes criadas e os exemplos codificados conforme pedido. Deve ser enviado também uma imagem com iluminação por vértice e uma imagem com iluminação por pixel. Além disso, escreva no texto da mensagem o desempenho observado na execução das soluções. Prazo: O trabalho deve ser enviado até o dia 15 de abril, terça-feira.