1On est là.YUVDessinez une mosaïque basée sur la carte de texture!!!
Comment??
Diviser l'image en petits blocs de pixels,Puis changez la couleur de chaque bloc de pixels à la couleur d'un point(C'est juste que ce petit bloc de pixels a la même couleur)
2 Mise en œuvre dans les shaders de puces
vec2 XYMosaic = vec2(floor(intXY.x / mosaicSize.x) * mosaicSize.x, floor(intXY.y / mosaicSize.y) * mosaicSize.y);// Le but de cette phrase est de grossir les coordonnées de texture à l'origine méticuleuses selon les blocs de mosaïque (Compréhension personnelle)
Le principe est comme une petite image pixel , Coller sur une grande fenêtre :
Après l'échantillonnage de l'échantillonneur d'ombres de puces :
Shader à puces:
#version 330 core layout(location = 0) out vec4 FragColor; in vec2 TexCoord; uniform sampler2D dataY; uniform sampler2D dataU; uniform sampler2D dataV; vec3 yuv; vec3 rgb; // Taille du bloc de mosaïque const vec2 mosaicSize = vec2(30.0, 30.0); //Taille de l'image const vec2 TexSize = vec2(1920.0, 1080.0); void main() { // Calculer la position réelle de l'image Convertir en1920*1080Coordonnées de vec2 intXY = vec2(TexCoord.x * TexSize.x, TexCoord.y * TexSize.y); //floor(x)Retour⼩égal àXDe⼤Valeur entière. Calculer les coordonnées des mosaïques entières vec2 XYMosaic = vec2(floor(intXY.x / mosaicSize.x) * mosaicSize.x, floor(intXY.y / mosaicSize.y) * mosaicSize.y); // Convertir en coordonnées de texture vec2 UVMosaic = vec2(XYMosaic.x / TexSize.x, XYMosaic.y / TexSize.y); yuv.x = texture2D(dataY,UVMosaic).r-0.0625; yuv.y = texture2D(dataU,UVMosaic).r-0.5; yuv.z = texture2D(dataV,UVMosaic).r-0.5; rgb = mat3(1, 1, 1, 0, -0.18732, 1.8556, 1.57481, -0.46813, 0) * yuv; FragColor = vec4(rgb.x, rgb.y,rgb.z,1); };
#include<string> #include<windows.h> #include<fstream> #include<sstream> #include<iostream> #include<stdio.h> #include <glad/glad.h> #include <GLFW/glfw3.h> const unsigned int SCR_WIDTH = 500; const unsigned int SCR_HEIGHT = 600; const int len = 1920 * 1080 * 3 / 2; BYTE YUVdata[len]; unsigned int VBO = 0; unsigned int VAO = 0; unsigned int EBO = 0; unsigned int texturePIC = 0; int shaderProgram = 0; GLuint texIndexarray[3]; GLuint texUniformY = 99; GLuint texUniformU = 99; GLuint texUniformV = 99; void LoadPicture() { glGenTextures(3, texIndexarray);// Générer trois index de texture glBindTexture(GL_TEXTURE_2D, texIndexarray[0]); //Pourbind Configuration de texture surround pour ,Mode de filtrage glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, texIndexarray[1]); //Pourbind Configuration de texture surround pour ,Mode de filtrage glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, texIndexarray[2]); //Pourbind Configuration de texture surround pour ,Mode de filtrage glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //En utilisant le programme Shader, Renvoie le numéro de série de l'échantillonneur glUseProgram(shaderProgram);// Cette déclaration doit avoir ;Installation Spécifiez le programme Shader texUniformY = glGetUniformLocation(shaderProgram, "dataY"); texUniformU = glGetUniformLocation(shaderProgram, "dataU"); texUniformV = glGetUniformLocation(shaderProgram, "dataV"); ////----------Chargement des données-------------------------------------------------------- FILE* fp = fopen("./out.yuv", "rb+");//I420 int returns = fread(YUVdata, 1, len, fp); int w = 1920; int h = 1080; int ysize = w*h; int uvsize = w * h / 4; void* uptr = &YUVdata[ysize]; void* vptr = &YUVdata[ysize * 5 / 4]; //--------------------------------------------------------------------------- glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texIndexarray[0]);// texindexarray[0] =1 //UtiliserGL_redReprésente un seul canal,glfw3Il n'y en a pas.YUVCelle - là.GLPropriétés; glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, YUVdata); glUniform1i(texUniformY, 0); //Adoption glUniform1i Paramètres pour,Chaque uniform L'échantillonneur correspond à la bonne cellule de texture ;Attention, ça ne marche pas icitesindexarray[0]; glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texIndexarray[1]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w / 2, h / 2, 0, GL_RED, GL_UNSIGNED_BYTE, uptr); glUniform1i(texUniformU, 1); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, texIndexarray[2]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w / 2, h / 2, 0, GL_RED, GL_UNSIGNED_BYTE, vptr); glUniform1i(texUniformV, 2); ; glUseProgram(0); } void render() { glBindVertexArray(VAO); glUseProgram(shaderProgram); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); //glDrawArrays(GL_TRIANGLE_FAN,0,4);Oui. glUseProgram(0); glBindVertexArray(0); } void initmodule() { // Faire un modèle ;Carré; .La correspondance entre les coordonnées du Vertex et les coordonnées de texture est cartographiée float vertexs[] = { //Coordonnées du vertex-------Coordonnées de texture( Rotation des coordonnées de l'écran ) 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f }; // Un carré vient de deux triangles ; Enregistrer l'ordre d'indexation des sommets unsigned int indexs[] = { 0,1,3, 1,2,3, }; //Fais - le.VAO glGenVertexArrays(1, &VAO); glBindVertexArray(VAO); //Fais - le.VBO glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); // Créer un espace d'affichage glBufferData(GL_ARRAY_BUFFER, sizeof(vertexs), vertexs, GL_STATIC_DRAW); // Définir le tampon d'index glGenBuffers(1, &EBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexs), indexs, GL_STATIC_DRAW); //Charger l'image de texture,Générer une texture LoadPicture(); //Set No.0Points d'ancrage,3Un point,Pas besoin de normalisation,Portée5- Oui.float Vous pouvez lire le point suivant glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); // Ouvrir les sommets glEnableVertexAttribArray(0); // Paramètres des attributs de texture , Texture au premier point d'ancrage ( Spécifier les données Vertex ) glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); //Ouvrir la texture glEnableVertexAttribArray(1); //DébloquerVBO glBindBuffer(GL_ARRAY_BUFFER, 0); //DégroupageVAO glBindVertexArray(0); } void initshader(const char* verpath, const char* fragpath) { //Compilershader,Et enregistrershaderID std::string VerCode(""); std::string fregCode(""); //Lire le document std::ifstream vShaderFile; std::ifstream fShaderFile; vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit); fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit); try { vShaderFile.open(verpath); fShaderFile.open(fragpath); std::stringstream vsstream, fsstream; vsstream << vShaderFile.rdbuf(); fsstream << fShaderFile.rdbuf(); VerCode = vsstream.str(); fregCode = fsstream.str(); } catch (const std::exception&) { std::cout << "read file error" << std::endl; } const char* vshader = VerCode.c_str(); const char* fshader = fregCode.c_str(); //shader Compiler les connexions unsigned int vertexID = 0, fragID = 0; char infoLog[512];//Stocker les informations d'erreur int successflag = 0; vertexID = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexID, 1, &vshader, NULL); glCompileShader(vertexID); // Obtenir si la compilation a réussi glGetShaderiv(vertexID, GL_COMPILE_STATUS, &successflag); if (!successflag) { glGetShaderInfoLog(vertexID, 512, NULL, infoLog); std::string errstr(infoLog); std::cout << "v shader err" << infoLog; } //frag fragID = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragID, 1, &fshader, NULL); glCompileShader(fragID); // Obtenir si la compilation a réussi glGetShaderiv(fragID, GL_COMPILE_STATUS, &successflag); if (!successflag) { glGetShaderInfoLog(fragID, 512, NULL, infoLog); std::string errstr(infoLog); std::cout << "f shader err" << infoLog; } //Liens shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexID); glAttachShader(shaderProgram, fragID); glBindAttribLocation(shaderProgram, 0, "aPos"); glBindAttribLocation(shaderProgram, 1, "texCoord"); glLinkProgram(shaderProgram); glGetProgramiv(shaderProgram, GL_LINK_STATUS, &successflag); if (!successflag) { glGetShaderInfoLog(shaderProgram, 512, NULL, infoLog); std::string errstr(infoLog); std::cout << "link error"; } //Une fois la compilation terminée, Vous pouvez supprimer le Programme d'étape intermédiaire glDeleteShader(vertexID); glDeleteShader(fragID); } void processInput(GLFWwindow *window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) { // Régler la fenêtre pour fermer ,Sortir de la boucle glfwSetWindowShouldClose(window, true); } } void framebuffer_size_callback(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); } int main() { //glfwInitialisation glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //glfwCréer une fenêtre GLFWwindow* window = glfwCreateWindow(500, 600, "LearnOpenGL", NULL, NULL); if (window == NULL) { printf("Impossible de créer la fenêtre"); //Résiliation glfwTerminate(); return -1; } //Afficher la fenêtre glfwMakeContextCurrent(window); //Réglage du rappel, Cette fonction de rappel est appelée lorsque la fenêtre est redimensionnée glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); // gladInitialisation if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { printf("Échec du chargement"); return -1; } initshader("vertexShader.glsl", "fragmentShader.glsl");// Compilez d'abord les ombres initmodule(); // Utilisez la boucle pour obtenir l'effet de rendu de la boucle while (!glfwWindowShouldClose(window)) { // Personnaliser les événements d'entrée processInput(window); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); render(); //Tampon interactif, Sinon, l'espace vide est affiché glfwSwapBuffers(window); // Événements d'entrée / sortie , Sinon, la fenêtre ne peut pas être interactive glfwPollEvents(); } // Terminer le rendu Fermer et nettoyer glfwRessources locales glfwTerminate(); return 0; }
Shaders vertex:
#version 330 core layout(location = 0) in vec3 aPos; layout(location = 1) in vec2 texCoord; out vec2 TexCoord; void main() { gl_Position = vec4(aPos.x,aPos.y,aPos.z,1.0); TexCoord = texCoord; };
Image originale:
Afficher les résultats: