Remplacement pour gl_Position = gl_ModelViewProjectionMasortingx * gl_Vertex;

Il y a quelques questions comme celle-ci, mais je n’ai toujours pas compris. Je codais avec OpenGL il y a plus de 10 ans et j’ai remarqué à quel point il est difficile d’entrer dans OpenGL moderne. La page OpenGL.org est un désordre épouvantable quand il s’agit d’exemples, on ne sait jamais de quelle version il s’agit, n’importe quelle version semble être mélangée dans divers exemples de code. D’accord, j’ai un ancien code que je souhaite mettre à jour pour OpenGL> 3 au moins. Donc, la première chose que j’ai faite a été de passer de glVertex3fv à finalement le faire avec glVertexAtsortingbPointer (au cours d’une étape avec glVertexPointer jusqu’à ce que je lise ceci est également déconseillé). Cela fonctionne bien, mais lorsque j’essayais de placer des textures, je me suis retrouvé coincé rapidement et je suppose que c’est à cause d’un mauvais positionnement et que je voulais me débarrasser du code c ++:

glMasortingxMode( GL_PROJECTION ); glLoadIdentity(); glFrustum( -RProjZ, +RProjZ, -Aspect*RProjZ, +Aspect*RProjZ, 1.0, 32768.0 ); 

et le dessiner

 // bind vertex buffer glBindBuffer(GL_ARRAY_BUFFER, VertBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(float) * size, verts, GL_STATIC_DRAW); // enable arrays glEnableVertexAtsortingbArray(0); // set pointers glVertexAtsortingbPointer(0,3,GL_FLOAT, GL_FALSE, sizeof(float) * floatsPerVertex, 0); // render ComplexSurface glDrawArrays(GL_TRIANGLE_FAN, 0, size); glDisableVertexAtsortingbArray(0); 

avec dans le vertexshader

 gl_Position = gl_ModelViewProjectionMasortingx * gl_Vertex; 

Et tout fonctionne comme par magie. Maintenant, ne vous méprenez pas, je suis un grand fan de magie, mais … Ensuite, j’ai trouvé quelques conversions de masortingce qui peuvent être utilisées pour obtenir une masortingce pour remplacer glFrustum, mais chaque fois que j’essaie de la remplacer, échoue mal (bien que je pense avoir compris les calculs derrière glFrustum et la conversion dans la masortingce).

Ce qui a essayé, c’est quelque chose comme

 buildPerspProjMat(g_ProjView,FovAngle,Aspect,1.0,32768.0 ); glUseProgram(g_program); glUniformMasortingx4fv(g_programFrustum, 1, GL_FALSE, g_ProjView ); glUseProgram(0); 

et utiliser la position dans le shader depuis le buffer ci-dessus avec le projection matix, mais cela ne marche pas du tout.

Donc, ce que je ne comprends pas maintenant, c’est où remplacer ceci et avec quoi dans le shader. Je ne sais pas à quel moment le glMasortingxMode a lieu et “quand” pour le remplacer par une masortingce uniforme (passer l’argument comme uniforme n’est pas le problème ici). Je ne peux pas compter le nombre de tutoriels que j’ai déjà lus, mais je suis toujours dérouté par toutes les versions mixtes. Je suis toujours content de quelques exemples de code, mais s’il vous plaît OpenGL 3 ou supérieur.

La prochaine serait un remplacement de glTexCoord2f pour texturer, mais c’est une autre histoire 🙂

Je trouve que lorsqu’on pense à OpenGL moderne, il vaut mieux oublier que glMasortingxMode jamais existé.

Dans cet esprit, gl_ModelViewProjectionMasortingx ce dont vous avez besoin pour l’opération de dessin la plus élémentaire: un remplacement pour gl_ModelViewProjectionMasortingx . Comme son nom l’indique, il s’agit d’une combinaison de 3 masortingces différentes: la masortingce de modèle, la masortingce de vue et la masortingce de projection.

Vous aurez donc besoin de 3 variables uniformes de type mat4 dans votre shader. Que vous utiliserez comme suit:

 uniform mat4 projMat; uniform mat4 viewMat; uniform mat4 modelMat; layout (location = 0) in vec3 position; void main() { gl_Position = projMat * viewMat * modelMat * vec4(position, 1.0); } 

Ce code de shader remplit la même fonction que celle que vous avez précédemment. Ce qui a changé, c’est que gl_ModelViewProjectionMasortingx été remplacé par 3 variables uniformes (qui peuvent être combinées en une seule si vous vous assurez de les multiplier vous-même du côté C ++ avant de les transmettre). Et le gl_Vertex gl_Vertex été remplacé par une variable d’entrée.

Du côté C ++, vous devrez faire 2 choses. Vous devez d’abord obtenir l’emplacement de chacun de ces uniformes:

 GLuint modelMatIdx = glGetUniformLocation(shaderProgId, "modelMat"); GLuint viewMatIdx = glGetUniformLocation(shaderProgId, "viewMat"); GLuint projMatIdx = glGetUniformLocation(shaderProgId, "projMat"); 

Et avec cela en main, vous pouvez maintenant passer les valeurs de chaque uniforme avant de dessiner avec glUniformMasortingx4fv .

Une bibliothèque particulière qui rend cela particulièrement facile est GLM . Par exemple, pour obtenir la même masortingce de projection que dans votre exemple, procédez comme suit:

 glm::mat4 projMat = glm::frustum(-RProjZ, +RProjZ, -Aspect*RProjZ, +Aspect*RProjZ, 1.0, 32768.0); 

et vous le passeriez comme ceci:

 glUniformMasortingx4fv(projMatIdx, 1, GL_FALSE, glm::value_ptr(projMat)); 

Maintenant que vous savez comment faire, j’aimerais aborder la question du “quand”. Vous avez dit que vous n’étiez pas clair sur le mode masortingce, ce qui me ramène à mon affirmation précédente d’oubli. Le mode masortingce était là pour vous permettre d’indiquer à opengl quels composants intégrés devaient être affectés par des appels à des opérations de masortingce OpenGL telles que glTranslate, glFrustum, etc., mais tout cela a disparu. Vous êtes maintenant en charge de la gestion des (éventuellement de nombreuses) masortingces impliquées. Tout ce que vous avez à faire est de les passer avant de dessiner (comme je l’ai montré ci-dessus) et tout ira bien. Assurez-vous simplement que le programme est lié avant de tenter de modifier ses uniformes.

Voici un exemple de travail (si vous êtes surpris par gl :: … au lieu de gl … c’est parce que j’utilise un en-tête opengl généré par glLoadGen qui place toutes les fonctions de l’API opengl dans l’espace de noms gl.)

 GLuint simpleProgramID; // load the shader and make the program GLuint modelMatIdx = gl::GetUniformLocation(simpleProgramID, "modelMat"); GLuint viewMatIdx = gl::GetUniformLocation(simpleProgramID, "viewMat"); GLuint projMatIdx = gl::GetUniformLocation(simpleProgramID, "projMat"); GLuint vaoID; gl::GenVertexArrays(1, &vaoID); gl::BindVertexArray(vaoID); GLuint vertBufferID, indexBufferID; gl::GenBuffers(1, &vertBufferID); gl::GenBuffers(1, &indexBufferID); struct Vec2 { float x, y; }; struct Vec3 { float x, y, z; }; struct Vert { Vec3 pos; Vec2 tex; }; std::array cubeVerts = {{ { { 0.5f, 0.5f, 0.5f }, { 1.0f, 0.0f } }, { { 0.5f, 0.5f, -0.5f }, { 1.0f, 1.0f } }, { { 0.5f, -0.5f, -0.5f }, { 0.0f, 1.0f } }, { { 0.5f, -0.5f, 0.5f }, { 0.0f, 0.0f } }, { { -0.5f, 0.5f, 0.5f }, { 0.0f, 0.0f } }, { { -0.5f, 0.5f, -0.5f }, { 0.0f, 1.0f } }, { { -0.5f, -0.5f, -0.5f }, { 1.0f, 1.0f } }, { { -0.5f, -0.5f, 0.5f }, { 1.0f, 0.0f } } }}; std::array cubeIdxs = {{ 0, 2, 1, 0, 3, 2, // Right 4, 5, 6, 4, 6, 7, // Left 0, 7, 3, 0, 4, 7, // Top 1, 6, 2, 1, 5, 6, // Bottom 0, 5, 1, 0, 4, 5, // Front 3, 7, 6, 3, 6, 2 // Back }}; // Vertex buffer gl::BindBuffer(gl::ARRAY_BUFFER, vertBufferID); gl::BufferData(gl::ARRAY_BUFFER, sizeof(Vert) * cubeVerts.size(), cubeVerts.data(), gl::STATIC_DRAW); gl::EnableVertexAtsortingbArray(0); // Matches layout (location = 0) gl::VertexAtsortingbPointer(0, 3, gl::FLOAT, gl::FALSE_, sizeof(Vert), 0); gl::EnableVertexAtsortingbArray(1); // Matches layout (location = 1) gl::VertexAtsortingbPointer(1, 2, gl::FLOAT, gl::FALSE_, sizeof(Vert), (GLvoid*)sizeof(Vec3)); // Index buffer gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, indexBufferID); gl::BufferData(gl::ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * cubeIdxs.size(), cubeIdxs.data(), gl::STATIC_DRAW); gl::BindVertexArray(0); glm::mat4 projMat = glm::perspective(56.25f, 16.0f/9.0f, 0.1f, 100.0f); glm::mat4 viewMat = glm::lookAt(glm::vec3(5, 5, 5), glm::vec3(0, 0, 0), glm::vec3(0, 0, 1)); glm::mat4 modelMat; // identity while (!glfwWindowShouldClose(window)) { gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT); gl::UseProgram(simpleProgramID); gl::UniformMasortingx4fv(projMatIdx, 1, gl::FALSE_, glm::value_ptr(projMat)); gl::UniformMasortingx4fv(viewMatIdx, 1, gl::FALSE_, glm::value_ptr(viewMat)); gl::UniformMasortingx4fv(modelMatIdx, 1, gl::FALSE_, glm::value_ptr(modelMat)); gl::BindVertexArray(vaoID); gl::DrawElements(gl::TRIANGLES, 36, gl::UNSIGNED_INT, 0); gl::BindVertexArray(0); gl::UseProgram(0); glfwSwapBuffers(window); glfwPollEvents(); } 

Vertex Shader associé:

 //[VERTEX SHADER] #version 430 uniform mat4 projMat; uniform mat4 viewMat; uniform mat4 modelMat; layout (location = 0) in vec3 in_position; // matches gl::EnableVertexAtsortingbArray(0); layout (location = 1) in vec2 in_uv; // matches gl::EnableVertexAtsortingbArray(1); out vec2 uv; void main() { gl_Position = projMat * viewMat * modelMat * vec4(in_position, 1.0); uv = in_uv; } 

Et enfin Fragment shader:

 //[FRAGMENT SHADER] #version 430 in vec2 uv; out vec4 color; void main() { color = vec4(uv, 0.0, 1.0); } 

L’image résultante est:

entrez la description de l'image ici

Eh bien, je conviens que la plupart des tutoriels OpenGL confondent des éléments de contenu obsolètes et non obsolètes. Pour vous mettre dans la bonne direction, laissez-moi vous expliquer.

gl_ModelViewProjectionMasortingx , gl_ModeView , glMasortingxMode() et la stack de masortingce glPushMasortingx() glPopMasortingx() sont obsolètes. Vous devez définir vos propres masortingces en tant que variables uniformes, puis les définir et les transmettre au shader à l’aide de glUniform* .

gl_Vertex est également obsolète. En fait, tous les noms d’atsortingbuts fixes sont déconseillés. Sinon, vous devez définir vos propres noms d’atsortingbut et les lier à des emplacements spécifiques. Vous pouvez ensuite définir leurs valeurs à l’aide de glVertexAtsortingbPointer en lui transmettant l’emplacement de l’atsortingbut ( Explication complète ici ). Par exemple:

 glVertexAtsortingbPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices); // for vertices glVertexAtsortingbPointer(1, 4, GL_FLOAT, GL_FALSE, 0, color); // for color 

Et pour le code shader

 layout (location = 0) in vec4 vertex; layout (location = 1) in vec4 color; uniform mat4 modelview; uniform mat4 projection; void main() { gl_Position = projection* modelview* vertex; } 

Pour les emplacements d’atsortingbuts, vous pouvez les définir dans le code de shader comme je l’ai fait ou à partir de l’API OpenGL à l’aide de glBindAtsortingbLocation .

La gestion des variables uniformes peut être quelque peu délicate si vous êtes habitué aux anciennes variables globales OpenGL telles que gl_ModelView J’ai écrit un article qui, espérons-le, peut vous aider à gérer des variables uniformes pour un grand projet.