Как обрезать текстуру в OpenGL? - PullRequest
0 голосов
/ 06 апреля 2020

Мне нужно обрезать изображение. Но в opencv это создаст ошибку из-за целочисленной области. Поэтому я хочу обрезать каждую единицу в плавающей области, чтобы уменьшить ошибку смещения. Может быть, openGL поможет мне, но я не очень хорош в этом.

Изображение точно так же (но не это):

The image just like this

Я хочу каждую черно-белую единицу, затем сохраняю их в cv :: Mat.

Я думаю, может быть, шейдер или l oop или что-то еще можно повторить, чтобы обрезать все блоки, а затем сохранить их.

Теперь я могу получить одну единицу. Вот так:

glfwInit();//initalization
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

GLFWwindow* window = glfwCreateWindow(100, 100, "LearnOpenGL", nullptr, nullptr);
if (window == nullptr)
{
    cout << "Failed to create GLFW window" << endl;
    glfwTerminate();
    return false;
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
    std::cout << "Failed to initialize GLAD" << std::endl;
    return false;
}

Shader ourShader("vertex.vs.glsl", "fragment.fs.glsl");

float unitWidth = moduleLength / (float)tex.cols;
float startP_x = 100.0f / (float)tex.cols + unitWidth * 2;
float startP_y = 104.0f / (float)tex.rows + unitWidth * 2;
float vertices[] = {
    // positions        // texture coords (note that we changed them to 'zoom in' on our texture image)
     0.5f,  0.5f, 0.0f,     startP_x + unitWidth,   startP_y, // top right
     0.5f, -0.5f, 0.0f,     startP_x + unitWidth,   startP_y + unitWidth, // bottom right
    -0.5f, -0.5f, 0.0f,     startP_x,               startP_y + unitWidth, // bottom left
    -0.5f,  0.5f, 0.0f,     startP_x,               startP_y  // top left 
};

unsigned int indices[] = {
   0, 1, 3, // first triangle
   1, 2, 3  // second triangle
};

unsigned int VBO, VAO, EBO;

glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);

glBindVertexArray(VAO);

glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

// position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// texture coord attribute
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);


// texture 
// ---------
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
//// set the texture wrapping parameters
// set the texture wrapping parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);  
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
// set texture filtering parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

GLubyte* pixels;
int width = tex.cols;
int height = tex.rows;

int pixellength = width * height*tex.channels();
pixels = new GLubyte[pixellength];
memcpy(pixels, tex.data, pixellength * sizeof(unsigned char));
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, pixels);
free(pixels);

while (!glfwWindowShouldClose(window))
{
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    // bind Texture
    glBindTexture(GL_TEXTURE_2D, texture);

    // draw our first triangle
    ourShader.use();

    // create transformations
    glm::mat4 model = glm::mat4(1.0f); // make sure to initialize matrix to identity matrix first
    glm::mat4 view = glm::mat4(1.0f);
    glm::mat4 projection = glm::mat4(1.0f);

    model = glm::rotate(model, glm::radians(0.0f), glm::vec3(1.0f, 0.0f, 0.0f));
    view = glm::translate(view, glm::vec3(0.0f, 0.0f, -1.1f));
    projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);

    // retrieve the matrix uniform locations
    unsigned int modelLoc = glGetUniformLocation(ourShader.ID, "model");
    unsigned int viewLoc = glGetUniformLocation(ourShader.ID, "view");
    unsigned int transformLoc = glGetUniformLocation(ourShader.ID, "projection");

    glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
    glUniformMatrix4fv(viewLoc, 1, GL_FALSE, &view[0][0]);
    glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(projection));

    glBindVertexArray(VAO); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); // set the count to 6 since we're drawing 6 vertices now (2 triangles); not 3!

    glfwPollEvents();
    glfwSwapBuffers(window);
}

glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);

glfwTerminate();
return true;

vetex шейдер:

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

out vec2 TexCoord;

void main()
{
    gl_Position =  projection * view * model *vec4(aPos, 1.0);
    TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}

фрагментный шейдер:

#version 330 core
out vec4 FragColor;

in vec2 TexCoord;

uniform sampler2D texture1;


void main()
{
    FragColor = texture(texture1, TexCoord);
}
...