使用assimp加载,
引用动态链接库dll主要有两种方法:
法1:配置属性->调试->环境:输入path=包含dll文件的文件夹路径,
【注意】path(空格)=路径、path=(空格)路径、path(空格)=(空格)路径等写法都会导致dll引用失败。
法2:将dll文件拷贝到生成的.exe所在的文件夹中
代码:
// Std. Includes
#include
// GLEW
#define GLEW_STATIC
#include
// GLFW
#include
// GL includes
#include "../../../common/Shader.h"
#include "../../../common/Camera.h"
#include "../../../common/Model.h"
// GLM Mathemtics
#include
#include
#include
// Other Libs
#include
using namespace myshader;
using namespace mycamera;
//去掉控制台
#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
// Properties
GLuint screenWidth = 800, screenHeight = 600;
//按键回调函数
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
//鼠标回调函数
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
//滚轮回调函数
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
//处理按键
void do_movement();
// Camera
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()
{
// Init GLFW
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* window = glfwCreateWindow(screenWidth, screenHeight, "Load Model", nullptr, nullptr); // Windowed
glfwMakeContextCurrent(window);
//窗口回调函数
glfwSetKeyCallback(window, key_callback);
glfwSetCursorPosCallback(window, mouse_callback);
glfwSetScrollCallback(window, scroll_callback);
// 隐藏鼠标
//glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
// 将其设置为true,以便GLEW知道使用现代方法来检索函数指针和扩展
glewExperimental = GL_TRUE;
glewInit();
// Define the viewport dimensions
glViewport(0, 0, screenWidth, screenHeight);
// 开启深度缓冲
glEnable(GL_DEPTH_TEST);
//定义顶点数组
GLfloat vertices[] = {
-0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
-0.5f, 0.5f, -0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, -0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, -0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
-0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
-0.5f, -0.5f, 0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, -0.5f
};
//光照相关
GLuint lightVAO , VBO;
glGenVertexArrays(1, &lightVAO);
glGenBuffers(1, &VBO);
glBindVertexArray(lightVAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
// 设置灯立方体的顶点属性指针(仅设置灯的顶点数据)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glBindVertexArray(0);
// 编译模型和光照着色器
Shader shader("shaders/3.0/model_loading.vs", "shaders/3.0/model_loading.fs");
Shader lightShader("shaders/2.2/light.vs", "shaders/2.2/light.fs");
// 加载模型
Model ourModel("models/Nanosuit/nanosuit.obj");
// 线框模式
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// 游戏循环
while (!glfwWindowShouldClose(window))
{
// Set frame time
GLfloat currentFrame = glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
//检测键盘 鼠标事件
glfwPollEvents();
do_movement();
//清空颜色和深度缓冲
glClearColor(0.05f, 0.05f, 0.05f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
shader.Use();
//点光源位置
glm::vec3 lightPos[2];
lightPos[0] = glm::vec3(1.0f + sin(glfwGetTime()) * 2.0f, sin(glfwGetTime() / 2.0f) * 1.0f, 1.9f);
lightPos[1] = glm::vec3(1.0f - sin(glfwGetTime()) * 2.0f, -sin(glfwGetTime() / 2.0f) * 1.0f, -1.9f);
//点光源颜色
glm::vec3 lightColor[2];
lightColor[0] = glm::vec3(sin(glfwGetTime()), cos(glfwGetTime()), 1 - (sin(glfwGetTime()) + cos(glfwGetTime())));
lightColor[1] = glm::vec3(cos(glfwGetTime()), sin(glfwGetTime()), (sin(glfwGetTime()) + cos(glfwGetTime())));
// 点光源1
glUniform3f(glGetUniformLocation(shader.Program, "pointLights[0].position"), lightPos[0].x, lightPos[0].y, lightPos[0].z);
glUniform3f(glGetUniformLocation(shader.Program, "pointLights[0].ambient"), 0.05f, 0.05f, 0.05f);
glUniform3f(glGetUniformLocation(shader.Program, "pointLights[0].diffuse"), 0.8f, 0.8f, 0.8f);
glUniform3f(glGetUniformLocation(shader.Program, "pointLights[0].specular"), lightColor[0].r, lightColor[0].g, lightColor[0].b);
glUniform1f(glGetUniformLocation(shader.Program, "pointLights[0].constant"), 1.0f);
glUniform1f(glGetUniformLocation(shader.Program, "pointLights[0].linear"), 0.09);
glUniform1f(glGetUniformLocation(shader.Program, "pointLights[0].quadratic"), 0.032);
// 点光源2
glUniform3f(glGetUniformLocation(shader.Program, "pointLights[1].position"), lightPos[1].x, lightPos[1].y, lightPos[1].z);
glUniform3f(glGetUniformLocation(shader.Program, "pointLights[1].ambient"), 0.05f, 0.05f, 0.05f);
glUniform3f(glGetUniformLocation(shader.Program, "pointLights[1].diffuse"), 0.8f, 0.8f, 0.8f);
glUniform3f(glGetUniformLocation(shader.Program, "pointLights[1].specular"), lightColor[0].r, lightColor[0].g, lightColor[0].b);
glUniform1f(glGetUniformLocation(shader.Program, "pointLights[1].constant"), 1.0f);
glUniform1f(glGetUniformLocation(shader.Program, "pointLights[1].linear"), 0.09);
glUniform1f(glGetUniformLocation(shader.Program, "pointLights[1].quadratic"), 0.032);
//获取在shader里的位置
GLint viewPosLoc = glGetUniformLocation(shader.Program, "viewPos");
glUniform3f(viewPosLoc, camera.Position.x, camera.Position.y, camera.Position.z);
// MVP
glm::mat4 projection = glm::perspective(camera.Zoom, (float)screenWidth / (float)screenHeight, 0.1f, 100.0f);
glm::mat4 view = camera.GetViewMatrix();
glUniformMatrix4fv(glGetUniformLocation(shader.Program, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
glUniformMatrix4fv(glGetUniformLocation(shader.Program, "view"), 1, GL_FALSE, glm::value_ptr(view));
// 渲染模型
glm::mat4 model;
model = glm::translate(model, glm::vec3(0.0f, -1.75f, 0.0f)); // Translate it down a bit so it's at the center of the scene
model = glm::scale(model, glm::vec3(0.2f, 0.2f, 0.2f)); // It's a bit too big for our scene, so scale it down
glUniformMatrix4fv(glGetUniformLocation(shader.Program, "model"), 1, GL_FALSE, glm::value_ptr(model));
ourModel.Draw(shader);
//渲染光源
lightShader.Use();
for (int i = 0; i < 2; i++)
{
model = glm::mat4();
model = glm::translate(model, lightPos[i]);
model = glm::scale(model, glm::vec3(0.2f));
GLint modeLoc = glGetUniformLocation(lightShader.Program, "model");
GLint viewLoc = glGetUniformLocation(lightShader.Program, "view");
GLint projectionLoc = glGetUniformLocation(lightShader.Program, "projection");
GLuint lightColorLoc = glGetUniformLocation(lightShader.Program, "lightColor");
glUniform3f(lightColorLoc, lightColor[i].x, lightColor[i].y, lightColor[i].z);
glUniformMatrix4fv(modeLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));
glBindVertexArray(lightVAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
}
// 双缓冲
glfwSwapBuffers(window);
}
glfwTerminate();
return 0;
}
#pragma region "User input"
// Moves/alters the camera positions based on user input
void do_movement()
{
// Camera controls
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);
}
// Is called whenever a key is pressed/released via GLFW
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);
}
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
camera.ProcessMouseScroll(yoffset);
}
#pragma endregion
模型顶点Shader:
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec2 texCoords;
out vec2 TexCoords;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
out vec3 Normal;
out vec3 FragPos;
void main()
{
gl_Position = projection * view * model * vec4(position, 1.0f);
TexCoords = texCoords;
FragPos = vec3(model * vec4(position, 1.0f));
Normal = mat3(transpose(inverse(model))) * normal;
}
模型片段Shader:
#version 330 core
struct PointLight {
vec3 position;
float constant;
float linear;
float quadratic;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
struct Material {
sampler2D diffuse;
sampler2D specular;
float shininess;
};
in vec3 FragPos;
in vec3 Normal;
in vec2 TexCoords;
uniform vec3 viewPos;
out vec4 color;
uniform sampler2D texture_diffuse1;
#define NR_POINT_LIGHTS 2
uniform PointLight pointLights[NR_POINT_LIGHTS];
uniform Material material;
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir);
void main()
{
color = vec4(texture(texture_diffuse1, TexCoords));
vec3 norm = normalize(Normal);
vec3 viewDir = normalize(viewPos - FragPos);
vec3 lightColor = vec3(0,0,0);
for(int i = 0; i < NR_POINT_LIGHTS; i++)
lightColor += CalcPointLight(pointLights[i], norm, FragPos, viewDir);
color = vec4(lightColor ,1.0);
}
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
{
vec3 lightDir = normalize(light.position - fragPos);
// Diffuse shading
float diff = max(dot(normal, lightDir), 0.0);
// Specular shading
vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
// Attenuation
float distance = length(light.position - fragPos);
float attenuation = 1.0f / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
// Combine results
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
ambient *= attenuation;
diffuse *= attenuation;
specular *= attenuation;
return (ambient + diffuse + specular);
}
光源顶点Shader:
#version 330 core
uniform vec3 lightColor;
out vec4 color;
void main()
{
color = vec4(lightColor,1.0);
}
光源片段Shader:
#version 330 core
layout (location = 0) in vec3 position;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(position, 1.0f);
}
效果:
参考文章:https://learnopengl-cn.readthedocs.io/zh/latest/03%20Model%20Loading/03%20Model/