• opengl 学习 之 05 lesson


    简介

    颜色和坐标一眼都是opengl 的属性,不过坐标是作为内建属性之一。
    加载纹理

    link

    http://www.opengl-tutorial.org/uncategorized/2017/06/07/website-update/

    UV

    When texturing a mesh, you need a way to tell to OpenGL which part of the image has to be used for each triangle. This is done with UV coordinates.

    UV坐标是用来对纹理进行适配的,以三角形的方式进行适配。

    使用Blender来构建uv坐标

    Linear filtering

    普通的BMP映射会产生锯齿。使用Linear filtering进行滤波操作。简单来说就是颜色插值

    With linear fifiltering, texture() also looks at the other texels around, and mixes the colours according to the distance to each center. This avoids the hard edges seen above.

    Anisotropic fifiltering

    如果你想要更好的效果,可以使用Anisotropic fifiltering(各向异性滤波)

    猜测:应该是选择一个矩形方向,然后按照一定的颜色比例进行调色。

    For instance, if the following texture is seen from the side, and a little bit rotated, anisotropic fifiltering will compute the colour contained in the blue rectangle by taking a fifixed number of samples (the “anisotropic level”) along its main direction.

    linear and anisotropic filtering都有一个问题, If the texture is seen from far away, mixing only 4 texels won’t be enough(纹理距离足够远的话,仅仅四个像素文进行调色是远远不够的)

    Mipmaps

    原理很简单就是,缩放一系列纹理,然后在一定距离选择一定的纹理,然后使用linear或者anisotropic filtering

    At initialisation time, you scale down your image by 2, successively, until you only have a 1x1 image (which effectively is the average of all the texels in the image)

    When you draw a mesh, you select which mipmap is the more appropriate to use given how big the texel should be.

    You sample this mipmap with either nearest, linear or anisotropic fifiltering

    For additional quality, you can also sample two mipmaps and blend the results

    use GLFW to load texture

    GLuint loadTGA_glfw(const char * imagepath){
     // Create one OpenGL texture
     GLuint textureID;
     glGenTextures(1, &textureID);
     // "Bind" the newly created texture : all future texture functions will modify this texture
     glBindTexture(GL_TEXTURE_2D, textureID);
     // Read the file, call glTexImage2D with the right parameters
     glfwLoadTexture2D(imagepath, 0);
     // Nice trilinear filtering.
     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_TEXTURE_MAG_FILTER, GL_LINEAR);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
     glGenerateMipmap(GL_TEXTURE_2D);
     // Return the ID of the texture we just created
     return textureID; 
    }
    

    为什么要使用.DDS格式的纹理

    如果直接用内存进行和GPU内存的交换会导致性能损失,如果使用DDS然后在传输的过程中进行解压,因为有专门的硬件实现硬解,所以会达到20%的性能提升。

    At this point, your image is compressed in a format that is directly compatible with the GPU. Whenever calling texture() in a shader, it will uncompress it on-the-flfly. This can seem slow, but since it takes a LOT less memory, less data needs to be transferred. But memory transfers are expensive; and texture decompression is free (there is dedicated hardware for that). Typically, using texture compression yields a 20% increase in performance. So you save on performance and memory, at the expense of reduced quality.

    code that load dds

    GLuint loadDDS(const char * imagepath){
     unsigned char header[124];
     FILE *fp;
     /* try to open the file */
     fp = fopen(imagepath, "rb");
     if (fp == NULL)
     return 0;
     /* verify the type of file */
     char filecode[4];
     fread(filecode, 1, 4, fp);
     if (strncmp(filecode, "DDS ", 4) != 0) {
         fclose(fp);
         return 0;
     }
     /* get the surface desc */
     fread(&header, 124, 1, fp);
     unsigned int height = *(unsigned int*)&(header[8 ]);
     unsigned int width = *(unsigned int*)&(header[12]);
     unsigned int linearSize = *(unsigned int*)&(header[16]);
     unsigned int mipMapCount = *(unsigned int*)&(header[24]);
     unsigned int fourCC = *(unsigned int*)&(header[80]);
     unsigned char * buffer;
     unsigned int bufsize;
     /* how big is it going to be including all mipmaps? */
     bufsize = mipMapCount > 1 ? linearSize * 2 : linearSize;
     buffer = (unsigned char*)malloc(bufsize * sizeof(unsigned char));
     fread(buffer, 1, bufsize, fp);
     /* close the file pointer */
     fclose(fp);
     unsigned int components = (fourCC == FOURCC_DXT1) ? 3 : 4;
     unsigned int format;
     switch(fourCC)
     {
         case FOURCC_DXT1:
         format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
         break;
         case FOURCC_DXT3:
         format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
         break;
         case FOURCC_DXT5:
         format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
         break;
         default:
         free(buffer);
         return 0;
     }
     // Create one OpenGL texture
     GLuint textureID;
     glGenTextures(1, &textureID);
     // "Bind" the newly created texture : all future texture functions will modify this texture
     glBindTexture(GL_TEXTURE_2D, textureID);
     unsigned int blockSize = (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16;
     unsigned int offset = 0;
     /* load the mipmaps */
     for (unsigned int level = 0; level < mipMapCount && (width || height); ++level)
     {
     unsigned int size = ((width+3)/4)*((height+3)/4)*blockSize;
     glCompressedTexImage2D(GL_TEXTURE_2D, level, format, width, height,
     0, size, buffer + offset);
     offset += size;
     width /= 2;
     height /= 2;
     }
     free(buffer);
     return textureID;
    }
    

    TIPS

    DXT压缩算法来自于DirectX,他与opengl的v坐标是相反的。需要使用( coord.u, 1.0-coord.v) ,进行UV坐标矫正。

    image

    DDS:感觉出现cube总出现了裂缝,不知道出了什么问题

    BMP

    code

    // Include standard headers
    #include <stdio.h>
    #include <stdlib.h>
    
    // Include GLEW
    #include <GL/glew.h>
    
    // Include GLFW
    #include <GLFW/glfw3.h>
    GLFWwindow* window;
    
    // Include GLM
    #include <glm/glm.hpp>
    #include <glm/gtc/matrix_transform.hpp>
    using namespace glm;
    
    #include <common/shader.hpp>
    #include <common/texture.hpp>
    
    int main( void )
    {
    	// Initialise GLFW
    	if( !glfwInit() )
    	{
    		fprintf( stderr, "Failed to initialize GLFW
    " );
    		return -1;
    	}
    
    	glfwWindowHint(GLFW_SAMPLES, 4);
    	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    	glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed
    	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    
    	// Open a window and create its OpenGL context
    	window = glfwCreateWindow( 1024, 768, "Tutorial 05 - Textured Cube", NULL, NULL);
    	if( window == NULL ){
    		fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.
    " );
    		glfwTerminate();
    		return -1;
    	}
    	glfwMakeContextCurrent(window);
    
    	// Initialize GLEW
    	glewExperimental = true; // Needed for core profile
    	if (glewInit() != GLEW_OK) {
    		fprintf(stderr, "Failed to initialize GLEW
    ");
    		return -1;
    	}
    
    	// Ensure we can capture the escape key being pressed below
    	glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
    
    	// Dark blue background
    	glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
    
    	// Enable depth test
    	glEnable(GL_DEPTH_TEST);
    	// Accept fragment if it closer to the camera than the former one
    	glDepthFunc(GL_LESS); 
    
    	GLuint VertexArrayID;
    	glGenVertexArrays(1, &VertexArrayID);
    	glBindVertexArray(VertexArrayID);
    
    	// Create and compile our GLSL program from the shaders
    	GLuint programID = LoadShaders( "TransformVertexShader.vertexshader", "TextureFragmentShader.fragmentshader" );
    
    	// Get a handle for our "MVP" uniform
    	GLuint MatrixID = glGetUniformLocation(programID, "MVP");
    
    	// Projection matrix : 45� Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units
    	glm::mat4 Projection = glm::perspective(glm::radians(45.0f), 4.0f / 3.0f, 0.1f, 100.0f);
    	// Camera matrix
    	glm::mat4 View       = glm::lookAt(
    								glm::vec3(4,3,3), // Camera is at (4,3,3), in World Space
    								glm::vec3(0,0,0), // and looks at the origin
    								glm::vec3(0,1,0)  // Head is up (set to 0,-1,0 to look upside-down)
    						   );
    	// Model matrix : an identity matrix (model will be at the origin)
    	glm::mat4 Model      = glm::mat4(1.0f);
    	// Our ModelViewProjection : multiplication of our 3 matrices
    	glm::mat4 MVP        = Projection * View * Model; // Remember, matrix multiplication is the other way around
    
    	// Load the texture using any two methods
    	GLuint Texture = loadBMP_custom("uvtemplate.bmp");
    	//GLuint Texture = loadDDS("uvtemplate.DDS");
    	
    	// Get a handle for our "myTextureSampler" uniform
    	GLuint TextureID  = glGetUniformLocation(programID, "myTextureSampler");
    
    	// Our vertices. Tree consecutive floats give a 3D vertex; Three consecutive vertices give a triangle.
    	// A cube has 6 faces with 2 triangles each, so this makes 6*2=12 triangles, and 12*3 vertices
    	static const GLfloat g_vertex_buffer_data[] = { 
    		-1.0f,-1.0f,-1.0f,
    		-1.0f,-1.0f, 1.0f,
    		-1.0f, 1.0f, 1.0f,
    		 1.0f, 1.0f,-1.0f,
    		-1.0f,-1.0f,-1.0f,
    		-1.0f, 1.0f,-1.0f,
    		 1.0f,-1.0f, 1.0f,
    		-1.0f,-1.0f,-1.0f,
    		 1.0f,-1.0f,-1.0f,
    		 1.0f, 1.0f,-1.0f,
    		 1.0f,-1.0f,-1.0f,
    		-1.0f,-1.0f,-1.0f,
    		-1.0f,-1.0f,-1.0f,
    		-1.0f, 1.0f, 1.0f,
    		-1.0f, 1.0f,-1.0f,
    		 1.0f,-1.0f, 1.0f,
    		-1.0f,-1.0f, 1.0f,
    		-1.0f,-1.0f,-1.0f,
    		-1.0f, 1.0f, 1.0f,
    		-1.0f,-1.0f, 1.0f,
    		 1.0f,-1.0f, 1.0f,
    		 1.0f, 1.0f, 1.0f,
    		 1.0f,-1.0f,-1.0f,
    		 1.0f, 1.0f,-1.0f,
    		 1.0f,-1.0f,-1.0f,
    		 1.0f, 1.0f, 1.0f,
    		 1.0f,-1.0f, 1.0f,
    		 1.0f, 1.0f, 1.0f,
    		 1.0f, 1.0f,-1.0f,
    		-1.0f, 1.0f,-1.0f,
    		 1.0f, 1.0f, 1.0f,
    		-1.0f, 1.0f,-1.0f,
    		-1.0f, 1.0f, 1.0f,
    		 1.0f, 1.0f, 1.0f,
    		-1.0f, 1.0f, 1.0f,
    		 1.0f,-1.0f, 1.0f
    	};
    
    	// Two UV coordinatesfor each vertex. They were created with Blender.
    	static const GLfloat g_uv_buffer_data[] = { 
    		0.000059f, 1.0f-0.000004f, 
    		0.000103f, 1.0f-0.336048f, 
    		0.335973f, 1.0f-0.335903f, 
    		1.000023f, 1.0f-0.000013f, 
    		0.667979f, 1.0f-0.335851f, 
    		0.999958f, 1.0f-0.336064f, 
    		0.667979f, 1.0f-0.335851f, 
    		0.336024f, 1.0f-0.671877f, 
    		0.667969f, 1.0f-0.671889f, 
    		1.000023f, 1.0f-0.000013f, 
    		0.668104f, 1.0f-0.000013f, 
    		0.667979f, 1.0f-0.335851f, 
    		0.000059f, 1.0f-0.000004f, 
    		0.335973f, 1.0f-0.335903f, 
    		0.336098f, 1.0f-0.000071f, 
    		0.667979f, 1.0f-0.335851f, 
    		0.335973f, 1.0f-0.335903f, 
    		0.336024f, 1.0f-0.671877f, 
    		1.000004f, 1.0f-0.671847f, 
    		0.999958f, 1.0f-0.336064f, 
    		0.667979f, 1.0f-0.335851f, 
    		0.668104f, 1.0f-0.000013f, 
    		0.335973f, 1.0f-0.335903f, 
    		0.667979f, 1.0f-0.335851f, 
    		0.335973f, 1.0f-0.335903f, 
    		0.668104f, 1.0f-0.000013f, 
    		0.336098f, 1.0f-0.000071f, 
    		0.000103f, 1.0f-0.336048f, 
    		0.000004f, 1.0f-0.671870f, 
    		0.336024f, 1.0f-0.671877f, 
    		0.000103f, 1.0f-0.336048f, 
    		0.336024f, 1.0f-0.671877f, 
    		0.335973f, 1.0f-0.335903f, 
    		0.667969f, 1.0f-0.671889f, 
    		1.000004f, 1.0f-0.671847f, 
    		0.667979f, 1.0f-0.335851f
    	};
    
    	GLuint vertexbuffer;
    	glGenBuffers(1, &vertexbuffer);
    	glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    	glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
    
    	GLuint uvbuffer;
    	glGenBuffers(1, &uvbuffer);
    	glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
    	glBufferData(GL_ARRAY_BUFFER, sizeof(g_uv_buffer_data), g_uv_buffer_data, GL_STATIC_DRAW);
    
    	do{
    
    		// Clear the screen
    		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    		// Use our shader
    		glUseProgram(programID);
    
    		// Send our transformation to the currently bound shader, 
    		// in the "MVP" uniform
    		glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
    
    		// Bind our texture in Texture Unit 0
    		glActiveTexture(GL_TEXTURE0);
    		glBindTexture(GL_TEXTURE_2D, Texture);
    		// Set our "myTextureSampler" sampler to use Texture Unit 0
    		glUniform1i(TextureID, 0);
    
    		// 1rst attribute buffer : vertices
    		glEnableVertexAttribArray(0);
    		glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    		glVertexAttribPointer(
    			0,                  // attribute. No particular reason for 0, but must match the layout in the shader.
    			3,                  // size
    			GL_FLOAT,           // type
    			GL_FALSE,           // normalized?
    			0,                  // stride
    			(void*)0            // array buffer offset
    		);
    
    		// 2nd attribute buffer : UVs
    		glEnableVertexAttribArray(1);
    		glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
    		glVertexAttribPointer(
    			1,                                // attribute. No particular reason for 1, but must match the layout in the shader.
    			2,                                // size : U+V => 2
    			GL_FLOAT,                         // type
    			GL_FALSE,                         // normalized?
    			0,                                // stride
    			(void*)0                          // array buffer offset
    		);
    
    		// Draw the triangle !
    		glDrawArrays(GL_TRIANGLES, 0, 12*3); // 12*3 indices starting at 0 -> 12 triangles
    
    		glDisableVertexAttribArray(0);
    		glDisableVertexAttribArray(1);
    
    		// Swap buffers
    		glfwSwapBuffers(window);
    		glfwPollEvents();
    
    	} // Check if the ESC key was pressed or the window was closed
    	while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
    		   glfwWindowShouldClose(window) == 0 );
    
    	// Cleanup VBO and shader
    	glDeleteBuffers(1, &vertexbuffer);
    	glDeleteBuffers(1, &uvbuffer);
    	glDeleteProgram(programID);
    	glDeleteTextures(1, &Texture);
    	glDeleteVertexArrays(1, &VertexArrayID);
    
    	// Close OpenGL window and terminate GLFW
    	glfwTerminate();
    
    	return 0;
    }
    
    
    
    #ifndef TEXTURE_HPP
    #define TEXTURE_HPP
    
    // Load a .BMP file using our custom loader
    GLuint loadBMP_custom(const char * imagepath);
    
    //// Since GLFW 3, glfwLoadTexture2D() has been removed. You have to use another texture loading library, 
    //// or do it yourself (just like loadBMP_custom and loadDDS)
    //// Load a .TGA file using GLFW's own loader
    //GLuint loadTGA_glfw(const char * imagepath);
    
    // Load a .DDS file using GLFW's own loader
    GLuint loadDDS(const char * imagepath);
    
    
    #endif
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include <GL/glew.h>
    
    #include <GLFW/glfw3.h>
    
    
    GLuint loadBMP_custom(const char * imagepath){
    
    	printf("Reading image %s
    ", imagepath);
    
    	// Data read from the header of the BMP file
    	unsigned char header[54];
    	unsigned int dataPos;
    	unsigned int imageSize;
    	unsigned int width, height;
    	// Actual RGB data
    	unsigned char * data;
    
    	// Open the file
    	FILE * file = fopen(imagepath,"rb");
    	if (!file){
    		printf("%s could not be opened. Are you in the right directory ? Don't forget to read the FAQ !
    ", imagepath);
    		getchar();
    		return 0;
    	}
    
    	// Read the header, i.e. the 54 first bytes
    
    	// If less than 54 bytes are read, problem
    	if ( fread(header, 1, 54, file)!=54 ){ 
    		printf("Not a correct BMP file
    ");
    		fclose(file);
    		return 0;
    	}
    	// A BMP files always begins with "BM"
    	if ( header[0]!='B' || header[1]!='M' ){
    		printf("Not a correct BMP file
    ");
    		fclose(file);
    		return 0;
    	}
    	// Make sure this is a 24bpp file
    	if ( *(int*)&(header[0x1E])!=0  )         {printf("Not a correct BMP file
    ");    fclose(file); return 0;}
    	if ( *(int*)&(header[0x1C])!=24 )         {printf("Not a correct BMP file
    ");    fclose(file); return 0;}
    
    	// Read the information about the image
    	dataPos    = *(int*)&(header[0x0A]);
    	imageSize  = *(int*)&(header[0x22]);
    	width      = *(int*)&(header[0x12]);
    	height     = *(int*)&(header[0x16]);
    
    	// Some BMP files are misformatted, guess missing information
    	if (imageSize==0)    imageSize=width*height*3; // 3 : one byte for each Red, Green and Blue component
    	if (dataPos==0)      dataPos=54; // The BMP header is done that way
    
    	// Create a buffer
    	data = new unsigned char [imageSize];
    
    	// Read the actual data from the file into the buffer
    	fread(data,1,imageSize,file);
    
    	// Everything is in memory now, the file can be closed.
    	fclose (file);
    
    	// Create one OpenGL texture
    	GLuint textureID;
    	glGenTextures(1, &textureID);
    	
    	// "Bind" the newly created texture : all future texture functions will modify this texture
    	glBindTexture(GL_TEXTURE_2D, textureID);
    
    	// Give the image to OpenGL
    	glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
    
    	// OpenGL has now copied the data. Free our own version
    	delete [] data;
    
    	// Poor filtering, or ...
    	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    
    	// ... nice trilinear filtering ...
    	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_TEXTURE_MAG_FILTER, GL_LINEAR);
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    	// ... which requires mipmaps. Generate them automatically.
    	glGenerateMipmap(GL_TEXTURE_2D);
    
    	// Return the ID of the texture we just created
    	return textureID;
    }
    
    // Since GLFW 3, glfwLoadTexture2D() has been removed. You have to use another texture loading library, 
    // or do it yourself (just like loadBMP_custom and loadDDS)
    //GLuint loadTGA_glfw(const char * imagepath){
    //
    //	// Create one OpenGL texture
    //	GLuint textureID;
    //	glGenTextures(1, &textureID);
    //
    //	// "Bind" the newly created texture : all future texture functions will modify this texture
    //	glBindTexture(GL_TEXTURE_2D, textureID);
    //
    //	// Read the file, call glTexImage2D with the right parameters
    //	glfwLoadTexture2D(imagepath, 0);
    //
    //	// Nice trilinear filtering.
    //	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_TEXTURE_MAG_FILTER, GL_LINEAR);
    //	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 
    //	glGenerateMipmap(GL_TEXTURE_2D);
    //
    //	// Return the ID of the texture we just created
    //	return textureID;
    //}
    
    
    
    #define FOURCC_DXT1 0x31545844 // Equivalent to "DXT1" in ASCII
    #define FOURCC_DXT3 0x33545844 // Equivalent to "DXT3" in ASCII
    #define FOURCC_DXT5 0x35545844 // Equivalent to "DXT5" in ASCII
    
    GLuint loadDDS(const char * imagepath){
    
    	unsigned char header[124];
    
    	FILE *fp; 
     
    	/* try to open the file */ 
    	fp = fopen(imagepath, "rb"); 
    	if (fp == NULL){
    		printf("%s could not be opened. Are you in the right directory ? Don't forget to read the FAQ !
    ", imagepath); getchar(); 
    		return 0;
    	}
       
    	/* verify the type of file */ 
    	char filecode[4]; 
    	fread(filecode, 1, 4, fp); 
    	if (strncmp(filecode, "DDS ", 4) != 0) { 
    		fclose(fp); 
    		return 0; 
    	}
    	
    	/* get the surface desc */ 
    	fread(&header, 124, 1, fp); 
    
    	unsigned int height      = *(unsigned int*)&(header[8 ]);
    	unsigned int width	     = *(unsigned int*)&(header[12]);
    	unsigned int linearSize	 = *(unsigned int*)&(header[16]);
    	unsigned int mipMapCount = *(unsigned int*)&(header[24]);
    	unsigned int fourCC      = *(unsigned int*)&(header[80]);
    
     
    	unsigned char * buffer;
    	unsigned int bufsize;
    	/* how big is it going to be including all mipmaps? */ 
    	bufsize = mipMapCount > 1 ? linearSize * 2 : linearSize; 
    	buffer = (unsigned char*)malloc(bufsize * sizeof(unsigned char)); 
    	fread(buffer, 1, bufsize, fp); 
    	/* close the file pointer */ 
    	fclose(fp);
    
    	unsigned int components  = (fourCC == FOURCC_DXT1) ? 3 : 4; 
    	unsigned int format;
    	switch(fourCC) 
    	{ 
    	case FOURCC_DXT1: 
    		format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; 
    		break; 
    	case FOURCC_DXT3: 
    		format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; 
    		break; 
    	case FOURCC_DXT5: 
    		format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; 
    		break; 
    	default: 
    		free(buffer); 
    		return 0; 
    	}
    
    	// Create one OpenGL texture
    	GLuint textureID;
    	glGenTextures(1, &textureID);
    
    	// "Bind" the newly created texture : all future texture functions will modify this texture
    	glBindTexture(GL_TEXTURE_2D, textureID);
    	glPixelStorei(GL_UNPACK_ALIGNMENT,1);	
    	
    	unsigned int blockSize = (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16; 
    	unsigned int offset = 0;
    
    	/* load the mipmaps */ 
    	for (unsigned int level = 0; level < mipMapCount && (width || height); ++level) 
    	{ 
    		unsigned int size = ((width+3)/4)*((height+3)/4)*blockSize; 
    		glCompressedTexImage2D(GL_TEXTURE_2D, level, format, width, height,  
    			0, size, buffer + offset); 
    	 
    		offset += size; 
    		width  /= 2; 
    		height /= 2; 
    
    		// Deal with Non-Power-Of-Two textures. This code is not included in the webpage to reduce clutter.
    		if(width < 1) width = 1;
    		if(height < 1) height = 1;
    
    	} 
    
    	free(buffer); 
    
    	return textureID;
    
    
    }
    
    #version 330 core
    
    // Input vertex data, different for all executions of this shader.
    layout(location = 0) in vec3 vertexPosition_modelspace;
    layout(location = 1) in vec2 vertexUV;
    
    // Output data ; will be interpolated for each fragment.
    out vec2 UV;
    
    // Values that stay constant for the whole mesh.
    uniform mat4 MVP;
    
    void main(){
    
    	// Output position of the vertex, in clip space : MVP * position
    	gl_Position =  MVP * vec4(vertexPosition_modelspace,1);
    	
    	// UV of the vertex. No special space for this one.
    	UV = vertexUV;
    }
    
    
    
    #version 330 core
    
    // Interpolated values from the vertex shaders
    in vec2 UV;
    
    // Ouput data
    out vec3 color;
    
    // Values that stay constant for the whole mesh.
    uniform sampler2D myTextureSampler;
    
    void main(){
    
    	// Output color = color of the texture at the specified UV
    	color = texture( myTextureSampler, UV ).rgb;
    }
    
    Hope is a good thing,maybe the best of things,and no good thing ever dies.----------- Andy Dufresne
  • 相关阅读:
    android绘画折线图二
    android绘画折线图一
    jQuery Select操作大集合
    jquery事件切换hover/toggle
    jquery $(document).ready() 与window.onload的区别
    canny边缘检测 C++手动实现
    高斯核原理和C++实现
    darknet-yolov3 burn_in learning_rate policy
    UserWarning: indexing with dtype torch.uint8 is now deprecated, please use a dtype torch.bool instead
    BatchNormaliation
  • 原文地址:https://www.cnblogs.com/eat-too-much/p/14066868.html
Copyright © 2020-2023  润新知