|
Post by Roger Cabo on Jan 28, 2024 19:22:47 GMT 1
I wanted to convert the vertex and matrix and struct data to 64 bit in Scalions Shader example. It took some time to get all the required infos. But there is a PasCall Error by the function. ~StdCall(A_glVertexAttribLPointer)(index, size, enumtype, normalized, stride, ptr)For the info.. OpenGL32 supports 64bit calculations and matrix operations for vertex, transform and Uniform data. From the version #400, but I would prefer #430. The assem code will be generated on the fly after F5 in the debug window.
~StdCall(A_glVertexAttribLPointer)(index, size, enumtype, normalized, stride, ptr)
065FCD53: FF 55 B4 call dpt -76[ebp] 065FCD56: FF 35 18 EE 89 07 push dpt [0x0789EE18] 065FCD5C: FF 75 2C push dpt 44[ebp] 065FCD5F: FF 75 28 push dpt 40[ebp] 065FCD62: 0F BA 65 24 00 bt dpt 36[ebp],0 065FCD67: 1B C0 sbb eax,eax 065FCD69: 50 push eax 065FCD6A: FF 75 20 push dpt 32[ebp] 065FCD6D: FF 75 1C push dpt 28[ebp] 065FCD70: FF 75 18 push dpt 24[ebp] 065FCD73: B8 06 00 00 00 mov eax,6 065FCD78: FF 15 A8 1E 4D 00 scall PASCALL 065FCD7E: FF 55 B4 call dpt -76[ebp]
index: 0 size : 3 enumtype: 5130 normalized: Falsch stride: 64 ptr: 0
The error could indicate an issue with how the function is being called or how the parameters are being passed to it. The assembly code seems to show that the parameters are being passed correctly, but there may be an issue with the OpenGL implementation or the graphics driver not responding correctly to the glVertexAttribLPointer function, especially in terms of processing 64-bit data.
Some info: The 3 functions: glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, SizeOf(Vertex_Struct), OffsetOf(Vertex_Struct.Position)) ... etc
... etc..
working great with the 32 bit vertex data structure.
The code in 64bit. Keep in mind that the opengl32.dll version supports 64bit transformation vertex, position, Normal, and TexCord data. Shader_Double.txt (36.53 KB) Would be great if someone have an idea why this PasCall error happen and maybe to fit it. So we can use 64bit float double!
|
|
|
Post by dragonjim on Jan 29, 2024 10:24:22 GMT 1
If I remember correctly, there has always been an intermittent and unpredictable error with StdCall which Sjouke has not been able to fix.
I will check further but I don't think there is a workaround.
|
|
|
Post by scalion on Jan 29, 2024 10:39:21 GMT 1
The Generate_Torus arrays produce floating point value (not double). You must make some change in it before a call to glVertexAttribLPointer ! by Changing all memory offsets and changing all SngPoke by dblPoke ! Change also SizeData = Tcount * 96 by SizeData = Tcount * 192
Note also : In shaders the 64 bits computing is not autorized for trigonometric functions (sin, cos etc...)
Edit : As you said If you have the PASCAL error change :
~LStdCall(A_glVertexAttribLPointer)(index, size, enumtype, normalized, stride, ptr)
By :
Local Long ANor ANor = normalized . push [ptr] . push [stride] . push [ANor] . push [enumtype] . push [size] . push [index] . mov eax, [A_glVertexAttribLPointer] . call eax
That's work. But if the result is strange even the data are correct.
with glDrawArray GL_INVALID_OPERATION is generated if a geometry shader is active and mode is incompatible with the input primitive type of the geometry shader in the currently installed program object.
Maybe to draw vertex with double values you must implement a Geometry Shader...
Another thing, maybe double are in MBF format in OpenGL ? but that's not sure.
|
|
|
Post by Roger Cabo on Jan 29, 2024 17:58:01 GMT 1
The Generate_Torus arrays produce floating point value (not double). You must make some change in it before a call to glVertexAttribLPointer ! by Changing all memory offsets and changing all SngPoke by dblPoke ! Change also SizeData = Tcount * 96 by SizeData = Tcount * 192
Note also : In shaders the 64 bits computing is not autorized for trigonometric functions (sin, cos etc...)
Edit : As you said If you have the PASCAL error change :
~LStdCall(A_glVertexAttribLPointer)(index, size, enumtype, normalized, stride, ptr)
By :
Local Long ANor ANor = normalized . push [ptr] . push [stride] . push [ANor] . push [enumtype] . push [size] . push [index] . mov eax, [A_glVertexAttribLPointer] . call eax
That's work. But if the result is strange even the data are correct. with glDrawArray GL_INVALID_OPERATION is generated if a geometry shader is active and mode is incompatible with the input primitive type of the geometry shader in the currently installed program object. Maybe to draw vertex with double values you must implement a Geometry Shader... Another thing, maybe double are in MBF format in OpenGL ? but that's not sure.
>>> Maybe to draw vertex with double values you must implement a Geometry Shader...I think the vertex Shader should be also convert into 64bit double. Not the Fragment.. ---------------------------------------------- Peut-être que pour dessiner des sommets avec des valeurs en double, vous devez mettre en place un Geometry Shader... Je pense que le Shader de sommet doit également être converti en double de 64 bits. Pas le Fragment...
:Geometry-Shader64.txt #version 430
layout(triangles) in; layout(triangle_strip, max_vertices = 3) out;
// Eingangsvariablen (Double-Präzision) in dvec3 position[]; in dvec3 normal[]; in dvec2 texCoords[];
// Ausgangsvariablen out dvec3 fragPosition; out dvec3 fragNormal; out dvec2 fragTexCoords;
// Uniform-Matrizen (Double-Präzision) uniform dmat4 modelMatrix; uniform dmat4 viewMatrix; uniform dmat4 projectionMatrix;
void main() { for (int i = 0; i < gl_in.length(); i++) { // Berechnungen in Double-Präzision dvec4 worldPosition = modelMatrix * dvec4(position[i], 1.0); dvec3 worldNormal = normalize((modelMatrix * dvec4(normal[i], 0.0)).xyz);
// Transformation zu Float für die Ausgabe fragPosition = worldPosition.xyz; fragNormal = worldNormal; fragTexCoords = texCoords[i];
// Setzen der Position des Fragments // gl_Position = projectionMatrix * viewMatrix * worldPosition; gl_Position = vec4(projectionMatrix * viewMatrix * modelMatrix * worldPosition); // convert to 32bit for screen space EmitVertex(); } EndPrimitive(); }
:Vertex-Shader64.txt #version 430 core // Vertex Shader 64bit // Eingangsattribute in Double-Präzision in dvec3 p; in dvec3 n; in dvec2 t; in dvec4 c;
// Ausgangsattribute out dvec3 pOut; out dvec3 nOut; out dvec2 tOut; out dvec4 cOut; out dvec3 pp;
// Uniform-Matrizen in Double-Präzision uniform dmat4 pmat; uniform dmat4 vmat; uniform dmat4 imat; uniform int instruction; uniform dvec3 eye; uniform dvec3 spot;
dvec3 normaliseDVec3(dvec3 a){ double d;
d = sqrt(a.x * a.x + a.y * a.y + a.z * a.z); if(d > 0.0){ a.x /= d; a.y /= d; a.z /= d; return a; } if(a.x!=0){ a.x = sign(a.x); a.y = 0.0; a.z = 0.0; return a; } if(a.y != 0.0){ a.x = 0.0; a.y = sign(a.y); a.z = 0.0; return a; } if(a.z != 0.0){ a.x = 0.0; a.y = 0.0; a.z = sign(a.y); return a; } a.x = 0.0; a.y = 1.0; a.z = 0.0; return a; }
double cosvvd(dvec3 a, dvec3 b){
a = normaliseDVec3(a); b = normaliseDVec3(b);
return (a.x * b.x + a.y * b.y + a.z * b.z);
}
dvec3 reflectiond(dvec3 r, dvec3 n){
double dp;
r = normaliseDVec3(r); n = normaliseDVec3(n); dp = 2. * (n.x * r.x + n.y * r.y + n.z * r.z); return dvec3(r.x - n.x * dp, r.y - n.y * dp, r.z - n.z * dp);
}
dvec3 subxyzd(dvec3 a,dvec3 b){ return dvec3(a.x-b.x,a.y-b.y,a.z-b.z); }
void main(){ pp = p; pOut=dvec4(pmat*vmat*dvec4(p,1.0)).xyz; nOut=dvec4(pmat*vmat*dvec4(p+n,1.0)).xyz-pOut; tOut=t; // transforme la position du vertex // gl_Position = pmat * vmat * dvec4(p,1.0); Error while converting gl_Position = vec4(pmat * vmat * dvec4(p, 1.0)); // pass is to 32bit for ==> gl_Position /* float l; dvec3 em = vec4(imat*vmat*vec4(eye,1.0)).xyz; dvec3 ed = pOut-em; dvec3 r = reflection(ed,nOut); l = max(0,cosvvd(r,spot-pOut)/2.0); l = min(1.0,4*pow(l,2)); pOut = dvec4(l,l,l,1.0).xyz; */
}
I think we should ask for the 64bit ability of the driver as well in special function of your lib later.. PFNGLGETSTRINGIPROC glGetStringi = (PFNGLGETSTRINGIPROC)wglGetProcAddress("glGetStringi"); I changed your shader program to: Proc ShadersLoading(Vertex_Shader_File As String, Fragment_Shader_File As String, Optional Geometry_Shader_File As String) Proc ShadersCompilation(Vertex_Shader_Code As String, Fragment_Shader_Code As String, Geometry_Shader_Code As String)
Je pense que nous devrions également demander la capacité en 64 bits du pilote dans une fonction spéciale de votre bibliothèque plus tard... PFNGLGETSTRINGIPROC glGetStringi = (PFNGLGETSTRINGIPROC)wglGetProcAddress("glGetStringi");
J'ai modifié votre programme de shader comme suit : Procédures de chargement des shaders (Fichier du shader de sommet en tant que chaîne, Fichier du shader de fragment en tant que chaîne, Fichier du shader de géométrie en option en tant que chaîne) Procédures de compilation des shaders (Code du shader de sommet en tant que chaîne, Code du shader de fragment en tant que chaîne, Code du shader de géométrie en tant que chaîne)
Geometry-Shader64.txt (1.09 KB) Vertex-Shader64.txt (1.94 KB) Next post ----> Attachments:FragmentShader32.txt (2.98 KB)
|
|
|
Post by Roger Cabo on Jan 29, 2024 18:03:09 GMT 1
Here is the complete new code using 64bit vertex 32bit fragment 64bit geometry and changed the complete code to torus double. But the screen stays black for any reason.. also compiled the Geometry Shader successfully. but I'm not sure if the hole stuff is correct.
Voici le code complet utilisant vertex 64 bits fragment 32 bits geometry 64 bits
et j'ai modifié tout le code pour le faire fonctionner en double torus. Cependant, l'écran reste noir pour une raison quelconque... J'ai également compilé avec succès le Geometry Shader. mais je ne suis pas sûr que tout soit correct.
Including shaders: Shaders_02_Double Precision.G32 (46.4 KB)
|
|
|
Post by scalion on Jan 29, 2024 20:46:44 GMT 1
Here is the complete new code using 64bit vertex 32bit fragment 64bit geometry and changed the complete code to torus double. But the screen stays black for any reason.. also compiled the Geometry Shader successfully. but I'm not sure if the hole stuff is correct.
Voici le code complet utilisant vertex 64 bits fragment 32 bits geometry 64 bits
et j'ai modifié tout le code pour le faire fonctionner en double torus. Cependant, l'écran reste noir pour une raison quelconque... J'ai également compilé avec succès le Geometry Shader. mais je ne suis pas sûr que tout soit correct.
Including shaders: View Attachment
I tried your code and i see exactly what i obtained with my own modification :
We both carried out the same work on our own for an identical result. We were not mistaken (I checked the torus data), the problem comes from the way the data is transmitted either by the vertexarray or by the geometry shader.... There's something I'm missing.
|
|
|
Post by Roger Cabo on Jan 29, 2024 22:13:51 GMT 1
Tried so many times with chatgpt to explore the code and find solutions. On my screen all stays black. I think I done all the stuff, was possible. At first the vertex geometry must be 64bit, but not sure if the .normals and texcords must be 64bit as well. Perhaps it could be possible that the .normals and .texcords must be 32bit, because the fragment shader is in 32bit as well. And these .normals and .texcords are a part of the stuff can bee seen by the fragment shader in screen space? Type Triangle_Struct Packed 4 - Vertex_Struct a, b, c EndType
Type Vertex_Struct Packed 4 - v3d_Struct Position // double - v3f_Struct Normal //<--- float - v2f_Struct TexCoords // <--- float EndType
Type XYZ_STRUCT - Double x, y, z EndType
Type v3d_Struct Packed 4 - Double x, y, z EndType
Type v2d_Struct Packed 4 - Double x, y EndType
Type v2f_Struct Packed 4 - Float x, y EndType
I can try this tomorrow.. Edit: could it be possible that we should test if 64 is possible on the driver?
|
|
|
Post by Roger Cabo on Jan 30, 2024 12:48:51 GMT 1
You need a current GL context for glewInit() and glGetString() to work.
InitialisationOpenGL CheckDoublePrecisionSupport()
Declare Function glGetString Lib "opengl32.dll" Alias "glGetString" (ByVal name As Long) As String Const GL_EXTENSIONS = &H1F03 CheckDoublePrecisionSupport()
Proc CheckDoublePrecisionSupport() Dim extensions As String extensions = glGetString(GL_EXTENSIONS)
If InStr(1, extensions, "GL_ARB_gpu_shader_fp64") > 0 Then MsgBox "Double precision (64-bit) supported" Else MsgBox "Double precision (64-bit) not supported" End If EndProc
All 64bit Shaders need: #version 430 core #extension GL_ARB_gpu_shader_fp64 : enable
Unfortunately my screen stays black.. This is really hardcore to solve this problem...
|
|
|
Post by scalion on Feb 1, 2024 16:10:37 GMT 1
J'ai parcouru pas mal de forum au sujet des vertex en double précision, et une réponse qui revient très régulièrement est "As-tu vraiment besoin d'utiliser des double pour la 3D ?". Apparemment les vertex sont rarement calculé en double au niveau du hardware.
Une autre approche serait de diviser le monde en zone de 10000 x 10000 (c'est un exemple), les objets sont gérés dans le programme avec des doubles et envoyés en Float dans OpenGl, Ainsi tu ne dépasse jamais les limites de précision. Si dans ton monde 3D tu est à la case 12,10 (120000,100000 à 129999,109999) tu effectue les translations dans le programme et tu envoies les données à OpenGL en Float. Ainsi un LookAt(122000,100,100500,122200,100,100550,0,1,0) deviens LookAt(2000,100,500,2200,100,550,0,1,0) Tu fais pareil avec tes glVertex(x,y,z) et tout le reste.
US : I've browsed quite a few forums about double precision vertices, and one answer that comes up very regularly is "Do you really need to use doubles for 3D?". Apparently vertices are rarely calculated twice in hardware.
Another approach would be to divide the world into an area of 10000 x 10000 (this is an example), the objects are managed in the program with doubles and sent as Float in OpenGl, So you never exceed the precision limits. If in your 3D world you are in box 12.10 (120000,100000 to 129999,109999) you carry out the translations in the program and send the data to OpenGL in Float. So a LookAt(122000,100,100500,122200,100,100550,0,1,0) becomes LookAt(2000,100,500,2200,100,550,0,1,0) You do the same with your glVertex(x,y,z) and everything else.
|
|
|
Post by Roger Cabo on Feb 4, 2024 9:50:57 GMT 1
Thank for having a look at this!
I will have look how to convert obj files into a 3d structure and later.. with texture maps and UVs texture maps.
Then add some simple collision recognition between the world an objects. ________________
Merci d'y jeter un coup d'œil !
Je vais voir comment convertir des fichiers obj en une structure 3D, puis plus tard... avec des cartes de texture et des UVs.
Ensuite, ajouter une reconnaissance simple des collisions entre le monde et les objets.
|
|
|
Post by Roger Cabo on Feb 11, 2024 15:28:55 GMT 1
J'ai parcouru pas mal de forum au sujet des vertex en double précision, et une réponse qui revient très régulièrement est "As-tu vraiment besoin d'utiliser des double pour la 3D ?". Apparemment les vertex sont rarement calculé en double au niveau du hardware. Une autre approche serait de diviser le monde en zone de 10000 x 10000 (c'est un exemple), les objets sont gérés dans le programme avec des doubles et envoyés en Float dans OpenGl, Ainsi tu ne dépasse jamais les limites de précision. Si dans ton monde 3D tu est à la case 12,10 (120000,100000 à 129999,109999) tu effectue les translations dans le programme et tu envoies les données à OpenGL en Float. Ainsi un LookAt(122000,100,100500,122200,100,100550,0,1,0) deviens LookAt(2000,100,500,2200,100,550,0,1,0) Tu fais pareil avec tes glVertex(x,y,z) et tout le reste. US : I've browsed quite a few forums about double precision vertices, and one answer that comes up very regularly is "Do you really need to use doubles for 3D?". Apparently vertices are rarely calculated twice in hardware.
Another approach would be to divide the world into an area of 10000 x 10000 (this is an example), the objects are managed in the program with doubles and sent as Float in OpenGl, So you never exceed the precision limits. If in your 3D world you are in box 12.10 (120000,100000 to 129999,109999) you carry out the translations in the program and send the data to OpenGL in Float. So a LookAt(122000,100,100500,122200,100,100550,0,1,0) becomes LookAt(2000,100,500,2200,100,550,0,1,0) You do the same with your glVertex(x,y,z) and everything else.In unity we have the same troubles on moving parts into the right position. That's a ugly behavior, because on larger geometry it jerks for some time. and think about if you add some collisions and gravity acceleration effects..
Just wondering there is no way to activate 64bit transform and vertex positions, the driver and cars supports all the stuff.. Unreal and other engines support as well. Unity3d do not want to support because they want to sell games for android only.
Further I found out that you use variant instead of double. No idea that it cause some trouble as well.
_______________________________________________________________________
Dans Unity, nous rencontrons les mêmes problèmes pour déplacer les éléments dans la bonne position. C'est un comportement laid, car sur une géométrie plus grande, cela saccade pendant un certain temps. Et pensez si vous ajoutez des collisions et des effets d'accélération de la gravité...
Je me demande s'il n'y a aucun moyen d'activer les transformations et les positions des sommets sur 64 bits, le pilote et les voitures prennent en charge tout cela... Unreal et d'autres moteurs le prennent également en charge. Unity3D ne veut pas le prendre en charge car ils veulent vendre des jeux uniquement pour Android.
De plus, j'ai découvert que vous utilisez des variantes plutôt que des doubles. Aucune idée que cela puisse aussi causer des problèmes.
Proc LookAt(xEye, yEye, zEye, xTarget, yTarget, zTarget, xUp, yUp, Zup) gluPerspective(45, Max(1, _X) / Max(1, _Y), 0.1, 1000) gluLookAt(xEye, yEye, zEye, xTarget, yTarget, zTarget, xUp, yUp, Zup) MatrixToUniforms EndProc Proc Rotate(Angle, x, y, z) glRotatef(Angle, x, y, z) MatrixToUniforms EndProc Proc Translate(x, y, z) glTranslatef(x, y, z) MatrixToUniforms EndProc
|
|
|
Post by Roger Cabo on Feb 11, 2024 15:54:02 GMT 1
It's a pity that we can't get 64 vertex and shader data to work... ----------------- C'est dommage que nous ne puissions pas faire fonctionner les données de 64 sommets et shaders...
|
|
|
Post by Roger Cabo on Mar 2, 2024 21:16:25 GMT 1
Une autre approche serait de diviser le monde en zone de 10000 x 10000 (c'est un exemple), les objets sont gérés dans le programme avec des doubles et envoyés en Float dans OpenGl, Ainsi tu ne dépasse jamais les limites de précision. Si dans ton monde 3D tu est à la case 12,10 (120000,100000 à 129999,109999) tu effectue les translations dans le programme et tu envoies les données à OpenGL en Float. Ainsi un LookAt(122000,100,100500,122200,100,100550,0,1,0) deviens LookAt(2000,100,500,2200,100,550,0,1,0) Tu fais pareil avec tes glVertex(x,y,z) et tout le reste. Another approach would be to divide the world into an area of 10000 x 10000 (this is an example), the objects are managed in the program with doubles and sent as Float in OpenGl, So you never exceed the precision limits. If in your 3D world you are in box 12.10 (120000,100000 to 129999,109999) you carry out the translations in the program and send the data to OpenGL in Float. So a LookAt(122000,100,100500,122200,100,100550,0,1,0) becomes LookAt(2000,100,500,2200,100,550,0,1,0) You do the same with your glVertex(x,y,z) and everything else.I didn't understand exactly what this workaround should do?
If you have world objects placed in the area xy -100000.0001 to xy 1000000.0001 How you will place the cam at -59567.0081, 78678.0601 ? Or I have to move all objects to the relative position of 0,0 , but that's a mega CPU and GPU work.
Would you so kind and explain a bit more?
|
|