如何在openGL中扭曲纹理

如何在openGL中扭曲纹理

本文介绍了如何在openGL中扭曲纹理? (是否更正?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想让OpenGL程序可以显示图像并扭曲显示的图像.

I wanna make the OpenGL program can present images and warp the images presented.

尽管我使用OpenGL实现了图像渲染,但我不知道如何扭曲图像.

Although I achieved image rendering using OpenGL, I don't know how to warp an image.

我想要的一个可变形示例是(参考):

An warpable example I want is (Reference):

但是我得到的照片是:

据我所知,此问题与透视校正映射有关.

As I know, this problem is related to perspective correction mapping.

但是我对此不太了解.

But I don't know about that well.

这是我的源代码.

void imageRender(Shader initShader, Shader imgShader, char *path){

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);

float positions = { 0.5f, 1.0f, 0.0f,
                    1.0f, -1.0f, 0.0f,
                    -1.0f, -1.0f, 0.0f,
                    -1.0f, 1.0f, 0.0f };

float vertices[] = {
    // positions                                 // colors           // texture coords
    position[0], position[1], position[2],   1.0f, 0.0f, 0.0f,   1.0f, 1.0f, // top right
    position[3], position[4], position[5],   0.0f, 1.0f, 0.0f,   1.0f, 0.0f, // bottom right
    position[6], position[7], position[8],   0.0f, 0.0f, 1.0f,   0.0f, 0.0f, // bottom left
    position[9], position[10],position[11],  1.0f, 1.0f, 0.0f,   0.0f, 1.0f  // top left
};
unsigned int indices[] = {
    0, 1, 3,
    1, 2, 3
};

unsigned int VAO, VBO, EBO;

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

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(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);

// color attribute
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(2);

//texture attribute
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(3);


FREE_IMAGE_FORMAT format = FreeImage_GetFileType(path, 0);
if (format == -1){
    cerr << BOLDRED << "[ERROR] IMAGE_NOT_FOUND" << RESET << endl;
    exit(1);
}

if (format == FIF_UNKNOWN){
    cerr << BOLDRED << "[ERROR] UNKNOWN_IMAGE_FORMAT" << RESET << endl;
    format = FreeImage_GetFIFFromFilename(path);
    if (!FreeImage_FIFSupportsReading(format)){
        cerr << BOLDRED << "[ERROR] IMAGE_FORMAT_NOT_READABLE" << RESET << endl;
        exit(1);
    }
}

FIBITMAP *bitmap = FreeImage_Load(format, path);
FIBITMAP *bitmap32;

int bitsPerPixel = FreeImage_GetBPP(bitmap);
bitmap32 = FreeImage_ConvertTo32Bits(bitmap);
int imageWidth = FreeImage_GetWidth(bitmap32);
int imageHeight = FreeImage_GetHeight(bitmap32);

GLubyte *textureData = FreeImage_GetBits(bitmap32);

GLuint texture1;
glGenTextures(1, &texture1);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageWidth, imageHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, textureData);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);   // set texture wrapping to GL_REPEAT (default wrapping method)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

initShader.use();
glBindVertexArray(VAO);

int initalTime = time(NULL);

while(1){

    glBindVertexArray(VAO);

    int timecal = time(NULL);
    //glDrawElements(GL_TRIANGLE_STRIP, 6, GL_UNSIGNED_INT, 0);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    glfwSwapBuffers(window);
    glfwPollEvents();
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    if ((timecal - initalTime) > imageTime) // imageTime value is 10
        break;
}

glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

glDeleteTextures(1, &texture1);// image
glDisable(GL_TEXTURE_2D);//image

FreeImage_Unload(bitmap32);
FreeImage_Unload(bitmap);

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

}

着色器代码就是这样

//shader.vs
#version 330 core
layout(location = 1) in vec3 position;
layout(location = 2) in vec3 color;
layout(location = 3) in vec2 texcoord;

out vec3 Color;
out vec2 Texcoord;

void main()
{
    gl_Position = vec4(position, 1.0);
    Texcoord = texcoord;
}

//shader.fs
#version 330 core
in vec3 Color;
in vec2 Texcoord;

out vec4 outColor;
uniform sampler2D texture5;

void main()
{
    outColor = texture2D(texture5, Texcoord);
}

如何变形纹理?

然后使用位置值使纹理图像变形是否正确?

And then Is it correct to use position value to warp texture image?

推荐答案

此问题与透视投影无关.您绘制了一个具有4个与视图的XY平面平行的顶点的多边形,但是该多边形不是四边形!更改第一个顶点的x坐标(0.5f-> 1.0f).透视投影适用于同质坐标.

The issue has nothing to do with perspective projection. You draw a polygon with 4 vertices parallel to the XY plane of the view, but the polygon is not a quad! Change the x coordinate of the 1st vertex (0.5f -> 1.0f). Perspective projection works with Homogeneous coordinates.

通常,透视投影是通过透视投影矩阵实现的.当然,您可以定义齐次顶点来检查行为:

In generalperspective projection is achieved by a Perspective projection matrix. Of course you can define homogeneous vertices to inspect the behavior:

定义具有相同顶点(四个分量)的属性元组:

Define an attribute tuple with homogenous vertices (4 components):

float vertices[] = {
    // positions                // colors           // texture coords
    1.0f,  1.0f,  0.5f, 2.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f, // top right
    1.0f, -1.0f, -0.5f, 1.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f, // bottom right
   -1.0f, -1.0f, -0.5f, 1.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f, // bottom left
   -1.0f,  1.0f,  0.5f, 2.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f  // top left
};

调整顶点规格和顶点着色器:

Adapt the vertex specification and the vertex shader:

// position attribute
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);

// color attribute
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (void*)(4 * sizeof(float)));
glEnableVertexAttribArray(2);

//texture attribute
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (void*)(7 * sizeof(float)));
glEnableVertexAttribArray(3);
#version 330 core
layout(location = 1) in vec4 position;
layout(location = 2) in vec3 color;
layout(location = 3) in vec2 texcoord;

out vec3 Color;
out vec2 Texcoord;

void main()
{
    gl_Position = position;
    Texcoord = texcoord;
}

要达到这种效果的另一个选择是,将一个Z分量添加到几何图形.例如:

Another option to achieve the effect is, to a an Z component to the geometry. e.g:

float positions = { 1.0f,  1.0f,  0.5f,
                    1.0f, -1.0f,  0.0f,
                   -1.0f, -1.0f, -0.5f,
                   -1.0f,  1.0f,  0.0f };

并根据顶点着色器中的z计算w分量(例如w = z + 2.5:

and to compute the w component dependent on z in the vertex shader (e.g. w = z + 2.5:

#version 330 core
layout(location = 1) in vec3 position;
layout(location = 2) in vec3 color;
layout(location = 3) in vec2 texcoord;

out vec3 Color;
out vec2 Texcoord;

void main()
{
    gl_Position = vec4(position, position.z + 2.5);
    Texcoord = texcoord;
}

这篇关于如何在openGL中扭曲纹理? (是否更正?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 13:10