OpenGL Shader 绘制天空盒_基础 2

OpenGL Shader 绘制天空盒_基础 2_第1张图片


参考:

http://learnopengl-cn.readthedocs.io/zh/latest/04%20Advanced%20OpenGL/06%20Cubemaps/


源码:

http://download.csdn.net/detail/yulinxx/9719755



main.cpp


#define GLEW_STATIC  
#include   

#include   

#include "Shader.h"  
#include "Camera.h"  

#include   
#include   
#include   

#include   

#include   

#pragma comment (lib, "opengl32.lib")  
#pragma comment (lib, "glew32s.lib")  
#pragma comment (lib, "glfw3.lib")   
#pragma comment (lib, "glfw3dll.lib")   
#pragma comment (lib, "glew32mxs.lib")  
#pragma comment (lib, "assimp.lib")  
#pragma comment(lib, "SOIL.lib")  


GLuint WIDTH = 800, HEIGHT = 600;

void key_callback(GLFWwindow* pWnd, int key, int scancode, int action, int mode);
void mouse_callback(GLFWwindow* pWnd, double xpos, double ypos);
void Do_Movement();
GLuint loadTexture(GLchar* path, GLboolean alpha = false);
GLuint loadCubemapTexture(std::vector vecSkyfaces);


Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
bool keys[1024];
GLfloat lastX = 400, lastY = 300;
bool firstMouse = true;

GLfloat deltaTime = 0.0f;
GLfloat lastFrame = 0.0f;

// ******************************************************
int main()
{
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

	GLFWwindow* pWnd = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr); // Windowed  
	glfwMakeContextCurrent(pWnd);

	glfwSetKeyCallback(pWnd, key_callback);
	glfwSetCursorPosCallback(pWnd, mouse_callback);

	//glfwSetInputMode(pWnd, GLFW_CURSOR, GLFW_CURSOR_DISABLED);  
	glewExperimental = GL_TRUE;
	glewInit();
	glViewport(0, 0, WIDTH, HEIGHT);

	// 立方体  
	GLfloat cubeVertices[] = {
		-0.5f, -0.5f, -0.5f,  0.0f, 0.0f,		0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
		0.5f,  0.5f, -0.5f,  1.0f, 1.0f,		0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
		-0.5f,  0.5f, -0.5f,  0.0f, 1.0f,		-0.5f, -0.5f, -0.5f,  0.0f, 0.0f,

		-0.5f, -0.5f,  0.5f,  0.0f, 0.0f,		0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
		0.5f,  0.5f,  0.5f,  1.0f, 1.0f,		0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
		-0.5f,  0.5f,  0.5f,  0.0f, 1.0f,		-0.5f, -0.5f,  0.5f,  0.0f, 0.0f,

		-0.5f,  0.5f,  0.5f,  1.0f, 0.0f,		-0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
		-0.5f, -0.5f, -0.5f,  0.0f, 1.0f,		-0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
		-0.5f, -0.5f,  0.5f,  0.0f, 0.0f,		-0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

		0.5f,  0.5f,  0.5f,  1.0f, 0.0f,		0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
		0.5f, -0.5f, -0.5f,  0.0f, 1.0f,		0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
		0.5f, -0.5f,  0.5f,  0.0f, 0.0f,		0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

		-0.5f, -0.5f, -0.5f,  0.0f, 1.0f,		0.5f, -0.5f, -0.5f,  1.0f, 1.0f,
		0.5f, -0.5f,  0.5f,  1.0f, 0.0f,		0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
		-0.5f, -0.5f,  0.5f,  0.0f, 0.0f,		-0.5f, -0.5f, -0.5f,  0.0f, 1.0f,

		-0.5f,  0.5f, -0.5f,  0.0f, 1.0f,		0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
		0.5f,  0.5f,  0.5f,  1.0f, 0.0f,		0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
		-0.5f,  0.5f,  0.5f,  0.0f, 0.0f,		-0.5f,  0.5f, -0.5f,  0.0f, 1.0f
	};

	// 地面  
	GLfloat floorVertices[] = {
		5.0f,  -0.5f,  5.0f,  2.0f, 0.0f,
		-5.0f, -0.5f,  5.0f,  0.0f, 0.0f,
		-5.0f, -0.5f, -5.0f,  0.0f, 2.0f,

		5.0f,  -0.5f,  5.0f,  2.0f, 0.0f,
		-5.0f, -0.5f, -5.0f,  0.0f, 2.0f,
		5.0f,  -0.5f, -5.0f,  2.0f, 2.0f
	};
	
	// 天空盒
	GLfloat skyboxVertices[] = {
		-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
	};

	// 数据处理
	
	// 地面  
	GLuint floorVAO, floorVBO;
	glGenVertexArrays(1, &floorVAO);
	glBindVertexArray(floorVAO);
	{
		glGenBuffers(1, &floorVBO);
		glBindBuffer(GL_ARRAY_BUFFER, floorVBO);
		glBufferData(GL_ARRAY_BUFFER, sizeof(floorVertices), floorVertices, GL_STATIC_DRAW);

		glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)0);
		glEnableVertexAttribArray(0);

		glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));
		glEnableVertexAttribArray(1);
	}
	glBindVertexArray(0);

	// 盒子
	GLuint cubeVAO, cubeVBO;
	glGenVertexArrays(1, &cubeVAO);
	{
		glGenBuffers(1, &cubeVBO);
		glBindVertexArray(cubeVAO);
		glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
		glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), &cubeVertices, GL_STATIC_DRAW);
		
		glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);
		glEnableVertexAttribArray(0);

		glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 
			5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
		glEnableVertexAttribArray(1);
	}
	glBindVertexArray(0);

	// 天空
	GLuint skyboxVAO, skyboxVBO;
	glGenVertexArrays(1, &skyboxVAO);
	glBindVertexArray(skyboxVAO);
	{
		glGenBuffers(1, &skyboxVBO);
		glBindBuffer(GL_ARRAY_BUFFER, skyboxVBO);
		glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), skyboxVertices, GL_STATIC_DRAW);

		glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GL_FLOAT), (void*)0);
		glEnableVertexAttribArray(0);

		glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GL_FLOAT), (void*)(2 * sizeof(GL_FLOAT)));
		glEnableVertexAttribArray(1);
	}
	glBindVertexArray(0);

	// Shader  
	Shader shaderCube("./Shader/cube_vertex", "./Shader/cube_fragement");
	Shader shaderFloor("./Shader/floor_vertex", "./Shader/floor_fragement");
	Shader shaderSkybox("./Shader/skybox_vertex", "./Shader/skybox_fragement");

	// 纹理  
	GLuint textCube = loadTexture("./Img/cube.jpg");
	GLuint textFloor = loadTexture("./Img/floor.jpg");

	std::vector vecSkyfaces;
	vecSkyfaces.push_back("./img/skybox/right.jpg");
	vecSkyfaces.push_back("./img/skybox/left.jpg");
	vecSkyfaces.push_back("./img/skybox/top.jpg");
	vecSkyfaces.push_back("./img/skybox/bottom.jpg");
	vecSkyfaces.push_back("./img/skybox/back.jpg");
	vecSkyfaces.push_back("./img/skybox/front.jpg");

	GLuint textureCubemap = loadCubemapTexture(vecSkyfaces);
	
	// 视图设置
	glm::mat4 model = glm::mat4();
	glm::mat4 view = camera.GetViewMatrix();
	glm::mat4 projection = glm::perspective(camera.Zoom, (float)WIDTH / (float)HEIGHT, 0.0f, 100.0f);
	
	// 主循环
	while (!glfwWindowShouldClose(pWnd))
	{
		GLfloat currentFrame = glfwGetTime();
		deltaTime = currentFrame - lastFrame;
		lastFrame = currentFrame;

		glfwPollEvents();
		Do_Movement();

		glClearColor(0.1f, 0.2f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);

		// 绘制天空盒
		shaderSkybox.useShaderPrograme();
		view = glm::mat4(glm::mat3(camera.GetViewMatrix()));
		glUniformMatrix4fv(glGetUniformLocation(shaderSkybox.getPrograme(), "view"),
			1, GL_FALSE, glm::value_ptr(view));
		glUniformMatrix4fv(glGetUniformLocation(shaderSkybox.getPrograme(), "projection"),
			1, GL_FALSE, glm::value_ptr(projection));

		glBindVertexArray(cubeVAO);		// 使用天空盒数据
		{
			glActiveTexture(GL_TEXTURE0);
			glUniform1i(glGetUniformLocation(shaderSkybox.getPrograme(), "skybox"), 0);
			glBindTexture(GL_TEXTURE_CUBE_MAP, textureCubemap); // 使用天空盒数据纹理
			{
				glDrawArrays(GL_TRIANGLES, 0, 36);
			}
			glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
		}
		glBindVertexArray(0);


		view = camera.GetViewMatrix();

		// 绘制地面
		shaderFloor.useShaderPrograme();
		glBindVertexArray(floorVAO);
		{
			glUniformMatrix4fv(glGetUniformLocation(shaderFloor.getPrograme(), "model"),
				1, GL_FALSE, glm::value_ptr(model));
			glUniformMatrix4fv(glGetUniformLocation(shaderFloor.getPrograme(), "view"),
				1, GL_FALSE, glm::value_ptr(view));
			glUniformMatrix4fv(glGetUniformLocation(shaderFloor.getPrograme(), "projection"),
				1, GL_FALSE, glm::value_ptr(projection));

			glActiveTexture(GL_TEXTURE0);
			glBindTexture(GL_TEXTURE_2D, textFloor);
			{
				glDrawArrays(GL_TRIANGLES, 0, 6);
			}
			glBindTexture(GL_TEXTURE_2D, 0);
		}
		glBindVertexArray(0);

		// 绘制立方体
		shaderCube.useShaderPrograme();
		glBindVertexArray(cubeVAO);	// 使用立方体数据
		{
			glUniformMatrix4fv(glGetUniformLocation(shaderCube.getPrograme(), "model"),
				1, GL_FALSE, glm::value_ptr(model));
			glUniformMatrix4fv(glGetUniformLocation(shaderCube.getPrograme(), "view"),
				1, GL_FALSE, glm::value_ptr(view));
			glUniformMatrix4fv(glGetUniformLocation(shaderCube.getPrograme(), "projection"),
				1, GL_FALSE, glm::value_ptr(projection));
			glUniform3f(glGetUniformLocation(shaderCube.getPrograme(), "cameraPos"), 
				camera.Position.x, camera.Position.y, camera.Position.z);

			glActiveTexture(GL_TEXTURE0);
			glUniform1i(glGetUniformLocation(shaderCube.getPrograme(), "inTexture"), 0);
			glBindTexture(GL_TEXTURE_CUBE_MAP, skyboxVAO);	// 使用天空盒的纹理
			{
				glDrawArrays(GL_TRIANGLES, 0, 36);
			}
			glBindTexture(GL_TEXTURE_2D, 0);
		}
		glBindVertexArray(0);
		
		glfwSwapBuffers(pWnd);
	}

	// While 循环之后  清理资源,退出程序  
	glDeleteVertexArrays(1, &cubeVAO);
	glDeleteVertexArrays(1, &floorVAO);
	glDeleteVertexArrays(1, &skyboxVAO);
	glDeleteBuffers(1, &cubeVBO);
	glDeleteBuffers(1, &floorVBO);
	glDeleteBuffers(1, &skyboxVBO);

	glfwTerminate();
	return 0;
}

// ******************************************************
// 加载纹理  
GLuint loadTexture(GLchar* path, GLboolean alpha /*= false*/)
{
	int nPicW = 0, nPicH = 0;
	unsigned char* pChImg =
		SOIL_load_image(path, &nPicW, &nPicH, 0, alpha ? SOIL_LOAD_RGBA : SOIL_LOAD_RGB);

	GLuint textureID = 0;
	glGenTextures(1, &textureID);
	glBindTexture(GL_TEXTURE_2D, textureID);
	{
		glTexImage2D(GL_TEXTURE_2D, 0, alpha ? GL_RGBA : GL_RGB, nPicW, nPicH, 0,
			alpha ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, pChImg);
		glGenerateMipmap(GL_TEXTURE_2D);

		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, alpha ? GL_CLAMP_TO_EDGE : GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, alpha ? GL_CLAMP_TO_EDGE : GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	}
	glBindTexture(GL_TEXTURE_2D, 0);
	SOIL_free_image_data(pChImg);
	return textureID;
}

// ******************************************************
// 加载天空盒纹理
GLuint loadCubemapTexture(std::vector vecSkyfaces)
{
	GLuint textureId = 0;
	glGenTextures(1, &textureId);
	glBindTexture(GL_TEXTURE_CUBE_MAP, textureId);
	{
		int nW = 0, nH = 0;
		unsigned char* pChImg = nullptr;

		for (int i = 0; i < vecSkyfaces.size(); i++)
		{
			pChImg = SOIL_load_image(vecSkyfaces[i], &nW, &nH, 0, SOIL_LOAD_RGB);
			glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB,
				nW, nH, 0, GL_RGB, GL_UNSIGNED_BYTE, pChImg);
			SOIL_free_image_data(pChImg);
		}
		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
	}
	glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
	return textureId;
}

// ******************************************************
void Do_Movement()
{
	if (keys[GLFW_KEY_W])
		camera.ProcessKeyboard(FORWARD, deltaTime);
	if (keys[GLFW_KEY_S])
		camera.ProcessKeyboard(BACKWARD, deltaTime);
	if (keys[GLFW_KEY_A])
		camera.ProcessKeyboard(LEFT, deltaTime);
	if (keys[GLFW_KEY_D])
		camera.ProcessKeyboard(RIGHT, deltaTime);
}

// ******************************************************
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
	if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
		glfwSetWindowShouldClose(window, GL_TRUE);

	if (action == GLFW_PRESS)
		keys[key] = true;
	else if (action == GLFW_RELEASE)
		keys[key] = false;
}

// ******************************************************
void mouse_callback(GLFWwindow* window, double xpos, double ypos)
{
	if (firstMouse)
	{
		lastX = xpos;
		lastY = ypos;
		firstMouse = false;
	}

	GLfloat xoffset = xpos - lastX;
	GLfloat yoffset = lastY - ypos;

	lastX = xpos;
	lastY = ypos;

	camera.ProcessMouseMovement(xoffset, yoffset);
}



Camera.h   Shader.h 参考之前的文章




*********************************************

------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Shader  GLSL 语言部分



地面  立方体   天空  绘制渲染方式不一样

所以分别给它们定义Shader


地面

floor_vertex


#version 330 core    
layout (location = 0) in vec3 position;    
layout (location = 1) in vec2 texCoords;    
    
out vec2 TexCoords;    
    
uniform mat4 model;    
uniform mat4 view;    
uniform mat4 projection;    
    
void main()    
{    
    gl_Position = projection * view * model * vec4(position, 1.0f);    
    TexCoords = texCoords;    
}


floor_fragement


#version 330 core    
    
in vec2 TexCoords;    
    
out vec4 color;    
    
uniform sampler2D inTexture;    
    
void main()    
{    
    color = texture(inTexture, TexCoords);    
} 


立方体

cube_vertex

// ================  
#version 330 core  
layout (location = 0) in vec3 pos;  
layout (location = 1) in vec3 normal;
  
//out vec2 TexCoords;  
out vec3 Normal;
out vec3 Pos;
 
uniform mat4 model;  
uniform mat4 view;  
uniform mat4 projection;  
  
void main()  
{  
    gl_Position = projection * view * model * vec4(pos, 1.0f);  
    //TexCoords = texCoords;  
	Normal = mat3(transpose(inverse(model))) * normal;
	Pos = vec3(model * vec4(pos, 1.0f));
}  


cube_fragement

// ================  
#version 330 core  

//in vec2 TexCoords;  
in vec3 Normal;
in vec3 Pos;

out vec4 color;  

uniform vec3 cameraPos;  
uniform samplerCube skybox;

//uniform sampler2D inTexture;  
  
void main()  
{  
    //color = texture(inTexture, TexCoords);  
	vec3 I = normalize(Pos - cameraPos);
	vec3 R = reflect(I, normalize(Normal));
	color = texture(skybox, R);
}  


天空


skybox_vertex

#version 330 core  
layout (location = 0) in vec3 position;

out vec3 TexCoords;
  
uniform mat4 view;
uniform mat4 projection;
  
void main()  
{  
    gl_Position = projection * view * vec4(position, 1.0f);  
    TexCoords = position;
}


skybox_fragement

// ================  

#version 330 core
in vec3 TexCoords;
out vec4 color;

uniform samplerCube skybox;

void main()
{
    color = texture(skybox, TexCoords);
}

OpenGL Shader 绘制天空盒_基础 2_第2张图片



你可能感兴趣的:(OpenGL)