Ich habe implementiert CPU-Code, der eine projizierte Textur in eine größere Textur auf einem 3D-Objekt, "Abziehbild Backen" kopiert, wenn Sie so wollen, aber jetzt muss ich es auf der GPU implementieren. Um dies zu tun, hoffe ich, Compute Shader zu verwenden, da es ziemlich schwierig ist, einen FBO in meinem aktuellen Setup hinzuzufügen. https://stackoverflow.com/a/27124029/2579996Compute Shader schreibe auf Textur
Die Textur, die geschrieben wird:
Example image from my current implementation
Diese Frage ist mehr darüber, wie Shadern Compute zu verwenden, sondern für alle Interessierten, die Idee auf eine Antwort basiert ich von Benutzer jozxyqk bekam, hier zu sehen -zu ist in meinem Code _texture
genannt, während das projizierte ein _textureProj
Einfache Compute Shader
istconst char *csSrc[] = {
"#version 440\n",
"layout (binding = 0, rgba32f) uniform image2D destTex;\
layout (local_size_x = 16, local_size_y = 16) in;\
void main() {\
ivec2 storePos = ivec2(gl_GlobalInvocationID.xy);\
imageStore(destTex, storePos, vec4(0.0,0.0,1.0,1.0));\
}"
};
Wie Sie sehen, möchte ich derzeit nur die Textur auf eine beliebige (blaue) Farbe aktualisiert haben.
Update-Funktion
void updateTex(){
glUseProgram(_computeShader);
const GLint location = glGetUniformLocation(_computeShader, "destTex");
if (location == -1){
printf("Could not locate uniform location for texture in CS");
}
// bind texture
glUniform1i(location, 0);
glBindImageTexture(0, *_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
// ^second param returns the GLint id - that im sure of.
glDispatchCompute(_texture->width()/16, _texture->height()/16, 1);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
glUseProgram(0);
printOpenGLError(); // reports no errors.
}
Problem Wenn ich die updateTex()
außerhalb meines Hauptprogramm-Objekt aufrufen siehe i Null Wirkung, während, wenn ich sie in ihrem Umfang nennen etwa so:
glUseProgram(_id); // vert, frag shader pipe
updateTex();
// Pass uniforms to shader
// bind _textureProj & _texture (latter is the one im trying to update)
glUseProgram(0);
Dann beim Rendern sehe ich das:
FRAGE: Ich stelle fest, dass die Update-Methode innerhalb des Haupt-Programmobjekt Umfang Einstellung ist nicht der richtige Weg, es zu tun, aber es ist der einzige Weg, um alle visuellen Ergebnisse zu erhalten. Es scheint mir, dass, was passiert ist, dass es den fragmentshader ziemlich beseitigt und zu screenspace ...
Was kann ich tun, damit dieses richtig funktioniert? (Mein Hauptaugenmerk ist in der Lage zu schreiben alles zu der Textur & Update)
Bitte lassen Sie mich wissen, wenn mehr Code Buchung benötigt.
Ich bin nicht sicher, was Sie mit "Hauptprogramm Objektumfang" meinen. Was macht '_programObject-> activate();' do? – GuyRT
Ist Ihr "Hauptprogrammumfang" auf einem separaten Thread? OpenGL funktioniert nicht richtig/überhaupt nicht, wenn Sie zwischen Threads telefonieren. –
@GuyRT - Oh, tut mir leid, vielleicht habe ich dort den falschen Begriff benutzt. Was _programObject-> activate() im Wesentlichen ist, dass es glUseProgram (id) aufruft, wo id GLint ist, werde ich meine Frage bearbeiten. – mike