openg 立方体纹理

opengl 立方体纹理
来给立方体贴个图。
// glfwTest.cpp : 定义控制台应用程序的入口点。
//
#include "glew.h"
#include <glfw3.h>
#include "common/loadShader.h"
#include "glm.hpp"
#include "ext.hpp"

int main(void)
{
	GLFWwindow* window;

	/* Initialize the library */
	if (!glfwInit())
		return -1;

	/* Create a windowed mode window and its OpenGL context */
	window = glfwCreateWindow(480, 320, "Hello World", NULL, NULL);
	if (!window)
	{
		glfwTerminate();
		return -1;
	}

	/* Make the window's context current */
	glfwMakeContextCurrent(window);

	// Needed in core profile
	if( glewInit() != GLEW_OK)
	{
		glfwTerminate();
		return -1;
	}

	// 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.f, 1.f, 1.f,
		-1.f,-1.f, 1.f,
		 1.f,-1.f, 1.f,

		 1.f,-1.f, 1.f,
		 1.f, 1.f, 1.f,
		 -1.f, 1.f, 1.f,


		 1.f, 1.f, 1.f,
		 1.f,-1.f, 1.f,
		 1.f,-1.f,-1.f,

		 1.f,-1.f,-1.f,
		 1.f, 1.f,-1.f,
		 1.f, 1.f, 1.f,


		-1.f, 1.f,-1.f,
		-1.f, 1.f, 1.f,
		 1.f, 1.f, 1.f,

		 1.f, 1.f, 1.f,
	     1.f, 1.f,-1.f,
		 -1.f, 1.f,-1.f,


		-1.f,-1.f,-1.f,
		-1.f,-1.f, 1.f,
		 1.f,-1.f, 1.f,

		 1.f,-1.f, 1.f,
		 1.f,-1.f,-1.f,
		 -1.f,-1.f,-1.f,


		-1.f, 1.f,-1.f,
		-1.f,-1.f,-1.f,
		 1.f,-1.f,-1.f,

		 1.f,-1.f,-1.f,
		 1.f, 1.f,-1.f,
		 -1.f, 1.f,-1.f,


		 -1.f, 1.f, 1.f,
		 -1.f, 1.f,-1.f,
		 -1.f,-1.f,-1.f,

		 -1.f,-1.f,-1.f,
		 -1.f,-1.f, 1.f,
		-1.f, 1.f, 1.f, 		
 		
	};

	
	//This will identify our vertex buffer
	GLuint vertexbuffer;

	
	//Generate 1 buffer,put the resulting identifier in vertexbuffer
	glGenBuffers(1,&vertexbuffer);		

	//The following commands will talk about our 'vertexbuffer' buffer
	glBindBuffer(GL_ARRAY_BUFFER,vertexbuffer);

	//Give our vertices to OpenGL.
	glBufferData(GL_ARRAY_BUFFER,sizeof(g_vertex_buffer_data),g_vertex_buffer_data,GL_STATIC_DRAW);


	GLuint Texture = loadBMP_custom("./resource/uvtemplate.bmp");
	// One color for each vertex. They were generated randomly.
	static const GLfloat g_uv_buffer_data[] = {
		0.0f, 1.0f,
		0.0f, 0.0f,
		1.0f, 0.0f,

		1.0f, 0.0f,
		1.0f, 1.0f,
		0.0f, 1.0f,


		0.0f, 1.0f,
		0.0f, 0.0f,
		1.0f, 0.0f,

		1.0f, 0.0f,
		1.0f, 1.0f,
		0.0f, 1.0f,



		0.0f, 1.0f,
		0.0f, 0.0f,
		1.0f, 0.0f,

		1.0f, 0.0f,
		1.0f, 1.0f,
		0.0f, 1.0f,


		0.0f, 1.0f,
		0.0f, 0.0f,
		1.0f, 0.0f,

		1.0f, 0.0f,
		1.0f, 1.0f,
		0.0f, 1.0f,


		0.0f, 1.0f,
		0.0f, 0.0f,
		1.0f, 0.0f,

		1.0f, 0.0f,
		1.0f, 1.0f,
		0.0f, 1.0f,


		0.0f, 1.0f,
		1.0f, 1.0f,
		1.0f, 0.0f,

		1.0f, 0.0f,
		0.0f, 0.0f,
		0.0f, 1.0f		
 		
	};
	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);


	GLuint programID = LoadShaders("./shader/vertex.shader","./shader/fragment.shader");
	glUseProgram(programID);
	glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
	/* Loop until the user closes the window */

	// Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit  100 units
	//glm::mat4 Projection = glm::ortho(-4.0f/3.0f, 4.0f/3.0f, -1.0f, 1.0f, 0.1f, 100.0f);
	glm::mat4 Projection = glm::perspective(45.0f,4.0f/3.0f,0.1f,100.f);
	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
	
		
	
		// Get a handle for our "MVP" uniform.
		// Only at initialisation time.
		GLuint MatrixID = glGetUniformLocation(programID,"MVP");
	
		// Send our transformation to the currently bound shader,
		// in the "MVP" uniform
		// For each model you render, since the MVP will be different (at least the M part)
		glUniformMatrix4fv(MatrixID,1,GL_FALSE,&MVP[0][0]);

		GLuint TextureID = glGetUniformLocation(programID,"myTextureSampler");
		 
		
	while (!glfwWindowShouldClose(window))
	{
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D,Texture);
		glUniform1i(TextureID, 0);
		

		glEnableVertexAttribArray(0);
		glBindBuffer(GL_ARRAY_BUFFER,vertexbuffer);
		glVertexAttribPointer(
			0,			// attribute 0. 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
			);

		

		glEnableVertexAttribArray(1);
		glBindBuffer(GL_ARRAY_BUFFER,uvbuffer);	
		glVertexAttribPointer(
			1,			// attribute 0. No particular reason for 0, but must match the layout in the shader.
			2,			// size
			GL_FLOAT,	// type
			GL_FALSE,	// normalized?
			0,			// stride
			(void*)0	// array buffer offset
			);

		glEnable(GL_DEPTH_TEST);
		glDepthFunc(GL_LESS);
		glDrawArrays(GL_TRIANGLES,0,12*3);// Starting from vertex 0; 3 vertices total -> 1 triangle
		
			
		

		
		

		
		glDisableVertexAttribArray(0);
		glDisableVertexAttribArray(1);
		/* Swap front and back buffers */
		glfwSwapBuffers(window);

		/* Poll for and process events */
		glfwPollEvents();
	}

	glfwTerminate();
	return 0;
}

加载纹理代码:
#include "loadShader.h"

GLuint LoadShaders(const char* vertex_file_path,const char* fragment_file_path)
{
	//Create the shaders
	GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
	GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);

	//Read the Vertex Shader code from the file
	std::string VertexShaderCode;
	std::ifstream VertexShaderStream(vertex_file_path,std::ios::in);
	if (VertexShaderStream.is_open())
	{
		std::string Line = "";
		while (getline(VertexShaderStream,Line))
		{
			VertexShaderCode += "\n" + Line;
		}

		VertexShaderStream.close();
	}


	//Read the Fragment Shader code from the file
	std::string FragmentShaderCode;
	std::ifstream FragmentShaderStream(fragment_file_path,std::ios::in);
	if (FragmentShaderStream.is_open())
	{
		std::string Line = "";
		while (getline(FragmentShaderStream,Line))
		{
			FragmentShaderCode += "\n" + Line;
		}

		FragmentShaderStream.close();
	}

	GLint Result = GL_FALSE;
	int InfoLogLength;

	//compile Vertex Shader
	printf("Compiling shader : %s\n",vertex_file_path);
	char const * VertexSourcePointer = VertexShaderCode.c_str();
	glShaderSource(VertexShaderID,1,&VertexSourcePointer,NULL);
	glCompileShader(VertexShaderID);

	// Check vertex Shader
	glGetShaderiv(VertexShaderID,GL_COMPILE_STATUS,&Result);
	glGetShaderiv(VertexShaderID,GL_INFO_LOG_LENGTH,&InfoLogLength);
	std::vector<char> VerTexShaderErrorMessage(InfoLogLength); 
	glGetShaderInfoLog(VertexShaderID,InfoLogLength,NULL,&VerTexShaderErrorMessage[0]);
	fprintf(stdout,"%s\n",&VerTexShaderErrorMessage[0]);

	//compile Fragment Shader
	printf("Compiling shader : %s\n",fragment_file_path);
	char const * FragmentSourcePointer = FragmentShaderCode.c_str();
	glShaderSource(FragmentShaderID,1,&FragmentSourcePointer,NULL);
	glCompileShader(FragmentShaderID);

	// Check vertex Shader
	glGetShaderiv(FragmentShaderID,GL_COMPILE_STATUS,&Result);
	glGetShaderiv(FragmentShaderID,GL_INFO_LOG_LENGTH,&InfoLogLength);
	std::vector<char> FragmentShaderErrorMessage(InfoLogLength); 
	glGetShaderInfoLog(FragmentShaderID,InfoLogLength,NULL,&FragmentShaderErrorMessage[0]);
	fprintf(stdout,"%s\n",&FragmentShaderErrorMessage[0]);

	//Link the program
	fprintf(stdout,"Linking programn");
	GLuint ProgramID = glCreateProgram();
	glAttachShader(ProgramID,VertexShaderID);
	glAttachShader(ProgramID,FragmentShaderID);
	glLinkProgram(ProgramID);

	//Check the program
	glGetProgramiv(ProgramID,GL_LINK_STATUS,&Result);
	glGetProgramiv(ProgramID,GL_INFO_LOG_LENGTH,&InfoLogLength);
	std::vector<char> ProgramErrorMessage(InfoLogLength);
	glGetProgramInfoLog(ProgramID,InfoLogLength,NULL,&ProgramErrorMessage[0]);
	fprintf(stdout,"%s\n",&ProgramErrorMessage[0]);

	glDeleteShader(VertexShaderID);
	glDeleteShader(FragmentShaderID);

	return ProgramID;
}

GLuint loadBMP_custom(const char * imagepath)
{
	// Data read from the header of the BMP file
	unsigned char header[54]; // Each BMP file begins by a 54-bytes header
	unsigned int dataPos;     //Position in the file where the actual data begins
	unsigned int width,height;
	unsigned int imageSize;    //= width*height*3
	// Actual RGB data
	unsigned char * data;

	//Open the file
	FILE * file = fopen(imagepath,"rb");
	if (!file)
	{
		printf("Image could not be openedn"); 
		return 0;
	}

	if (fread(header,1,54,file) != 54)
	{
		printf("Not a correct BMP filen");
		return false;
	}

	if (header[0] != 'B' || header[1] != 'M')
	{
		printf("Not a correct BMP filen");
		return 0;
	}

	dataPos		= *(int*)&(header[0x0A]);
	imageSize	= *(int*)&(header[0x22]);
	width		= *(int*)&(header[0x12]);
	height		= *(int*)&(header[0x16]);

	if (imageSize == 0)
	{
		imageSize = width * height * 3;
	}

	if (dataPos == 0)
	{
		dataPos = 54;
	}

	// 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);

	

	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);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

// 	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);
	delete[] data;
	return textureID;

}
vertex.shader
#version 330 core

layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec2 vertexUV;

uniform mat4 MVP;
out vec2 UV;

void main(){
	vec4 v = vec4(vertexPosition_modelspace,1);
	gl_Position = MVP * v;	
	UV = vertexUV;
	
}


fragment.shader
#version 330 core
// Interpolated values from the vertex shaders
in vec2 UV;

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;
	
	}

首先,解析图片,生成纹理。
glGenTextures(1, &textureID);
激活纹理
glBindTexture(GL_TEXTURE_2D, textureID);
图片数据写入到纹理
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
设置取样方式
//normal
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);


//nice
// 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);

得到shader中的纹理变量。
GLuint TextureID = glGetUniformLocation(programID,"myTextureSampler");
设置纹理序列
glActiveTexture(GL_TEXTURE0);
激活纹理
glBindTexture(GL_TEXTURE_2D, textureID);
关联shader变量与纹理
glUniform1i(TextureID, 0);

然后,shader中会通过纹理坐标把纹理给贴上去。

你可能感兴趣的:(openg 立方体纹理)