当前位置:网站首页>OpenGL Mosaic (8)

OpenGL Mosaic (8)

2022-06-13 05:39:00 Qiang Ying

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

RÉFÉRENCES: Jadon_Mao 

 

 

 

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:

 

原网站

版权声明
本文为[Qiang Ying]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/164/202206130537175691.html