Opengl 纹理映射和图像分辨率

Posted

技术标签:

【中文标题】Opengl 纹理映射和图像分辨率【英文标题】:Opengl texture mapping and image resoution 【发布时间】:2011-05-23 09:08:45 【问题描述】:

我正在使用 opengl 和纹理映射。 问题是,当应用的纹理为 512×32 像素时,一切正常,但当它为 128×128 时,纹理应用不正确。

纹理没有正确重复,它被应用到对象的开头,而他的其余部分没有任何纹理。

代码中:length参数约为100。

LoadTexture:读取.bmp文件并返回纹理索引的函数。

这是我正在使用的代码。

int LoadTexture(char *filename,int alpha) 

    using namespace std;
    int i, j=0; //Index variables
    static int num_texture;
    ifstream l_file(filename);
    unsigned char *l_texture; //The pointer to the memory zone in which we will load the texture

    // windows.h gives us these types to work with the Bitmap files
    BITMAPFILEHEADER fileheader; 
    BITMAPINFOHEADER infoheader;
    RGBTRIPLE rgb;

    num_texture++; // The counter of the current texture is increased

    if(!l_file) return (-1); // Open the file for reading

    l_file.read(reinterpret_cast<char *>(&fileheader), sizeof(fileheader)); // Read the fileheader

    //fseek(l_file, sizeof(fileheader), SEEK_SET); // Jump the fileheader
    l_file.read(reinterpret_cast<char *>(&infoheader), sizeof(infoheader)); // and read the infoheader

    // Now we need to allocate the memory for our image (width * height * color deep)
    l_texture = new byte [infoheader.biWidth * infoheader.biHeight * 4];
    // And fill it with zeros
    memset(l_texture, 0, infoheader.biWidth * infoheader.biHeight * 4);

    // At this point we can read every pixel of the image
    for (i=0; i < infoheader.biWidth*infoheader.biHeight; i++)
                
          // We load an RGB value from the file
          l_file.read(reinterpret_cast<char *>(&rgb), sizeof(rgb)); 

          // And store it
          l_texture[j+0] = rgb.rgbtRed; // Red component
          l_texture[j+1] = rgb.rgbtGreen; // Green component
          l_texture[j+2] = rgb.rgbtBlue; // Blue component
          l_texture[j+3] = alpha; // Alpha value
          j += 4; // Go to the next position
     

     l_file.close(); // Closes the file stream

     glBindTexture(GL_TEXTURE_2D, num_texture); // Bind the ID texture specified by the 2nd parameter

     // The next commands sets the texture parameters
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // If the u,v coordinates overflow the range 0,1 the image is repeated
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // The magnification function ("linear" produces better results)
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); //The minifying function

     // Finally we define the 2d texture
     glTexImage2D(GL_TEXTURE_2D, 0, 4, infoheader.biWidth, infoheader.biHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, l_texture);

     // And create 2d mipmaps for the minifying function
     gluBuild2DMipmaps(GL_TEXTURE_2D, 4, infoheader.biWidth, infoheader.biHeight, GL_RGBA, GL_UNSIGNED_BYTE, l_texture);

     delete [] l_texture; // Free the memory we used to load the texture

     return num_texture; // Returns the current texture OpenGL ID

这是我如何绘制坐标

void drawStreetStraight(Vector2d & point1,Vector2d & point2,Vector2d & point3,Vector2d & point4,double length)

    glEnable(GL_TEXTURE_2D);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECR); 
    glBindTexture(GL_TEXTURE_2D,streetTexture);
    glBegin(GL_QUADS);
    glTexCoord2f(0,0);
    glVertex3d(point1.x,0,point1.y);
    glTexCoord2f(1,0);
    glVertex3d(point2.x,0,point2.y);
    glTexCoord2f(1,length/2.0);
    glVertex3d(point3.x,0,point3.y);
    glTexCoord2f(0,length/2.0);
    glVertex3d(point4.x,0,point4.y);
    glEnd();
    glDisable(GL_TEXTURE_2D);

【问题讨论】:

纹理坐标的范围是0到1,不能加上length/2。为什么你在 glVertex3d 中给 z 的 y 坐标值? 第一个问题:为重复添加长度/2 即:我想重复纹理所以我这样做(长度/2)。超过 1 你会得到重复效果或钳位(根据你的代码)。第二个问题:我的对象(道路)位于 Y=0 的 XZ 坐标上,并且配置了 2 坐标点(x,y)。 为什么 glTexEnvf 调用中有 GL_DECR? 我试过 GL_REPLACE 但什么也没发生。 您可以尝试不使用 mipmapping 吗?如果能看到截图就好了。 【参考方案1】:

我不确定这是否可以解决您的示例,但您似乎没有在任何地方使用 glGenTextures。

这是有原因的吗?

我这样准备纹理:

    glGenTextures( 1, &texPlane);
glBindTexture( GL_TEXTURE_2D, texPlane );
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);  
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, texPlanes);

【讨论】:

我认为你可能是对的。我正在阅读 glBindTexture 旁边的 cmets,所以我匆忙推测他正在提供纹理名称作为 LoadTexture 函数的第二个参数。完全错过了他在函数中编写的代码。

以上是关于Opengl 纹理映射和图像分辨率的主要内容,如果未能解决你的问题,请参考以下文章

用于 OpenGL 纹理映射的 Java 图像作为 ByteBuffer

Android OpenGL ES 纹理映射/绘图问题 - 倾斜图像

opengl纹理映射总结

初识OpenGL (-)纹理过滤(Texture Filtering)

初识OpenGL (-)纹理过滤(Texture Filtering)

初识OpenGL (-)纹理过滤(Texture Filtering)