首先是顶点数组需要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);
}