Pergunta

Meu programa usa Pyopengl (então é Python) com Psyco.

Eu tenho cerca de 21.000 segmentos de linha que preciso renderizar em cada quadro da minha renderização (a menos que o usuário seja ampliado, nesse caso, os segmentos da linha são abatidos e não enviados ao cartão). Atualmente, está levando cerca de 1,5 segundos a cada quadro para ser concluído. Isso não é bom o suficiente, por isso estou procurando maneiras de reduzir o número de segmentos de linha distintos.

Eu imagino que haveria casos em que vários segmentos de linha podem ser mesclados em uma grande linha, mas sinceramente nem sei por onde começar com isso. Eu tenho o ponto de partida e o ponto final de cada linha armazenada, para que isso possa ajudar as coisas. Observe que sou capaz de demorar o tempo que precisar na startup, e o uso da memória não é muita preocupação.

Qualquer idéia será muito bem vinda.

Foi útil?

Solução

É quase certamente a sobrecarga de toda a função de modo imediata que está matando seu desempenho. Eu faria o seguinte.

Não use GL_LINE_STRIPS, use uma única lista de GL_LINES Em vez disso, eles podem ser renderizados de uma só vez.

Usar glDrawArrays Em vez de renderização imediata de modo:

float* coordinates = {....}; //x and y coordinate pairs for all line segments
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 2 * sizeof(float), coordinates);
glDrawArrays(GL_LINES, 0, 2 * linecount);
glDisableClientState(GL_VERTEX_ARRAY);

(Para um desempenho ainda melhor, você pode armazenar o buffer de vértice em algo chamado objeto buffer de vértice, mas isso deve ser bom para começar)

Uma coisa final, se você está se selecionando por linha, provavelmente é mais rápido ignorá -lo e enviar todas as linhas para a GPU.

Outras dicas

20k segmentos não são muito. Além disso, você terá sorte quando puder mesclar 10 a 100 linhas por quadro; portanto, a aceleração dessa otimização será negligenciável. O processo de renderização provavelmente é lento porque você cria o modelo repetidamente. Usar glNewList() Para salvar todos os comandos de renderização em uma lista de renderização GL no cartão e depois apenas emitir glCallList() para renderizá -lo com um único comando.

Você pode definir uma métrica de erro para mesclar dois segmentos de linha em um e depois testar todos os pares de segmentos e, em seguida, mesclá -los se o erro estiver abaixo de um determinado limite.

Um exemplo é este algoritmo:

  1. Construa um novo segmento de linha X a partir dos dois pontos mais distantes um do outro nos segmentos de duas linhas A e B.
  2. Encontre a distância mínima para X para todos os pontos em A e B.
  3. Atribua o erro como o máximo dessas distâncias mínimas.
  4. Substitua A e B por X se o erro estiver abaixo do seu limite.

Este não é o melhor algoritmo, mas é fácil de implementar.

Editar 1

Definitivamente, tente fazer listas de exibição ou renderização de objetos de buffer de vértice antes de implementar isso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top