glRotate+glTranslate in glLoadMatrix
-
Hallo Forumnutzer,
ich wollte folgenden Code
glRotatef(-loc.pitch,1.0f,0.0f,0.0f); // X-Achse rotieren glRotatef(loc.yaw,0.0f,1.0f,0.0f); // Y-Achse rotieren glTranslatef(loc.x,loc.y+player_size,loc.z); // "Kamera" bewegen
in eine eigene Matrix (double-Array) übersetzen.
Folgende Matrix ist allerdings falsch:
const static float PI=acos(-1); static double matrix[16]; { matrix[0]=cos(loc.yaw*PI/180.0f); matrix[1]=0; matrix[2]=-sin(loc.yaw*PI/180.0f); matrix[3]=0; matrix[4]=0; matrix[5]=cos(-loc.pitch*PI/180.0f); matrix[6]=sin(-loc.pitch*PI/180.0f); matrix[7]=0; matrix[8]=sin(loc.yaw*PI/180.0f); matrix[9]=-sin(-loc.pitch*PI/180.0f); matrix[10]=cos(-loc.pitch*PI/180.0f)*cos(loc.yaw*PI/180.0f); matrix[11]=0; matrix[12]=loc.x; matrix[13]=loc.y+player_size; matrix[14]=loc.z; matrix[15]=1; }; glLoadMatrixd(matrix);
Wie muss die die Matrix verändert werden, damit zuerst die X-Achse, dann die Y-Achse rotiert wird und schließlich alles verschoben wird (wie in der ersten, funktionierenden Funktion)?
Vielen Dank im Voraus!
Mit freundlichen Grüßen
Seikuassi
-
Das ist doch eine reine Fleißaufgabe.
Einfach die 3 Matrizen wie hier https://solarianprogrammer.com/2013/05/22/opengl-101-matrices-projection-view-model/beschrieben aufschreiben und dann auf ein Blatt papiere multiplizieren:
Rx * Ry * T
Mögliche Fehlerquellen: Reihenfolge der Multiplikation vertauschen: T * Rx * Rx
Am Ende dann mit Tranponieren rumprobieren, falls es immer noch nicht klappt.
Mit glGetFloatv(GL_MODELVIEW_MATRIX,*ptr) kannste ja dann kontrollieren, ob das gleiche rauskommt.
-
Hallo nochmal,
also, hab die Lösung gefunden. Ich liste hier nochmal alle Funktionen auf. Es geht um die Kamerabewegung im Raum.
Konstanten:
const float PI=acos(-1); const float rot_speed=3.0f; const float speed=0.1f;
Location (loc-)-Struktur
struct location{ float pitch=0.0f; double x=0.0; double y=0.0; float yaw=0.0f; double z=0.0; };
teilweise display-Funktion
static double matrix[16]; glMatrixMode(GL_MODELVIEW); { matrix[0]=cos(loc.yaw*PI/180.0f); matrix[1]=sin(loc.pitch*PI/180.0f)*-sin(loc.yaw*PI/180.0f); matrix[2]=cos(loc.pitch*PI/180.0f)*-sin(loc.yaw*PI/180.0f); matrix[3]=0; matrix[4]=0; matrix[5]=cos(loc.pitch*PI/180.0f); matrix[6]=-sin(loc.pitch*PI/180.0f); matrix[7]=0; matrix[8]=sin(loc.yaw*PI/180.0f); matrix[9]=sin(loc.pitch*PI/180.0f)*cos(loc.yaw*PI/180.0f); matrix[10]=cos(loc.pitch*PI/180.0f)*cos(loc.yaw*PI/180.0f); matrix[11]=0; matrix[12]=loc.x*cos(loc.yaw*PI/180.0f)+loc.z*sin(loc.yaw*PI/180.0f); matrix[13]=-loc.x*sin(loc.pitch*PI/180.0f)*sin(loc.yaw*PI/180.0f)+loc.z*sin(loc.pitch*PI/180.0f)*cos(loc.yaw*PI/180.0f)+loc.y*cos(loc.pitch*PI/180.0f); matrix[14]=-loc.x*cos(loc.pitch*PI/180.0f)*sin(loc.yaw*PI/180.0f)+loc.z*cos(loc.pitch*PI/180.0f)*cos(loc.yaw*PI/180.0f)-loc.y*sin(loc.pitch*PI/180.0f); matrix[15]=1; }; glLoadMatrixd(matrix);
idle-Funktion
void idle(){ if(keys.w==true){ // wenn die W-Taste gedrückt wird loc.x+=speed*sin(-loc.yaw*PI/180.0f); loc.z+=speed*cos(-loc.yaw*PI/180.0f); }; if(keys.s==true){ // wenn die S-Taste gedrückt wird loc.x-=speed*sin(-loc.yaw*PI/180.0f); loc.z-=speed*cos(-loc.yaw*PI/180.0f); }; if(keys.a==true){ // wenn die A-Taste gedrückt wird loc.x+=speed*sin((-loc.yaw+90.0f)*PI/180.0f); loc.z+=speed*cos((-loc.yaw+90.0f)*PI/180.0f); }; if(keys.d==true){ // wenn die D-Taste gedrückt wird loc.x-=speed*sin((-loc.yaw+90.0f)*PI/180.0f); loc.z-=speed*cos((-loc.yaw+90.0f)*PI/180.0f); }; if(keys.e==true){ // wenn die X-Taste gedrückt wird loc.y-=speed; }; if(keys.q==true){ // wenn die Y-Taste gedrückt wird loc.y+=speed; }; if(keys.up==true&&loc.pitch<90.0f){ // wenn die obere Pfeiltaste gedrückt wird loc.pitch+=rot_speed; }; if(keys.down==true&&loc.pitch>-90.0f){ // wenn die untere Pfeiltaste gedrückt wird loc.pitch-=rot_speed; }; if(keys.left==true){ // wenn die linke Pfeiltaste gedrückt wird loc.yaw-=rot_speed; if(loc.yaw<0.0f){ loc.yaw=360.0f-rot_speed; }; }; if(keys.right==true){ // wenn die rechte Pfeiltaste gedrückt wird loc.yaw+=rot_speed; if(loc.yaw>360.0f){ loc.yaw=rot_speed; }; }; display(); return; };
Danke nochmal für die Hilfe!
Mit freundlichen Grüßen
Seikuassi
-
Hallo nochmal,
ich habe ein Testprogramm geschrieben, um zu verstehen, wie Instancing funktioniert.
Funktioniert eigentlich ganz gut, ich habe allerdings eine Frage zur veralteten Matrix gl_ModelViewProjectionMatrix im Vertex-Shader.Erstmal der Shader:
#version 450\n layout(location=0)in vec3 VAO_position; layout(binding=2)buffer Matrices{ mat4 modelM; mat4 projM; }; void main(){ vec3 pos=VAO_position+vec3(gl_InstanceID*10.0f,0.0f,0.0f); gl_Position=projM*modelM*vec4(VAO_position+pos,1.0f); }
Im Fenster wird nichts angezeigt. Es fehlt die ViewMatrix.
Nur, wie wird die berechnet?Hier meine reshape-Funktion von freeglut:
void reshape(int width,int height){ const float aspect=static_cast<double>(width)/static_cast<double>(height); const static float cot=1/tan((65.0f/2)*PI/180.0f); OpenGL::glMatrixMode(OpenGL::GL_PROJECTION); OpenGL::glScissor(0,0,width,height); OpenGL::glViewport(0,0,width,height); { ssbo.projM[0]=cot/aspect; ssbo.projM[1]=0.0f; ssbo.projM[2]=0.0f; ssbo.projM[3]=0.0f; ssbo.projM[4]=0.0f; ssbo.projM[5]=cot; ssbo.projM[6]=0.0f; ssbo.projM[7]=0.0f; ssbo.projM[8]=0.0f; ssbo.projM[9]=0.0f; ssbo.projM[10]=(50.0f+0.05f)/(0.05f-50.0f); ssbo.projM[11]=-1.0f; ssbo.projM[12]=0.0f; ssbo.projM[13]=0.0f; ssbo.projM[14]=(2*50.0f*0.05f)/(0.05f-50.0f); ssbo.projM[15]=0.0f; } OpenGL::glLoadMatrixf(ssbo.projM); return; }
Das entspricht gluPerspective.
Und meine display- bzw. render-Funktion:
const static float scale_factor=0.01f; OpenGL::glMatrixMode(OpenGL::GL_MODELVIEW); { ssbo.modelM[0]=scale_factor*cos(loc.yaw*PI/180.0f); ssbo.modelM[1]=scale_factor*sin(loc.pitch*PI/180.0f)*sin(loc.yaw*PI/180.0f); ssbo.modelM[2]=-scale_factor*cos(loc.pitch*PI/180.0f)*sin(loc.yaw*PI/180.0f); ssbo.modelM[3]=0; ssbo.modelM[4]=0; ssbo.modelM[5]=scale_factor*cos(loc.pitch*PI/180.0f); ssbo.modelM[6]=scale_factor*sin(loc.pitch*PI/180.0f); ssbo.modelM[7]=0; ssbo.modelM[8]=scale_factor*sin(loc.yaw*PI/180.0f); ssbo.modelM[9]=-scale_factor*sin(loc.pitch*PI/180.0f)*cos(loc.yaw*PI/180.0f); ssbo.modelM[10]=scale_factor*cos(loc.pitch*PI/180.0f)*cos(loc.yaw*PI/180.0f); ssbo.modelM[11]=0; ssbo.modelM[12]=loc.x*cos(loc.yaw*PI/180.0f)+loc.z*sin(loc.yaw*PI/180.0f); ssbo.modelM[13]=loc.x*sin(loc.pitch*PI/180.0f)*sin(loc.yaw*PI/180.0f)-loc.z*sin(loc.pitch*PI/180.0f)*cos(loc.yaw*PI/180.0f)+loc.y*cos(loc.pitch*PI/180.0f); ssbo.modelM[14]=-loc.x*cos(loc.pitch*PI/180.0f)*sin(loc.yaw*PI/180.0f)+loc.z*cos(loc.pitch*PI/180.0f)*cos(loc.yaw*PI/180.0f)+loc.y*sin(loc.pitch*PI/180.0f); ssbo.modelM[15]=1; }
Das entspricht Rx*Ry*T*S (S=Scale-Matrix). (=Kamerabewegung)
Logisch ist, dass ssbo.modelM und ssbo.projM Pointer auf den Shader Storage sind. Das funktioniert ja auch alles.
Nur wie müsste jetzt die ViewMatrix berechnet werden? Wahrscheinlich auch in der reshape-Funktion, richtig?
Vielen Dank im Voraus!
Mit freundlichen Grüßen
PHBU
-
Die ViewMatrix ist doch die Matrix, welche die Kameraposition/Ausrichtung beschreibt.
Diese berechnest du doch bereits. Du nennst sie hier glaube Modelmatrix, was ja 'eigentlich' die Position/Ausrichtung von den einezelnen 3D-Objekten ist (Jedes 3D-Objekt hat seine eigene ModelMatrix)
-
Hallo XMA Man,
dachte ich eigentlich auch, dass ich alles berechnet hätte.
In GLSL im VertexShader gibt es wie schon gesagt das veraltete "Matrixprodukt" gl_ModelViewProjectionMatrix.
Hier sieht man im 5. Codefenster (der lange Code unten ), dass der Programmierer die viewMatrix mit den Daten von der gluLookAt-Funktion füttert. Die brauche ich aber im Prinzip nicht.
Hier nochmal der alte und der neue Vertex-Shader:
Alt#version 450 compatibility // schlecht... layout(location=0)in vec3 VAO_position; layout(location=1)in vec3 VAO_normals; layout(location=2)in vec3 VAO_tex; layout(binding=2)buffer Matrices{ mat4 modelM; mat4 projM; }; void main(){ vec3 pos=VAO_position+vec3(gl_InstanceID*10.0f,0.0f,0.0f); gl_Position=gl_ModelViewProjectionMatrix*vec4(VAO_position+pos,1.0f); // gl_ModelViewProjectionMatrix ist deprecated und möchte ich ersetzen };
Funktioniert einwandfrei, aber halt mit einer deprecated Funktion.
Neu
#version 450 layout(location=0)in vec3 VAO_position; layout(location=1)in vec3 VAO_normals; layout(location=2)in vec3 VAO_tex; layout(binding=2)buffer Matrices{ mat4 modelM; mat4 projM; }; void main(){ vec3 pos=VAO_position+vec3(gl_InstanceID*10.0f,0.0f,0.0f); gl_Position=projM*modelM*vec4(VAO_position+pos,1.0f); // hier berechne ich die Position ohne gl_ModelViewProjectionMatrix };
Der Code funktioniert halt nicht so, wie er soll => es werden keine Objekte angezeigt (s. Bilder).
ohne_deprecated
mit_deprecatedIn einem Forum habe ich auch schonmal gelesen, dass Funktionen wie glLoadMatrix, glMultMatrix, glPush/PopMatrix und glMatrixMode etc. eigentlich nicht mehr verwendet werden sollten. Der Anwender soll "selber mehr berechnen".
In der neuen Vulkan API werden diese Funktionen vllt. gar nicht mehr existieren...
Ist ja im Prinzip egal. Nur warum wird bei mir nichts angezeigt?
Wäre dankbar für jeden Tipp. Oder einen Komplettcode oder Beispielcode etc.
Mit freundlichen Grüßen
PHBU
-
Um die Shader-Variable gl_ModelViewProjectionMatrix zu befüllen, nutzt du doch OpenGL::glLoadMatrixf(ssbo.projM); und das funktioniert ja offentsichtlich.
Kannst du irgentwie sichersstellen, dass die verwendeten Matrizen zur neuen Schreibweise wirklich gleich sind?
Das hier ist erstmal richtig. Das mache ich auch so:
gl_Position=projM*modelM*vec4(VAO_position+pos,1.0f);
Im Nofall kannst du ja die Matrizen abfragen und dann fest im Shader schreiben, nur um zu sehen, ob der richtige Inhalt dort ankommt.
-
Hallo XMAMan,
hast du gerade den Code von dir parat?
Mich würde v.a. interessieren, wie du die Daten zum Shader schreibst.
Ich verwende SSBOs (später schreibe ich nämlich mehr Daten rein).
Vertex-Shader
#version 450 layout(location=0)in vec3 VAO_position; layout(location=1)in vec3 VAO_normals; layout(location=2)in vec2 VAO_tex; layout(binding=1)buffer Matrices{ mat4 modelM; mat4 projM; }; out vec2 TexCoord; void main(){ vec3 pos=VAO_position+vec3(gl_InstanceID*10.0f,0.0f,0.0f); gl_Position=projM*modelM*vec4(VAO_position+pos,1.0f); TexCoord=VAO_tex; }
Fragment-Shader
#version 450 layout(binding=0)uniform sampler2D tex; in vec2 TexCoord; out vec4 outColor; void main(){ outColor=texture2D(tex,TexCoord); }
Shader-Klasse
class Shader{ public: /* öffentliche Strukturen, Aufzählungen */ enum ShaderType:unsigned char{ Fragment, Geometry, Vertex }; /* öffentliche Deklarationen */ signed char add(const char*,ShaderType); signed char compile(); void freeResources(); template<typename T>T*getStorageAddress(const string&,unsigned int,unsigned int); signed char setUniform(const char*,int); void use(); /* öffentliche Variablen/Konstanten */ private: /* private Strukturen, Aufzählungen */ struct storage{ void*address; unsigned int blockIndex; unsigned int ID; }; /* private Deklarationen */ /* private Variablen/Konstanten */ static unsigned int actProgramID; unsigned char isCompiled=false; unsigned int programID=0; vector<int>shaderIDs; map<string,storage>storages; };
Hier ist wahrscheinlich die Funktion getStorageAddress am Wichtigsten
template<typename T>T*Shader::getStorageAddress(const string&name,unsigned int binding,unsigned int size){ if(this->isCompiled==false)return NULL; // wenn Programm noch nicht kompiliert wurde if(this->storages.count(name)==0){ // wenn Storage noch nicht erfragt wurde storage&actElement=this->storages[name]; if(Shader::actProgramID!=this->programID){ OpenGL::glUseProgram(this->programID); Shader::actProgramID=this->programID; } if((actElement.blockIndex=OpenGL::glGetProgramResourceIndex(this->programID,OpenGL::GL_SHADER_STORAGE_BLOCK,name.c_str()))!=OpenGL::GL_INVALID_INDEX){ // wenn Storage existiert OpenGL::glGenBuffers(1,&actElement.ID); OpenGL::glBindBuffer(OpenGL::GL_SHADER_STORAGE_BUFFER,actElement.ID); OpenGL::glBufferData(OpenGL::GL_SHADER_STORAGE_BUFFER,size,NULL,OpenGL::GL_DYNAMIC_DRAW); // Speicher allokieren actElement.address=OpenGL::glMapBuffer(OpenGL::GL_SHADER_STORAGE_BUFFER,OpenGL::GL_WRITE_ONLY); OpenGL::glShaderStorageBlockBinding(this->programID,actElement.blockIndex,binding); OpenGL::glBindBufferBase(OpenGL::GL_SHADER_STORAGE_BUFFER,binding,actElement.ID); }else{ this->storages.erase(name); cerr<<"Storage \""<<name<<"\" existiert nicht"<<endl; return NULL; } } return reinterpret_cast<T*>(this->storages[name].address); }
Diese gibt mir nicht NULL zurück. Müsste also funktionieren.
display-Funktion
void display(){ const static float scale_factor=0.01f; OpenGL::glClear(OpenGL::GL_COLOR_BUFFER_BIT|OpenGL::GL_DEPTH_BUFFER_BIT); // Modellmatrix OpenGL::glMatrixMode(OpenGL::GL_MODELVIEW); { ssbo.modelM[0]=scale_factor*cos(loc.yaw*PI/180.0f); ssbo.modelM[1]=scale_factor*sin(loc.pitch*PI/180.0f)*sin(loc.yaw*PI/180.0f); ssbo.modelM[2]=-scale_factor*cos(loc.pitch*PI/180.0f)*sin(loc.yaw*PI/180.0f); ssbo.modelM[3]=0; ssbo.modelM[4]=0; ssbo.modelM[5]=scale_factor*cos(loc.pitch*PI/180.0f); ssbo.modelM[6]=scale_factor*sin(loc.pitch*PI/180.0f); ssbo.modelM[7]=0; ssbo.modelM[8]=scale_factor*sin(loc.yaw*PI/180.0f); ssbo.modelM[9]=-scale_factor*sin(loc.pitch*PI/180.0f)*cos(loc.yaw*PI/180.0f); ssbo.modelM[10]=scale_factor*cos(loc.pitch*PI/180.0f)*cos(loc.yaw*PI/180.0f); ssbo.modelM[11]=0; ssbo.modelM[12]=loc.x*cos(loc.yaw*PI/180.0f)+loc.z*sin(loc.yaw*PI/180.0f); ssbo.modelM[13]=loc.x*sin(loc.pitch*PI/180.0f)*sin(loc.yaw*PI/180.0f)-loc.z*sin(loc.pitch*PI/180.0f)*cos(loc.yaw*PI/180.0f)+loc.y*cos(loc.pitch*PI/180.0f); ssbo.modelM[14]=-loc.x*cos(loc.pitch*PI/180.0f)*sin(loc.yaw*PI/180.0f)+loc.z*cos(loc.pitch*PI/180.0f)*cos(loc.yaw*PI/180.0f)+loc.y*sin(loc.pitch*PI/180.0f); ssbo.modelM[15]=1; } OpenGL::glLoadMatrixf(ssbo.modelM); { OpenGL::glBindVertexArray(VAOs[0]->ID); // VAO von GPU binden OpenGL::glActiveTexture(OpenGL::GL_TEXTURE_0); OpenGL::glBindTexture(OpenGL::GL_TEXTURE_2D,VAOs[0]->VBO.picID); // Textur von GPU binden OpenGL::glBindBuffer(OpenGL::GL_ELEMENT_ARRAY_BUFFER,VAOs[0]->VBO.indID); // Index-Array von GPU binden blockShader.use(); OpenGL::glDrawElementsInstanced(OpenGL::GL_TRIANGLES,VAOs[0]->VBO.indSize,OpenGL::GL_UNSIGNED_BYTE,NULL,20); OpenGL::glBindBuffer(OpenGL::GL_ELEMENT_ARRAY_BUFFER,0); OpenGL::glBindVertexArray(0); } OpenGL::glutSwapBuffers(); return; }
initShaderStorage-Funktion, die die Adresse des SSBO "Matrices" ermittelt
signed char initShaderStorage(){ ssbo.modelM=blockShader.getStorageAddress<float>("Matrices",1,4*4*sizeof(float)+4*4*sizeof(float)); if(ssbo.modelM==NULL){ cerr<<"Matrices can't be loaded."<<endl; return -1; } ssbo.projM=ssbo.modelM+4*4*sizeof(float); return 0; }
Rufst Du bei dir auch glLoadMatrix o.ä. auf?
Falls Du/Ihr mehr Code benötigen solltet/solltest, schreibt. Ich komm da wirklich nicht weiter.
Mit freundlichen Grüßen
PHBU
-
Ok, so sehen die Matrizen bei mir im Vertexshader aus:
#version 450 uniform mat4 projection_matrix; uniform mat4 modelview_matrix;
So lege ich die Variable erstmal an
int id1 = GetUniformLocation(shaderProgrameId, "projection_matrix"); int id2 = GetUniformLocation(shaderProgrameId, "modelview_matrix");
So übergebe ich dann die Daten an den Shader
Matrix4 projectionMatrix = ...; Matrix4 modelViewMatrix = ...; UniformMatrix4(id1, false, ref projectionMatrix); UniformMatrix4(id2, false, ref modelViewMatrix);
Ich nutze OpenTK als Framework.
Ich muss schon zugeben, dass sieht etwas anders aus als glGetProgramResourceIndex. Ist das auch für Uniform-Variablen?
-
Hallo,
glGetProgramResourceIndex geht auch für Uniforms (GL_UNIFORM statt GL_SHADER_STORAGE_BLOCK).
Also nutzt Du nicht glLoadMatrix!?
MfG
PHBU
-
Nein, glLoadMatrix nutze ich nicht. Ich denke mal, dass macht nur Sinn, wenn man gl_ModelViewProjectionMatrix im Shader verwenden will. Vielleicht klappt das auch nur mit alten OpenGL-Versionen.
-
Hallo nochmal,
wenn ich im Vertex-Shader folgenden Code verwende,
#version 450\n layout(location=0)in vec3 VAO_position; layout(location=1)in vec3 VAO_normals; layout(location=2)in vec2 VAO_tex; layout(binding=1)uniform ModelMatrix{mat4 modelM;}; layout(binding=2)uniform ProjectionMatrix{mat4 projM;}; out vec2 TexCoord; void main(){ vec3 pos=VAO_position+vec3(gl_InstanceID*10.0f,0.0f,0.0f); gl_Position=projM*modelM*vec4(VAO_position+pos,1.0f); TexCoord=VAO_tex; }
(benutze jetzt doch wieder Uniforms) dann würde es mit den Funktionsaufrufen
ubo.modelM=blockShader.getUniformAddress<float>("ModelMatrix",1u); ubo.projM=blockShader.getUniformAddress<float>("ProjectionMatrix",2u);
funktionieren (ubo.modelM und ubo.projM sind vom Typ float*).
Hier nochmal die Funktion getUniformAddress:
template<typename T>T*Shader::getUniformAddress(const string&name,unsigned int binding){ if(this->isCompiled==false)return NULL; // wenn Programm noch nicht kompiliert wurde if(this->uniforms.count(name)==0){ // wenn Storage noch nicht erfragt wurde uniform&actElement=this->uniforms[name]; if(Shader::actProgramID!=this->programID){ OpenGL::glUseProgram(this->programID); Shader::actProgramID=this->programID; } if((actElement.blockIndex=OpenGL::glGetUniformBlockIndex(this->programID,name.c_str()))!=OpenGL::GL_INVALID_INDEX){ // wenn Storage existiert int size; OpenGL::glGetActiveUniformBlockiv(this->programID,actElement.blockIndex,OpenGL::GL_UNIFORM_BLOCK_DATA_SIZE,&size); OpenGL::glGenBuffers(1,&actElement.ID); OpenGL::glBindBuffer(OpenGL::GL_UNIFORM_BUFFER,actElement.ID); OpenGL::glBufferData(OpenGL::GL_UNIFORM_BUFFER,size,NULL,OpenGL::GL_DYNAMIC_DRAW); // Speicher allokieren actElement.address=OpenGL::glMapBuffer(OpenGL::GL_UNIFORM_BUFFER,OpenGL::GL_WRITE_ONLY); OpenGL::glUniformBlockBinding(this->programID,actElement.blockIndex,binding); OpenGL::glBindBufferBase(OpenGL::GL_UNIFORM_BUFFER,binding,actElement.ID); }else{ this->uniforms.erase(name); cerr<<"Uniform \""<<name<<"\" existiert nicht"<<endl; return NULL; } } return reinterpret_cast<T*>(this->uniforms[name].address); }
Und spaßenshalber nochmal die komplette "Klassendeklaration":
class Shader{ public: /* öffentliche Strukturen, Aufzählungen */ enum ShaderType:unsigned char{ Fragment, Geometry, Vertex }; /* öffentliche Deklarationen */ signed char add(const char*,ShaderType); signed char compile(); void freeResources(); template<typename T>T*getUniformAddress(const string&,unsigned int); signed char setUniformi(const char*,int); void use(); /* öffentliche Variablen/Konstanten */ private: /* private Strukturen, Aufzählungen */ struct uniform{ void*address; unsigned int blockIndex; unsigned int ID; }; /* private Deklarationen */ /* private Variablen/Konstanten */ static unsigned int actProgramID; unsigned char isCompiled=false; unsigned int programID=0; vector<int>shaderIDs; map<string,uniform>uniforms; };
Irgendwie finde ich nicht die Vorgehensweise (code o.ä.), wie man auf Member einer Uniform/ShaderStorage-Blocks vom Hauptprogramm zugreifen kann...
Es wäre jetzt mit Uniforms nicht schlimm, da diese ja nur mindestens (hoffe das ist richtig) 16 kB auf dem VRAM einnehmen. Aber es wäre halt verschwendeter Platz...Falls Ihr noch Tipps habt, schreibt .
Mit freundlichen Grüßen
PHBU
-
Der Code sieht ja grauenvoll aus
-
roflo schrieb:
Der Code sieht ja grauenvoll aus
der beitrag ist von seiner nuetzlichkeit auch grauenvoll
vielleicht kannst du deinen beitrag aufwerten indem du ihm zeigst wie er seinen code aufwertet.