Je cherche / écrire une implémentation C ++ d'un numéro de point flottant de 16 bits à utiliser avec des tampons de vertex OpenGL (coordonnées de texture, normales, etc.). Voici mes exigences jusqu'à présent:
Voici ce que j'ai jusqu'à présent pour une interface: p> finalement, la vraie viande de la classe se situe dans le Quelles sont certaines préoccupations que je devrais être au courant de la mise en téléchargement d'un flotteur 16 bits sur OpenGL? Existe-t-il une implémentation à moitié float qui traite spécifiquement de ces préoccupations? P> Edit: par la demande populaire, voici comment mes données de sommet sont générées, téléchargées et rendues. P> Voici comment Les données sont définies dans la classe wirecubeentity: p> où tofloat () et
Fromfloat () Code> Fonctions, ce qui est ce dont j'ai besoin d'aide. J'ai été en mesure de trouver de nombreux exemples d'implémentations de float de 16 bits, mais aucun d'entre eux ne mentionne si elles peuvent être téléchargées ou non sur OpenGL ou non. P>
VA code> est une instance de vertexarray.
Va.load CODE> est défini comme suit: P>
void VertexArray::draw(void)
{
if (ready == false)
return;
/* Bind our vertex array */
bindArray();
/* Draw it's contents */
if (ibo == 0)
glDrawArrays(prim, 0, vcount);
else
glDrawElements(prim, icount, iformat, NULL);
unbindArray();
}
3 Réponses :
the bibliothèque GLM prend en charge Types de demi-float . Le préfixe utilisé est "h 'alors où GLM :: Vec3 code> est un vecteur de 3 éléments de valeurs de points flottants,
GLM :: hvec3 code> est un vecteur de 3 éléments de demi-floattes . p>
J'ai parcouru à travers le GLM et je n'arrive pas à trouver une implémentation pour le type code> moitié code>. Même dans demi_float.inl, je n'arrive pas à le trouver ...
J'ai copié la mise en œuvre de GLM, mais je reçois des résultats bizarres. Par exemple, lorsque je convertitons "0.9001F" à une demi puis retour à un flotteur, je reçois "0,899902F". Est-ce quelque chose qui inhérent à utiliser des flotteurs 16 bits ou est-il imparfait?
Oui, il est inhérent à 16 bits flotteurs. Vous avez moins de morceaux de précision afin que vous allez avoir une différence de potentiel plus importante entre le flotteur d'entrée et le flotteur de sortie. Vous obtenez la même chose avec des flotteurs normaux, avec plus de chiffres de précision.
Devrais-je avoir des préoccupations concernant l'envoi à OpenGL?
Je viens de le tester, et non, ça n'a pas fonctionné. Ce qui était utilisé pour être un beau cube est maintenant soupe au sommet.
OpenExR a également une classe «moitié» qui est compatible OpenGL. Cela ressemble à une copie ici: Sidefx.com/docs/hdk12.1 /half_8h_source.html
J'ai besoin de la mise en œuvre de "Convertir", ce qui n'est pas dans ce fichier.
Quelle est la performance comme pour GLM :: moitié? Je ne peux pas imaginer que c'est très rapide s'il n'y a pas de support matériel pour cela. Est-ce plus performant dans de grandes matrices, où la localité de données entre en jeu? Si oui, quelle est la taille d'un tableau doit être de justifier son utilisation?
Le point n'est pas vraiment nécessairement de commencer à utiliser GLM :: moitié code> où vous pourriez utiliser autrement float. Il s'agit généralement d'un mécanisme permettant de stocker des données que vous pourriez ensuite transmettre au GPU. Avoir un tableau de
GLM :: moitié code> va être plus facile à traiter dans le débogueur que de simplement avoir un caractère non signé * ou annulé * à un groupe d'octets qui n'ont aucun sens.
modifier em> strong>: l'erreur la plus évidente apparaît dans votre structure Vertexhalf. Vous avez un élément de rembourrage. Pourtant, lorsque vous spécifiez votre GLVERTEXATTRIBPOISER, vous spécifiez un 0 dans la foulée qui l'indique qu'il est bien emballé. Vous pouvez donc changer de vertexhalf pour éliminer le rembourrage ou modifier votre GLVERXATTRibpoinger pour avoir une foulée de 8 octets. J'utilise la classe suivante avec DirectX pour le support float16 et cela fonctionne parfaitement. P> float16.h : p> float16.cpp: p> / + ---- + - + - + - + ---- + ----- + ---- + ---- + ---- + ---- + ---- + ---- + ---- + - + ---- + ---- + ----- + ---- + ---- + ---- + ---- + EM> / P> float Float16ToFloat( short fltInt16 )
{
int fltInt32 = ((fltInt16 & 0x8000) << 16);
fltInt32 |= ((fltInt16 & 0x7fff) << 13) + 0x38000000;
float fRet;
memcpy( &fRet, &fltInt32, sizeof( float ) );
return fRet;
}
/*+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+*/
J'ai déjà une conversion float32-flottante16, avec courtoisie de Jherico. Le problème consiste à obtenir celui que OpenGL peut lire.
@ Haydnv.harach: Pourquoi OpenGL ne serait-il pas capable de le lire? OpenGL s'attend à ce que les données soient dans le bon modèle de bits et être de 16 bits par entrée. Ces données pourraient être stockées en short ou emballées dans des flotteurs pour toutes les cordes OpenGL ...
@ Haydnv.harach: J'ai ajouté ma mise en œuvre de la classe du flotteur16. Je l'utilise sous DirectX pendant un moment et je n'ai pas remarqué aucun problème.
Je l'ai testé, mais quand je convertit un numéro à moitié puis de retour à un flotteur, je reçois 0.0f.
@ Haydnv.harach: point équitable, j'ai repoussé quelque chose là-haut, tenez-vous malade de votre apparence ...
@ Haydnv.harach: OK après plus d'autres creuser, il semble que le code que j'ai sur Mac soit sur la date. Essayez ce qui précède.
Bien que sa mine signalant la mine ne fait pas de protection de trop-plein, etc. C'est très rapide à condition que vous puissiez être sûr que les données d'entrée sont valides.
Je peux convertir un flotteur à moitié et retour à un flotteur en toute sécurité, mais il mangue mes sommets comme les autres implémentations.
@ Haydnv.harach: L'objet est-il certainement assez petit pour être représenté par des moitiés?
Oui, c'est un cube composé entièrement d'arêtes, chaque position de sommet est (+ -1.0f, + -1.0f, + -1.0f).
@ Haydnv.harach: Puis-je vous suggérer de poster votre modèle de génération et de votre code de rendu?
@ Haydnv.harach: Vérifiez mon édition, je suis à peu près sûr que j'ai repéré votre erreur.
Je serai damné, vous aviez absolument raison. Merci beaucoup! PS, j'aime la simplicité de votre mise en œuvre, mais quelles sont les préoccupations que je devrais avoir sur "Données d'entrée valides"? Assurez-vous simplement que ce n'est pas NAN / INF?
@ Haydnv.harach: Fondamentalement, vous devez être prudent que vos flotteurs ne sont pas trop grands ou trop petits (maximum / minimum est +/- 65504, je crois). Au-dessus de ces valeurs, vous obtiendrez des résultats totalement invalides car les choses vont commencer à "envelopper". En dessous de la représentation minimale, vous continuerez à obtenir des zéros plutôt que de tout ce qui est utile. Une mise en œuvre meilleure, bien que plus lente, la protection contreflow (rond à l'infini, par exemple).
Je connais seulement bibliothèque OpenExR qui a une implémentation pour La mauvaise chose est que je ne sais pas si le type moitié code>. La bonne chose est que la mise en œuvre de la moitié a des fonctions que vous recherchez et cela fonctionne même avec NVIDIA CG < / a> boîte à outils. P>
moitié code> est compatible hors de la boîte avec la version OpenGL que vous utilisez (en théorie, cela devrait être), vous devez donc faire des tests. Avant de décider de l'utiliser. p>
Je viens de le tester en copiant la mise en œuvre de OpenExR exactement i> et, alors que je peux convertir un flotteur à moitié et à un flotteur avec une perte minimale de données, en le téléchargeant pour ouvrir des mangles sur mes sommets (même résultat que JHerico's Astuce).
@Haydn V. Harach: Quelle version OpenGL utilisez-vous? Êtes-vous sûr la version que vous utilisez Supports moitiés code>?
OpenGL 3.3.0, GLSL 3.30 Nvidia Via CG Compilateur, GeForce GTX 560 TI. Ma carte prend en charge OpenGL 4.3 (je pense que 4.4 aussi), mais je demande spécifiquement un contexte 3.3.
@HAYDN V. HARACH Pouvez-vous mettre à jour votre question avec un échantillon minimum sur l'initialisation et le rendu des données VERTEX (exemple de travail le plus court)? OpenExR La demi devrait être compatible avec le format CG et si cela ne fonctionne pas, je soupçonne que le problème est d'ailleurs
Cela vaut la peine d'être vérifiée: Half.Sourceforge.net (Disclaimer: c'est de moi). C'est IEEE / OPENGL-CONFORMANT, prend en charge tous les arithmétiques et conversions et s'efforce à la fois de performances et d'intégration simplifiée dans l'infrastructure C ++ existante (avec un support possible C ++ 11 lorsque cela est réalisable). Il devrait être parfaitement capable d'être up / téléchargé vers / depuis OpenGL immédiatement sur tout système raisonnable.
Le format que OpenGL attend est décrit dans OpenGL.org/registry/Specs/arb/ Half_float_Pixel.txt comme 5 bits d'exposant et 10 bits de Mantissa. Pour flotteur, il est respectivement 8 et 23. Vous ne pouvez-on pas simplement tapisser un float dans un pittoresque et copier le signe, la mantissie et l'exposant à un autre Bitfield?
@Damon Malheureusement, avec simplement la copie sur le champ de Bitfield, il est pas i> fait. Même désagréger toutes les valeurs spéciales telles que INFS et NANS, vous devrez toujours m'occuper de sous-flux (et bien sûr les différents biais exposants). Cependant, je suis d'accord, il est plus facile de ne pas vous soucier de la conformité de l'IEEE strict et de chaque cas séparé, mais la copie des bits est toujours un peu moins moins.