openGL learning note 22: MipMap multi level texture

Posted by DF7 on Mon, 20 Apr 2020 16:09:25 +0200

MipMap multi level texture:

    texture is not only a picture data, but also a series of picture data. Because the image zooms in and zooms out, the texture needs to be interpolated. This process takes a lot of time. In order to avoid this time-consuming calculation and improve the performance, the video card adopts a picture multi-level texture mode. According to the distance from the camera to the texture, different levels of texture are used, such as the camera from the texture The texture is relatively close, the larger texture is selected, the camera is far away from the texture, and the smaller texture is selected. This is the multi-level texture.

The code is as follows:

Create a multi-level texture

static unsigned createTexture(int w, int h, const void* data) {
	unsigned    texId;
	glGenTextures(1, &texId);
	glBindTexture(GL_TEXTURE_2D, texId);

	// ---Two kinds of amplification and filtering 
	//#Define GL "nearest 0x2600 closest point sampling
	//#Define GL "linear 0x2601 linear sampling

	// ---6 kinds of reduction filtering
	//#Define GL? Nearest 0x2600 use nearest neighbor filter on mip base
	//#Define GL "linear 0x2601 use linear filtering on mip base
	//#Define GL? Nearest? Mipmap? Nearest 0x2700 select the nearest mip layer and use the nearest filter
	//#Define GL? Linear? Mipmap? Nearest 0x2701 use linear interpolation and nearest neighbor filtering between mip layers
	//#Define GL? Nearest? Mipmap? Line 0x2702 select the closest mip layer and use linear filtering
	//#Define GL? Linear? Mipmap? Linear 0x2703 uses linear interpolation and linear filtering between mip layers, also known as trilinear mipmap

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, data); //Create a mipmap texture that produces twice as many textures as the gltex image2d function because there are multiple levels of textures
	//In essence, the gluBuild2DMipmaps function is a for loop to call glTexImage2D to generate different levels of textures
	//for ()
	//{
	//	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
	//}

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); //Set mipMap minimum level
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 4); //Set the maximum level of mipMap only to level 4

	return  texId;
}

Paint multi-level texture

// Draw
static void render(GLFWwindow * window) {
	glClearColor(0, 0, 0, 1);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	//Specify texture coordinates corresponding to data vertex coordinates
	Vertex cubeVertices[] =
	{
		{ -1.0f, -1.0f, 1.0f, 0, 0 },
		{ 1.0f, -1.0f, 1.0f, 1, 0 },
		{ 1.0f, 1.0f, 1.0f, 1, 1 },
		{ -1.0f, 1.0f, 1.0f, 0, 1 },

		{ -1.0f, -1.0f, -1.0f, 0, 0 },
		{ -1.0f, 1.0f, -1.0f, 1, 0 },
		{ 1.0f, 1.0f, -1.0f, 1, 1 },
		{ 1.0f, -1.0f, -1.0f, 0, 1 },

		{ -1.0f, 1.0f, -1.0f, 0, 0 },
		{ -1.0f, 1.0f, 1.0f, 1, 0 },
		{ 1.0f, 1.0f, 1.0f, 1, 1 },
		{ 1.0f, 1.0f, -1.0f, 0, 1 },

		{ -1.0f, -1.0f, -1.0f, 0, 0 },
		{ 1.0f, -1.0f, -1.0f, 1, 0 },
		{ 1.0f, -1.0f, 1.0f, 1, 1 },
		{ -1.0f, -1.0f, 1.0f, 0, 1 },

		{ 1.0f, -1.0f, -1.0f, 0, 0 },
		{ 1.0f, 1.0f, -1.0f, 1, 0 },
		{ 1.0f, 1.0f, 1.0f, 1, 1 },
		{ 1.0f, -1.0f, 1.0f, 0, 1 },

		{ -1.0f, -1.0f, -1.0f, 0, 0 },
		{ -1.0f, -1.0f, 1.0f, 1, 0 },
		{ -1.0f, 1.0f, 1.0f, 1, 1 },
		{ -1.0f, 1.0f, -1.0f, 0, 1 },
	};

	glMatrixMode(GL_MODELVIEW);

#if 0
	glEnable(GL_DEPTH_TEST);
	glInterleavedArrays( GL_T2F_V3F, sizeof(Vertex), cubeVertices );
#else
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_TEXTURE_2D);

	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	glVertexPointer(3, GL_FLOAT, sizeof(Vertex), &cubeVertices[0].x);
	glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &cubeVertices[0].u);
#endif
	//Draw the first cube
	// Qingcheng unit matrix
	glLoadIdentity();
	// Generate a matrix
	glTranslatef(-2, 0, -13);

	for(int i = 0; i < 6; ++i) {
		glBindTexture(GL_TEXTURE_2D, _texture[i%2]);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);//mipmap linear sampling for texture 
		glDrawArrays(GL_QUADS, i * 4, 4);
	}

	//Draw the second cube
	// Qingcheng unit matrix
	glLoadIdentity();
	// Generate a matrix
	glTranslatef(2, 0, -13);

	for(int i = 0; i < 6; ++i) {
		glBindTexture(GL_TEXTURE_2D, _texture[i % 2]);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); //Texture sampling with mipmap nearest point 
		glDrawArrays(GL_QUADS, i * 4, 4);
	}

	glfwSwapBuffers(window);
	glfwPollEvents();
}

Operation result: