|
// leadinmodel.cpp : ???????̨Ӧ?ó??????ڵ㡣
|
|
//
|
|
#include "stdafx.h"
|
|
#pragma once
|
|
// Std. Includes
|
|
#include <string>
|
|
#include <fstream>
|
|
#include <sstream>
|
|
#include <iostream>
|
|
#include <vector>
|
|
#include <assimp/Importer.hpp>
|
|
#include <assimp/scene.h>
|
|
#include <assimp/postprocess.h>
|
|
using namespace std;
|
|
// GL Includes
|
|
#include <GL/glew.h> // Contains all the necessery OpenGL includes
|
|
#include <glm/glm.hpp>
|
|
#include <glm/gtc/matrix_transform.hpp>
|
|
|
|
// ??????Ϣ?ṹ??
|
|
struct Vertex {
|
|
// Position λ??
|
|
glm::vec3 Position;
|
|
// Normal ????
|
|
glm::vec3 Normal;
|
|
// TexCoords ????
|
|
glm::vec2 TexCoords;
|
|
};
|
|
|
|
//??????Ϣ?ṹ??
|
|
struct Texture {
|
|
// ??????id
|
|
GLuint id;
|
|
// ?????????ͣ?????diffuse????????specular????
|
|
string type;
|
|
aiString path;
|
|
};
|
|
|
|
//??????
|
|
class Mesh {
|
|
public:
|
|
/* Mesh Data ???????? */
|
|
// ??????Ϣ
|
|
vector<Vertex> vertices;
|
|
// ????
|
|
vector<GLuint> indices;
|
|
// ????
|
|
vector<Texture> textures;
|
|
|
|
/* Functions */
|
|
// Constructor ???캯??
|
|
Mesh(vector<Vertex> vertices, vector<GLuint> indices, vector<Texture> textures)
|
|
{
|
|
this->vertices = vertices;
|
|
this->indices = indices;
|
|
this->textures = textures;
|
|
|
|
// Now that we have all the required data, set the vertex buffers and its attribute pointers.
|
|
this->setupMesh();
|
|
}
|
|
|
|
// Render the mesh ??Ⱦ
|
|
void Draw(Shader shader)
|
|
{
|
|
// Bind appropriate textures ???ʵ?????
|
|
GLuint diffuseNr = 1;
|
|
GLuint specularNr = 1;
|
|
//????????????????????
|
|
for (GLuint i = 0; i < this->textures.size(); i++)
|
|
{
|
|
glActiveTexture(GL_TEXTURE0 + i); // Active proper texture unit before binding ??֮ǰ??????ʵ?????
|
|
// Retrieve texture number (the N in diffuse_textureN) ????????????
|
|
stringstream ss;
|
|
string number;
|
|
string name = this->textures[i].type;
|
|
//??diffuse??????diffuseNr?Լ?
|
|
if (name == "texture_diffuse")
|
|
ss << diffuseNr++; // Transfer GLuint to stream
|
|
//??specular??????specularNr?Լ?
|
|
else if (name == "texture_specular")
|
|
ss << specularNr++; // Transfer GLuint to stream
|
|
number = ss.str();
|
|
// Now set the sampler to the correct texture unit ???ò?????????ȷ????????Ԫ
|
|
glUniform1i(glGetUniformLocation(shader.Program, (name + number).c_str()), i);
|
|
// And finally bind the texture ??????
|
|
glBindTexture(GL_TEXTURE_2D, this->textures[i].id);
|
|
}
|
|
|
|
// Also set each mesh's shininess property to a default value (if you want you could extend this to another mesh property and possibly change this value)
|
|
glUniform1f(glGetUniformLocation(shader.Program, "material.shininess"), 16.0f);
|
|
|
|
// Draw mesh ??????
|
|
glBindVertexArray(this->VAO);
|
|
glDrawElements(GL_TRIANGLES, this->indices.size(), GL_UNSIGNED_INT, 0);
|
|
glBindVertexArray(0);
|
|
|
|
// Always good practice to set everything back to defaults once configured. ???
|
|
for (GLuint i = 0; i < this->textures.size(); i++)
|
|
{
|
|
glActiveTexture(GL_TEXTURE0 + i);
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
}
|
|
}
|
|
|
|
private:
|
|
/* Render data */
|
|
GLuint VAO, VBO, EBO;
|
|
|
|
/* Functions */
|
|
// Initializes all the buffer objects/arrays ??ʼ??????
|
|
void setupMesh()
|
|
{
|
|
// Create buffers/arrays ??????????
|
|
glGenVertexArrays(1, &this->VAO);
|
|
glGenBuffers(1, &this->VBO);
|
|
glGenBuffers(1, &this->EBO);
|
|
|
|
// ??VAO
|
|
glBindVertexArray(this->VAO);
|
|
// Load data into vertex buffers ??VBO???????ݵ????黺????
|
|
glBindBuffer(GL_ARRAY_BUFFER, this->VBO);
|
|
// A great thing about structs is that their memory layout is sequential for all its items.
|
|
// The effect is that we can simply pass a pointer to the struct and it translates perfectly to a glm::vec3/2 array which
|
|
// again translates to 3/2 floats which translates to a byte array.
|
|
//????????
|
|
glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(Vertex), &this->vertices[0], GL_STATIC_DRAW);
|
|
|
|
//??EBO
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->EBO);
|
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->indices.size() * sizeof(GLuint), &this->indices[0], GL_STATIC_DRAW);
|
|
|
|
// Set the vertex attribute pointers
|
|
// Vertex Positions ????????λ??????
|
|
glEnableVertexAttribArray(0);
|
|
// ????λ??????ָ??
|
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)0);
|
|
// Vertex Normals ???????㷨??????
|
|
glEnableVertexAttribArray(1);
|
|
// ???㷨??????ָ??
|
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, Normal));
|
|
// Vertex Texture Coords ????????????????
|
|
glEnableVertexAttribArray(2);
|
|
// ????????????ָ??
|
|
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, TexCoords));
|
|
|
|
//???VAO
|
|
glBindVertexArray(0);
|
|
}
|
|
};
|