OpenGL since 1.0 - textures and surface details

To make the drawn objects more realistic, in addition to adding lighting, another important factor is the texture. , let's start with a simple example.
write picture description here

#include <Gl/glut.h>
void init()
{
    glClearColor(1.0, 1.0, 1.0, 0.0);
    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(0.0, 200.0, 0.0, 150.0);
}
void lineSegment()
{
    glClear(GL_COLOR_BUFFER_BIT);

    GLint k;
    GLubyte texLine[16];
    for (k = 0; k <= 2;k+=2)
    {
        texLine[4 * k] = 0;
        texLine[4 * k+1] = 255;
        texLine[4 * k+2] = 0;
        texLine[4 * k+3] = 255;
    }
    for (k = 1; k <= 3; k += 2)
    {
        texLine[4 * k] = 255;
        texLine[4 * k + 1] = 0;
        texLine[4 * k + 2] = 0;
        texLine[4 * k + 3] = 255;
    }
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);//指定纹理映射方法
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 4,0, GL_RGBA, GL_UNSIGNED_BYTE, texLine);//应用纹理数组
    glEnable(GL_TEXTURE_1D);//激活纹理

    glBegin(GL_LINES);//开始绘制纹理线段
    glTexCoord1f(0.0);//纹理起点
    glVertex2i(180, 15);
    glTexCoord1f(1.0);//纹理终点
    glVertex2i(10, 145);
    glEnd();
    glDisable(GL_TEXTURE_1D);
    glFlush();
}
void main(int argc, char**argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowPosition(50, 100);
    glutInitWindowSize(400, 300);
    glutCreateWindow("An Example OpenGL Program");
    init();
    glutDisplayFunc(lineSegment);
    glutMainLoop();
}

We see a line segment that alternates red and green. The following is a detailed explanation of the texture function.

glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 4,0, GL_RGBA, GL_UNSIGNED_BYTE, texLine);//第一个参数指出正在为一个一维对象即一条线段定义一个纹理数组,第二个参数表示该数组不是某个大纹理数组的缩减,第五个参数表示不希望在纹理周围有边界,第三个参数表示该纹理图案的每一颜色用RGBA四个值指定,第四个参数表示该纹理图案中的颜色数量,在无纹理边界的情况下,该值必须是2的指数,在有纹理边界的情况下,该值必须的2的指数加2。最后一个参数表示纹理颜色,纹理数组的大小为4*颜色数量。
    glEnable(GL_TEXTURE_1D);//激活纹理

Since textures are often not perfectly aligned with scene objects, the following two functions specify the texture mapping method:

glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);//指定纹理放大方法,采用最邻近插值。最邻近插值容易导致走样效果,故也经常替换为GL_LINEAR,即线型插值
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);//指定纹缩小大方法,采用最邻近插值

After that, as long as the texture coordinates are assigned to the corresponding primitive coordinates, the mapping relationship between the texture and the scene can be established.

glTexCoord1f(0.0);//纹理坐标变化范围为0.0-1.0

We can similarly use the surface texture function

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth,texHeight,0, GL_RGBA, GL_UNSIGNED_BYTE, surfTexArray);//参数变化的就是这里指定了二维纹理的宽texWidth和高texHeight。
glEnable(GL_TEXTURE_2D);//激活纹理

Similarly, there is also the volume texture function, which transforms the parameters into a dimension accordingly, so we won't go into details.
When a texel is mapped to an object, its value can be blended with the current object color, or it can replace the object color. The following functions are used to select the texture mapping method:

glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,applicationMethod);

If the parameter applicationMethod is assigned GL_REPLACE, the texture color, brightness, light intensity or alpha value replaces the corresponding value of the object. If the parameter applicationMethod is assigned a value of GL_REPLACE, it results in "modulation" of the color value of the object, that is, modulating the current color value with the texture color. If the parameter applicationMethod is set to GL_DECAL, the operation uses the alpha value of RGBA as the transparency coefficient.
When the coordinates in texture space are outside the range of 0 to 1.0, the following commands can be used to complement the pattern described in texture space:

glTexParameterf(texSpace,texWrapCoord,GL_REPEAT);//仅使用纹理空间坐标值的小数部分补充图案

The first parameter of the function is GL_TEXTURE_1D or a higher-dimensional symbolic constant, and the second parameter can be GL_TEXTURE_WRAP_R or GL_TEXTURE_WRAP_S, etc.
Textures can come not only from texture arrays, but also from the framebuffer. We can use a block of RGBA pixel values ​​to build a 2D pattern for the current texture state:

glCopyTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,x0,y0,texWidth,texHeight,0);

Two 0s in the function parameter indicate that the pattern is not reduced and has no boundaries. The framebuffer position (x0, y0) with the lower left corner of the buffer as the coordinate origin gives the pixel color block of texWidth and texHeight.
Pixel blocks used as texture subpatterns can also be obtained with functions similar to:

glCopyTexSubImage2D(GL_TEXTURE_2D,0,xTexElement,yTexElement,x0,y0,texWidth,texHeight);

The difference between this function and the above function is that the texture pattern obtained in the frame buffer replaces the part (xTexElement, yTexElement) in the original texture pattern.
We can also use an array of texture coordinates

glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(nCoords,dataType,offset,texCoordArray);

nCoords is assigned a value of 1/2/3 or 4, specifying the size of the texture pattern. The default value of 4 means that the texture space is specified in homogeneous coordinates.
We can give a texture pattern a name and use that name to manipulate the texture pattern later.

glBindTexture(GL_TEXTURE_1D,3);//为该图案命名
glTexImage1D(GL_TEXTURE_1D,0,GL_RGBA,4,0,GL_RGBA,GL_UNSIGNED_BYTE,texLine);//使用纹理数组
glBindTexture(GL_TEXTURE_1D,3);//将该图案指定为当前纹理状态。

We can modify a part of the texture pattern, that is, create another pattern (called a subpattern) to replace the part in the original pattern, which is more efficient.

glTexSubImage2D(GL_TEXTURE_@D,0,xTexElement,yTexElement,GL_RGBA,texSubwidth,texSubHeight,0,dataFormat,datatype,subSurfTexArray);

The parameters xTexElement and yTexElement are used to find the part that needs to be replaced in the original pattern, and subSurfTexArray is an array of 4*xTexElement*yTexElement.
For the reduced object size, we can use OpenGL functions to create a series of texture reduction patterns, called mip maps, we can use the glTexImage function to change the reduction factor, or we can let OpenGL automatically generate reduced patterns

gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA,16,16,GL_RGBA,GL_UNSIGNED_BYTE,surfTexArray);//对该16*16的纹理图案生成8*8,4*4,2*2,1*1的图案
gluBuild2DMipmapLevels(GL_TEXTURE_2D,GL_RGBA,16,16,GL_RGBA,GL_UNSIGNED_BYTE,0,minLevel,maxLevel,surfTexArray);//对该16*16的纹理图案生成缩减级别从minLevel到maxLevel的图案

Assign values ​​to texture boundaries:

glTexParameterfv(GL_TEXTURE_@D,GL_TEXTURE_BORDER_COLOR,borderColor);

We can also assign values ​​to secondary objects:

gluQuadricTexture(quadsurfobj,GL_TRUE):

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325525934&siteId=291194637