opengl2怎么将梯形的纹理映射在矩形上面不变形

opengl梯形贴图到矩形里面,希望等比拉申,而不是扭曲变形

img

你用的什么语言啊?进行拉伸

qt里面用opengl是吧

要实现OpenGL中梯形贴图到矩形内的等比拉伸,而不是扭曲变形,您可以使用纹理映射功能来实现。以下是一般的步骤:

  1. 创建一个矩形的顶点坐标数组和纹理坐标数组。确保矩形的纹理坐标是按照原始图像的梯形形状来定义的,而不是矩形的形状。
  2. 加载纹理图像并绑定到OpenGL纹理对象上。
  3. 在顶点着色器中,定义一个变换矩阵来对纹理坐标进行变换。根据梯形与矩形之间的变换关系,通过变换矩阵来实现等比拉伸。
  4. 在片段着色器中,使用纹理坐标对纹理进行采样,并将采样结果输出作为最终的片段颜色。

通过以上步骤,您可以将梯形贴图映射到矩形内部,并实现等比拉伸的效果。

需要注意的是,具体的实现代码会涉及到OpenGL的相关函数调用,包括顶点数组对象(VAO)、顶点缓冲对象(VBO)、着色器程序的创建和使用等。此外,您还需要了解矩阵变换的相关知识,以便正确定义变换矩阵。

能看下你的贴图的原始图片吗?如果拉升的变形比较大,原始图片被撑满势必会有图形的变形。如果图形显示无误,只是被拉升后出现模糊,可以改变纹理模式进行调整。

         // 线形滤波
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);           

        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 

        // 接近滤波
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);          

        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);

如果图形显示有问题,还需要修改纹理坐标。

贴图坐标

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 你可以看下这个问题的回答https://ask.csdn.net/questions/648847
  • 这篇博客也不错, 你可以看下OpenGL学习笔记(一):环境搭建、三维空间坐标系理解以及OpenGL的基本使用
  • 除此之外, 这篇博客: OPenGL 基本知识(根据自己理解整理)中的 2. OpenGL 管线 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    简单来说管线就是一系列过程,三维模型转换成二维图形输出屏幕的过程。这个过程分为多个步骤,每个步骤的输出就是下一个步骤的输入。这些步骤有些实在CPU中运行,有些实在GPU中运行。具体如下:
    在这里插入图片描述
    其中着色器是运行在GPU的小程序,大家不要被它的名字所迷惑,它并不是单单用给像素点上颜色的,它还计算像素点的位置、纹理等信息。

    因为GPU相对CPU来说,有更多的计算单元(成百上千计算核心)。CPU最多有两位数的计算单元。所以GPU可以同时使用大量的计算核心利用着色器程序计算每个像素点的位置、颜色、透明度等。因为每个像素单元的显示是独立的,所以每个GPU计算单元互不干扰。

    例如:一张1080*900的图片,如果使用CPU计算的话,可能需要计算90多万次,但是使用GPU并行计算的话,一次性的就可以计算出来。所以效率就显而易见区分出来了。

    顶点着色器和图元着色器在程序中可以进行编程的,把编程好的着色器放到GPU中运行。

    顶点着色器:是GPU渲染管线的第一步,它的数据来源于CPU。CPU把定点坐标、颜色、纹理等数据送入GPU。GPU会使用定点着色器把每个顶点都运行一次。计算每个顶点的坐标、光照、颜色等。顶点着色器输入是坐标顶点输出是经过变换后的顶点。

    图元装配:将顶点着色器输出的图元,装配成指定的图元(点、线、三角形),这些图元是构成模型的基本要素。

    几何着色器:几何着色器一个可编程的可选阶段。几何着色器的输入是完整的图元,输出是一个或者多个其他的图元或者不输出任何图形。也就是将输入的点或者线扩展成多边形。能够将(这一组)顶点变换为完全不同的图元,并且还能生成比原来更多的顶点。

    光栅化:是把几何图元转换成像素的过程,通俗来讲就是把一个三维图形拍平后的效果,然后在屏幕上显示。确定图元所围成的像素的位置以及图元边界像素的位置。

    片段着色器:计算图元中每个像素点的颜色、光照、阴影等(主要是和颜色相关)。每个像素点有4个元素组成(RGBA:红、绿、兰、透明度),每个分量取值范围都是0.0-1.0。片段着色器单独处理每一个片段,并不会影响到周围片元的计算,每个片元的计算都是独立的。正是因为独立性才保证了GPU可以高并发的工作。

  • 您还可以看一下 杨振老师的OpenGL萌谷手册视频教程课程中的 原理?课时数?课时长度?小节, 巩固相关知识点

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

 1 void MyGLWidget::paintGL()                              //从这里开始进行所以的绘制
 2 {
 3     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除屏幕和深度缓存
 4     glLoadIdentity();                                   //重置模型观察矩阵
 5     glTranslatef(0.0f, 0.0f, -5.0f);                    //移入屏幕5.0单位
 6     glRotatef(m_xRot, 1.0f, 0.0f, 0.0f);                //绕x轴旋转
 7     glRotatef(m_yRot, 0.0f, 1.0f, 0.0f);                //绕y轴旋转
 8     glRotatef(m_zRot, 0.0f, 0.0f, 1.0f);                //绕z轴旋转
 9  
10     glBindTexture(GL_TEXTURE_2D, m_Texture);            //选择纹理
11     glBegin(GL_QUADS);                                  //开始绘制立方体
12         glTexCoord2f(1.0f, 1.0f);
13         glVertex3f(1.0f, 1.0f, -1.0f);                  //右上(顶面)
14         glTexCoord2f(0.0f, 1.0f);
15         glVertex3f(-1.0f, 1.0f, -1.0f);                 //左上(顶面)
16         glTexCoord2f(0.0f, 0.0f);
17         glVertex3f(-1.0f, 1.0f, 1.0f);                  //左下(顶面)
18         glTexCoord2f(1.0f, 0.0f);
19         glVertex3f(1.0f, 1.0f, 1.0f);                   //右下(顶面)
20  
21         glTexCoord2f(0.0f, 0.0f);
22         glVertex3f(1.0f, -1.0f, 1.0f);                  //右上(底面)
23         glTexCoord2f(1.0f, 0.0f);
24         glVertex3f(-1.0f, -1.0f, 1.0f);                 //左上(底面)
25         glTexCoord2f(1.0f, 1.0f);
26         glVertex3f(-1.0f, -1.0f, -1.0f);                //左下(底面)
27         glTexCoord2f(0.0f, 1.0f);
28         glVertex3f(1.0f, -1.0f, -1.0f);                 //右下(底面)
29  
30         glTexCoord2f(1.0f, 1.0f);
31         glVertex3f(1.0f, 1.0f, 1.0f);                   //右上(前面)
32         glTexCoord2f(0.0f, 1.0f);
33         glVertex3f(-1.0f, 1.0f, 1.0f);                  //左上(前面)
34         glTexCoord2f(0.0f, 0.0f);
35         glVertex3f(-1.0f, -1.0f, 1.0f);                 //左下(前面)
36         glTexCoord2f(1.0f, 0.0f);
37         glVertex3f(1.0f, -1.0f, 1.0f);                  //右下(前面)
38  
39         glTexCoord2f(0.0f, 0.0f);
40         glVertex3f(1.0f, -1.0f, -1.0f);                 //右上(后面)
41         glTexCoord2f(1.0f, 0.0f);
42         glVertex3f(-1.0f, -1.0f, -1.0f);                //左上(后面)
43         glTexCoord2f(1.0f, 1.0f);
44         glVertex3f(-1.0f, 1.0f, -1.0f);                 //左下(后面)
45         glTexCoord2f(0.0f, 1.0f);
46         glVertex3f(1.0f, 1.0f, -1.0f);                  //右下(后面)
47  
48         glTexCoord2f(1.0f, 1.0f);
49         glVertex3f(-1.0f, 1.0f, 1.0f);                  //右上(左面)
50         glTexCoord2f(0.0f, 1.0f);
51         glVertex3f(-1.0f, 1.0f, -1.0f);                 //左上(左面)
52         glTexCoord2f(0.0f, 0.0f);
53         glVertex3f(-1.0f, -1.0f, -1.0f);                //左下(左面)
54         glTexCoord2f(1.0f, 0.0f);
55         glVertex3f(-1.0f, -1.0f, 1.0f);                 //右下(左面)
56  
57         glTexCoord2f(1.0f, 1.0f);
58         glVertex3f(1.0f, 1.0f, -1.0f);                  //右上(右面)
59         glTexCoord2f(0.0f, 1.0f);
60         glVertex3f(1.0f, 1.0f, 1.0f);                   //左上(右面)
61         glTexCoord2f(0.0f, 0.0f);
62         glVertex3f(1.0f, -1.0f, 1.0f);                  //左下(右面)
63         glTexCoord2f(1.0f, 0.0f);
64         glVertex3f(1.0f, -1.0f, -1.0f);                 //右下(右面)
65     glEnd();                                            //立方体绘制结束
66  
67     m_xRot += 0.6f;                                     //x轴旋转
68     m_yRot += 0.4f;                                     //y轴旋转
69     m_zRot += 0.8f;                                     //z轴旋转
70 }

纹理映射发生了变形的话,可能是纹理坐标或者映射坐标设置的不正确,导致纹理坐标超出纹理边界,从而发生了变形。解决方法就是检查下纹理坐标的映射方法或方式是否使用正确,其次可以考虑将梯形分割成矩形和直角三角形在做投影和映射。

可以通过使用纹理坐标的方式实现

先对梯形进行透视校正,将其转换为矩形形状,然后再进行纹理贴图

要在OpenGL中将梯形纹理等比例拉伸到矩形内而不产生扭曲变形,您可以使用纹理映射技术。以下是您可以遵循的步骤:

  1. 将纹理映射到一个与梯形具有相同纵横比的矩形上。
  2. 对矩形应用变换,将其转换为梯形形状。
  3. 使用纹理坐标将纹理映射到变换后的梯形上。
    要完成第2步,您可以使用仿射变换或透视变换。例如,您可以使用gluPerspective函数将矩形转换为梯形。在转换之前,您需要计算梯形的四个顶点的坐标。在转换之后,您可以使用glTexCoord2f函数设置每个顶点的纹理坐标,并使用glVertex3f函数指定每个顶点的位置。

```bash
// Define the vertices of the trapezoid and rectangle
GLfloat trapezoidVertices[] = {
    -0.5f, -0.5f, 0.0f,
    0.5f, -0.5f, 0.0f,
    -0.3f, 0.5f, 0.0f,
    0.3f, 0.5f, 0.0f
};
 GLfloat rectangleVertices[] = {
    -0.5f, -0.5f, 0.0f,
    0.5f, -0.5f, 0.0f,
    -0.5f, 0.5f, 0.0f,
    0.5f, 0.5f, 0.0f
};
 // Define the texture coordinates for the trapezoid
GLfloat trapezoidTexCoords[] = {
    0.0f, 0.0f,
    1.0f, 0.0f,
    0.3f, 1.0f,
    0.7f, 1.0f
};
 // Define the texture coordinates for the rectangle
GLfloat rectangleTexCoords[] = {
    0.0f, 0.0f,
    1.0f, 0.0f,
    0.0f, 1.0f,
    1.0f, 1.0f
};
 // Load the texture image
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
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);
int width, height;
unsigned char* image = SOIL_load_image("texture.png", &width, &height, 0, SOIL_LOAD_RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
SOIL_free_image_data(image);
 // Set up the projection and view matrices
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, 1.0f, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0f, 0.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
 // Enable texturing and set the active texture unit
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
 // Draw the trapezoid
glBegin(GL_TRIANGLE_STRIP);
for (int i = 0; i < 4; i++) {
    glTexCoord2f(trapezoidTexCoords[i*2], trapezoidTexCoords[i*2+1]);
    glVertex3f(trapezoidVertices[i*3], trapezoidVertices[i*3+1], trapezoidVertices[i*3+2]);
}
glEnd();
 // Draw the rectangle
glBegin(GL_TRIANGLE_STRIP);
for (int i = 0; i < 4; i++) {
    glTexCoord2f(rectangleTexCoords[i*2], rectangleTexCoords[i*2+1]);
    glVertex3f(rectangleVertices[i*3], rectangleVertices[i*3+1], rectangleVertices[i*3+2]);
}
glEnd();
 // Disable texturing
glDisable(GL_TEXTURE_2D);


  这个代码示例假设已经有了一个纹理图像,并将其加载到OpenGL中。它使用gluPerspective函数将矩形转换为梯形,并使用glTexCoord2f函数将纹理坐标映射到变换后的梯形上。