openGL 实现带贴图立方体旋转

首先是顶点数组需要36个顶点数据,这里就不用指定EBO了,因为这些点的有重复的顶点:

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

同样准备VAO,VBO

glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);
	glGenBuffers(1,&EBO);
	// renderObjByMoreP(VAO,VBO,vertices,sizeof(vertices));
	
	//render2dElement();
	render3dBox();

开启深度测试:

// 开启深度测试默认是关闭的
	glEnable(GL_DEPTH_TEST);
// 渲染3d盒子
void render3dBox() {
	glBindVertexArray(VAO);
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW);

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

准备两张图片是箱子皮上的贴图

unsigned int texture1, texture2;
	
	/*renderTexture(GL_TEXTURE0, &texture1,&width,&height,&nrChannels,data);
	stbi_set_flip_vertically_on_load(true);
	renderTexture(GL_TEXTURE1, &texture2,&width,&height,&nrChannels,data);*/
	renderTexture(&texture1,&texture2);
	
	// tell opengl for each sampler to which texture unit it belongs to (only has to be done once)
	// -------------------------------------------------------------------------------------------
	shaderItem.use(); // don't forget to activate/use the shader before setting uniforms!
	// or set it via the texture class
	shaderItem.setInt("texture1",0);
	shaderItem.setInt("texture2",1);
	uint textureArr[] = {texture1,texture2};
// 渲染纹理
void renderTexture(uint *texture1,uint *texture2) {
	int width, height, nrChannels;
	unsigned char* data = nullptr;
	stbi_set_flip_vertically_on_load(true);
	/*createTexture(texture1,&width,&height,&nrChannels,data,"container.jpg");
	createTexture(texture2,&width,&height,&nrChannels,data,"awesomeface.png");*/
	glGenTextures(1, texture1);
	glBindTexture(GL_TEXTURE_2D, *texture1);
	// set the texture wrapping parameters
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);	// set texture wrapping to GL_REPEAT (default wrapping method)
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	// set texture filtering parameters
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	// load image, create texture and generate mipmaps

	// The FileSystem::getPath(...) is part of the GitHub repository so we can find files on any IDE/platform; replace it with your own image path.
	data = stbi_load("container.jpg", &width, &height, &nrChannels, 0);
	if (data)
	{
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
		glGenerateMipmap(GL_TEXTURE_2D);
	}
	else
	{
		std::cout << "Failed to load texture" << std::endl;
	}
	stbi_image_free(data);
	// texture 2
	// ---------
	glGenTextures(1, texture2);
	glBindTexture(GL_TEXTURE_2D, *texture2);
	// set the texture wrapping parameters
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);	// set texture wrapping to GL_REPEAT (default wrapping method)
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	// set texture filtering parameters
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	// load image, create texture and generate mipmaps
	data = stbi_load("awesomeface.png", &width, &height, &nrChannels, 0);
	if (data)
	{
		// note that the awesomeface.png has transparency and thus an alpha channel, so make sure to tell OpenGL the data type is of GL_RGBA
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
		glGenerateMipmap(GL_TEXTURE_2D);
	}
	else
	{
		std::cout << "Failed to load texture" << std::endl;
	}
	stbi_image_free(data);

}

渲染循环里面:每次渲染迭代前清除深度缓冲(否则在前一帧的深度信息仍然保留在内存中)

while (!glfwWindowShouldClose(window))
	{
		// input
		// -----
		processInput(window);
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		float timeVary = (float)glfwGetTime();
		glm::mat4 trans;
		// 模型矩阵
		glm::mat4 modelMatrix(1.0f);
		modelMatrix = glm::rotate(modelMatrix, timeVary, glm::vec3(1.0, 1.0f, 1.0f));
		// 生成变换矩阵
		// 移动到(0.5,-0.5)处
		/*trans = glm::rotate(trans, timeVary, glm::vec3(0.0f, 1.0f, 0.0f));
		trans = glm::rotate(trans, timeVary, glm::vec3(0.0f, 0.0f, 1.0f));*/
		//trans = glm::rotate(trans, timeVary, glm::vec3(1.0f, 0.0f, 0.0f));
		//trans = glm::translate(trans,glm::vec3(0.0f,0.0f,0.0f));
		//trans = glm::scale(trans, glm::vec3(0.5f, 0.5f, 0.5f));
		glUniform1f(glGetUniformLocation(shaderItem.ID, "mixNumber"), mixNumber);

		glUniformMatrix4fv(glGetUniformLocation(shaderItem.ID, "model"),1,GL_FALSE,glm::value_ptr(modelMatrix));
		glUniformMatrix4fv(glGetUniformLocation(shaderItem.ID, "view"),1,GL_FALSE,glm::value_ptr(viewMatrix));
		glUniformMatrix4fv(glGetUniformLocation(shaderItem.ID, "projection"),1,GL_FALSE,glm::value_ptr(projectionMatrix));

		//double curTime = glfwGetTime();
		//shaderItem.setFloat("offsetY", 0.3);
		//shaderItem.setFloat("degree",curTime);
		//// draw
		//drawSomgthing();
		//drawMyElement(VAO,textureArr,sizeof(textureArr) / sizeof(*textureArr));
		//shaderItem.use();
		//drawMyElement(VAO,textureArr, sizeof(textureArr) / sizeof(*textureArr),false);
		drawMyElement(VAO,textureArr, sizeof(textureArr) / sizeof(*textureArr),true);
		// -------------------------------------------------------------------------------
		//glm::mat4 trans2;
		//trans2 = glm::mat4(1.0f); // reset it to identity matrix
		//trans2 = glm::translate(trans2, glm::vec3(-0.5f, 0.5f, 0.0f));
		//float scaleAmount = sin(glfwGetTime());
		//trans2 = glm::scale(trans2, glm::vec3(scaleAmount, scaleAmount, scaleAmount));
		//glUniformMatrix4fv(transformLoc, 1, GL_FALSE, &transform[0][0]);
		glfwSwapBuffers(window);
		glfwPollEvents();
	}
	glDeleteProgram(shaderItem.ID);
	glDeleteBuffers(1,&VBO);
	glDeleteVertexArrays(1,&VAO);
	glDeleteBuffers(1,&EBO);
	// glfw: terminate, clearing all previously allocated GLFW resources.
	// 回收占用的内存
	// ------------------------------------------------------------------
	glfwTerminate();
	return 0;
// 绘制矩形
void drawMyElement(uint VAO,uint* textures,uint size,bool is3D) {
	/*for (uint i = 0; i < size; i++) {
		glActiveTexture(GL_TEXTURE + i);
		glBindTexture(GL_TEXTURE_2D,textures[i]);
	}*/
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D,textures[0]);
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D,textures[1]);
	glBindVertexArray(VAO);
	if (!is3D) {
		glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);
	}
	else {
		glDrawArrays(GL_TRIANGLES,0,36);
	}
}
// 渲染3d盒子
void render3dBox() {
	glBindVertexArray(VAO);
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW);

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

需要注意的是属性指针这里偏移量应该是5,激活的分别是0和1

顶点着色器:

#version 330 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec2 aTexCoord;
out vec3 ourColor;
out vec2 texCoord;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main() {
	gl_Position = projection * view * model * vec4(aPos,1.0);
	texCoord = aTexCoord;
}

这里的纹理坐标的location为1了!!!注意 

片段着色器:

#version 330 core
out vec4 FragColor;
in vec3 ourColor;
in vec2 texCoord;
uniform sampler2D texture1;
uniform sampler2D texture2;
uniform float mixNumber;
void main() {
	FragColor = mix(texture(texture1,vec2(texCoord.x,texCoord.y)),texture(texture2,vec2(texCoord.x,texCoord.y)),mixNumber);
}

源码地址:https://github.com/lck898989/openglDemo.git 

猜你喜欢

转载自blog.csdn.net/lck8989/article/details/101380147
今日推荐