2010-11-29 31 views
2

J'ai une application openGL (JOGL, mais les mêmes concepts s'appliquent ici) où j'ai une scène qui rend environ 10k triangles sur chaque passe de rendu. L'échelle et l'angle des triangles doivent être calculés sur chaque rendu puisque les triangles doivent rester à une taille et une rotation constantes par rapport à l'emplacement de la caméra.Java OpenGL rendant plusieurs triangles

J'ai essayé d'utiliser une liste d'affichage, puis d'effectuer une mise à l'échelle/une rotation avant chaque appel à glCallList. Cela fonctionne, mais cela amène le système à une exploration. J'ai cherché dans l'utilisation de tampons de vertex pour cela, mais je ne suis pas sûr que ce soit la manière appropriée de le faire puisque j'ai besoin de tourner/mettre à l'échelle sur chaque rendu. Est-ce que quelqu'un peut m'aider dans la bonne direction pour rendre autant de triangles dans chaque scène?

EDIT - Cela fournit un contexte supplémentaire au problème.

L'application est une application cartographique montrant une vue 3D du monde. Il y a certaines formes qui doivent être dessinées sur la surface pointant dans une direction par rapport à une boussole, c'est-à-dire à 30 degrés. L'utilisateur peut faire pivoter la vue 3D, mais les formes doivent rester à plat sur la surface de la terre et également pointer dans la direction spécifiée.

, merci Jeff

+0

Donc les objets sont: a) identiques, et b) tournés par rapport à la boussole, de sorte qu'ils tournent exactement de la même manière que le monde lorsque l'utilisateur tourne la vue (plus un peu de leur propre rotation constante)? Aussi, quelle version d'OpenGL utilisez-vous? – Kos

+0

Ce sont les mêmes objets, oui. Ils ne tournent pas exactement de la même manière que le monde car ils doivent tourner pour être à plat sur la surface de la Terre. J'utilise JOGL 2.0. –

Répondre

5

Vertex avec buffers buffers GL_DYNAMIC_DRAW et índice avec GL_STATIC_DRAW serait le meilleur que vous pourriez faire en termes de simplicité. Si vous avez accès aux shaders (GLSL ou HSL), utilisez les Vertex Buffers avec GL_STATIC_DRAW et les Buffers d'indice avec GL_STATIC_DRAW, et calculez l'échelle et la rotation dans le vertex shader. De cette façon, vous pourriez déverser une partie du travail sur le GPU. (Si le travail était lourd pour commencer)

Peut-être faire un peu de trituration avant la main? Occlusion abattage? La meilleure façon d'accélérer une application est de réduire la quantité de triangles que vous affichez.

Peut-être même utiliser un peu de threading. Un fil à restituer, l'autre à calculer l'échelle et l'angle.

+0

merci. Une simple sélection de troncs de troncs a beaucoup aidé quand on a fait un zoom avant quand tous les points ne peuvent pas être vus. J'ai encore des problèmes quand tous les triangles sont visibles, mais c'est un bon début, c'est certain. –

+2

Culling aiderait pour le problème de remplissage-problème ou le problème de puissance de traitement de vertex/fragment. 10k triangles est une petite quantité donc cela me semble être un problème de CPU - donc les Vertex Buffers sont la solution, pour réduire le nombre d'appels draw (à un seul DrawArrays ou DrawElements par frame). Et évitez de diviser le threading et le rendu en différents threads, ce n'est pas une bonne idée (les appels de rendu ne sont pas chers!). Vous pouvez paralléliser le calcul lui-même si vous en avez besoin. – Kos

+0

On dirait qu'une grande partie de mon temps est occupé à faire les calculs pour les rotations. Je pourrais avoir besoin de trouver un moyen de les réduire. –

1

10.000 triangles est vraiment pas une grande quantité même pour votre GPU d'ordinateur portable moyen d'aujourd'hui.

Les listes d'affichage sont en quelque sorte obsolètes, ce n'est pas l'approche la plus utile.

La première chose à faire est dessinez vos trianges dans un seul appel nul - cela devrait être facilement possible.

Alors:

1) Gardez toutes vos données de triangle (sommet coordonnées) en une seule Buffer (qui est comment gère JOGL tableaux de sommets il, IIRC). Alors:

  • mise à jour ce tampon chaque image sur CPU et rendre tout cela en utilisant glVertexPointer et glDrawArrays,
  • Créer un VBO et (GL_DYNAMIC_DRAW type) et le mettre à jour chaque image avec ce tampon. Une approche plus moderne, mais pas vraiment une grande différence de ce qui précède en termes de vitesse dans ce cas.

Et après cela, vous rendre tous ces 10.000 triangles via un seul appel glDrawArrays. Cela laisserait toujours le calcul des triangles sur la CPU, mais vous épargnerait beaucoup de temps CPU passé sur les appels de pilotes - tous les triangles seraient envoyés via votre PCI-E à la fois et rendus en un clin d'œil.

Si c'est encore trop lent:

2) Pensez si vous pouvez/voulez déplacer quelques-unes des opérations effectuées sur les triangles au GPU et ont les calculs dans le vertex shader. Je ne peux pas en dire trop jusqu'à ce que je sache ce que vous faites, mais j'espère vraiment que 1) suffirait.

Si vous avez eu 10.000 appels à CallList chaque image, c'est certainement le coupable de votre faible performance.

+0

Actuellement tous mes triangles sont dessinés à (0.0f, 1.0f, 0.0f), (-0.5f, -1.0f, 0.0f), (0.5f, -1.0f, 0.0f), puis mis à l'échelle et tournés à l'emplacement correct. Parce que l'utilisateur peut zoomer et dézoomer et j'ai besoin de maintenir une taille constante en pixels, les coordonnées vont changer. Comment puis-je modifier différemment les triangles individuels lors de l'utilisation de glVertexPointer et de glDrawArrays? Merci. –

+0

OK, il y a des solutions, avant de plonger ici, pouvez-vous s'il vous plaît donner une description plus détaillée (vous pouvez éditer votre question et l'ajouter) ce que fait réellement votre application; quelles sont vos données et de quelle manière cela change dans le temps? Il pourrait être possible de discuter du problème à un niveau supérieur. – Kos

+0

merci. J'ai mis à jour la question avec quelques informations supplémentaires. –