Category Archives: programação

Bug na implementação OpenGL (GLKit framework) da Apple?

Durante o desenvolvimento de uma aplicação OpenGL ES 2.0 para iOS, me deparei com o seguinte erro ao carregar texturas (usando GLKTextureLoader):

Error Domain=GLKTextureLoaderErrorDomain Code=8 “The operation couldn’t be completed. (GLKTextureLoaderErrorDomain error 8.)” UserInfo=0x75a3990 {GLKTextureLoaderGLErrorKey=1280, GLKTextureLoaderErrorKey=OpenGLES Error.}

O estranho é que o erro ocorria apenas com a primeira textura. Analisando meu código, vi que estava chamando glEnable(GL_TEXTURE_2D); antes de carregar todas as texturas. No entanto, por usar OGLES2.0 (programmable pipeline), não preciso ativar o estado GL_TEXTURE_2D (http://www.opengl.org/wiki/GLSL_:_common_mistakes#Enable_Or_Not_To_Enable).

Assim, remover a chamada do glEnable(GL_TEXTURE_2D) resolveu o problema.

Mas uma coisa me chamou a atenção: o GLKTextureLoader aparentemente usa o último valor da flag de erro do OpenGL e parece não fazer uma checagem simples para ignorar erros que não estejam relacionados com sua função. Dessa forma, caso a última flag de erro do OpenGL seja diferente de GL_NO_ERROR (antes de carregar a textura), o parâmetro error do GLKTextureLoader é preenchido de forma errada (pelo menos na minha interpretação).

Um teste que realizei foi o de manter glEnable(GL_TEXTURE_2D) (gerando flag de erro) e chamar glGetError() antes do GLKTextureLoader. Resultado: a textura foi carregada corretamente.

Segue o método que escrevi para carregar a textura (assumindo que mTexture é um membro da classe, do tipo GLKTextureInfo).

- (void)loadTexture:(NSString *)filename
{
  // HACK: Clear GL error code before calling GLKTextureLoader, otherwise GLKTextureLoader will use the previous GL error...
  glGetError();

  NSError *error = nil;
  NSString *filePath = [[NSBundle mainBundle] pathForResource:[filename stringByDeletingPathExtension] ofType:[filename pathExtension]];
  mTexture = [GLKTextureLoader textureWithContentsOfFile:filePath options:nil error:&error];

  if (error)
  {
    NSLog(@"Error loading texture \"%@\" from image: %@", filename, error);
  }
  else
  {
    NSLog(@"loadTexture: %@\nname: %d\ntarget: %d (GL_TEXTURE_2D? %d)\nwidth: %d\nheight: %d\nalpha state: %d\ntexture origin: %d\ncontains mipmaps: %d\n",
      filename, mTexture.name, mTexture.target, mTexture.target==GL_TEXTURE_2D, mTexture.width, mTexture.height, mTexture.alphaState, mTexture.textureOrigin, mTexture.containsMipmaps);
  }
}
Be Sociable, Share!

Visual Assist X = produtividade++;

logoWTS
Dica para quem usa o Microsoft Visual Studio para qualquer linguagem (com exceção das versões Express) e ainda não usa o Visual Assist X (VAX): compre a licença e sua vida de programador nunca mais será a mesma. Dinheiro muito bem gasto.

O mesmo vale para empresas que usam a IDE; a produtividade dos seus programadores com certeza aumentará e eles ficarão mais felizes (e ao mesmo tempo ficarão P da vida porque terão que comprar uma licença pessoal para usarem na máquina pessoal deles).

Não, não estou recebendo nada para fazer essa “propaganda” :).

O VAX é uma daquelas ferramentas que, depois que você a conhece, fica se perguntando “Como vivi sem você até agora?”. Ela adiciona novas features ao Visual Studio que facilitam diversas tarefas de programação, como por exemplo: melhora no IntelliSense, sugestões de auto-completar, opções de refatoração, navegação entre arquivos mais rápida, correção de digitação, highlight de código e até conversão de . (ponto) para -> em C/C++. Vale a pena ver mais detalhes no site oficial.

Uma feature que sentia falta no Visual Studio é a possibilidade de alternar entre os arquivos h/cpp de maneira rápida (= via teclado), como acontece no XCode. Com o VAX, é só usar o atalho Alt+O.

Algumas features que uso bastante no dia-a-dia:

  • Alt+M para abrir um dropdown com os métodos (e logo em seguida, digitar parte do nome do método e apertar enter para ir pro método).
  • Shift+Alt+F para encontrar referências de símbolos (que é diferente do “Find in Files”).
  • Shift+Alt+R para renomear variáveis, métodos, etc., seja por erro de digitação ou nome mais apropriado (isso mais quando estou refatorando).
  • Fora aquelas que já funcionam automaticamente (IntelliSense, auto-complete, highlight, etc).

    Jogo dos 7 erros

    Segue abaixo duas imagens do VS2010, uma sem o VAX e outra com o VAX. Consegue listar as diferenças? (considerando o highlight de sintaxe como uma única diferença, realmente há 7 itens diferentes entre as duas versões).

    WithoutVax

    WithVax

    Sobre o código acima, é outro assunto que pretendo comentar futuramente aqui no blog.

    Até!

    Be Sociable, Share!