working on Assimp tex-mapping + normal mapping

This commit is contained in:
Hugo Willaume 2019-03-27 12:56:21 +09:00
parent cfb698e6c8
commit 34d4ba33e2
16 changed files with 100038 additions and 58 deletions

View File

@ -187,6 +187,8 @@
<None Include="fog.frag" />
<None Include="fog.vert" />
<None Include="base_light.vert" />
<None Include="nmap.frag" />
<None Include="nmap.vert" />
<None Include="spotlight.frag" />
<None Include="spotlight.vert" />
<None Include="tex_base_light.frag" />

View File

@ -172,6 +172,12 @@
<None Include="tex_spotlight.frag">
<Filter>Shaders</Filter>
</None>
<None Include="nmap.vert">
<Filter>Shaders</Filter>
</None>
<None Include="nmap.frag">
<Filter>Shaders</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Image Include="brick1.jpg">

View File

@ -103,6 +103,8 @@ Mesh::MeshEntry::MeshEntry(aiMesh *mesh, const aiScene* scene, Mesh * m, std::st
vbo[NORMAL_BUFFER] = NULL;
vbo[COLOR_BUFFER] = NULL;
vbo[INDEX_BUFFER] = NULL;
vbo[TANGENTS_BUFFER] = NULL;
vbo[BITTANGENTS_BUFFER] = NULL;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
@ -180,6 +182,37 @@ Mesh::MeshEntry::MeshEntry(aiMesh *mesh, const aiScene* scene, Mesh * m, std::st
delete[] indices;
}
if (mesh->HasTangentsAndBitangents()) {
float *tangents = new float[mesh->mNumVertices * 3];
float *bittangents = new float[mesh->mNumVertices * 3];
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
tangents[i * 3] = mesh->mTangents[i].x;
bittangents[i * 3] = mesh->mBitangents[i].x;
tangents[i * 3 + 1] = mesh->mTangents[i].y;
bittangents[i * 3 + 1] = mesh->mBitangents[i].y;
tangents[i * 3 + 2] = mesh->mTangents[i].z;
bittangents[i * 3 + 2] = mesh->mBitangents[i].z;
}
glGenBuffers(1, &vbo[TANGENTS_BUFFER]);
glBindBuffer(GL_ARRAY_BUFFER, vbo[TANGENTS_BUFFER]);
glBufferData(GL_ARRAY_BUFFER, 3 * mesh->mNumVertices * sizeof(GLfloat), tangents, GL_STATIC_DRAW);
glVertexAttribPointer(TANGENTS_BUFFER, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(TANGENTS_BUFFER);
glGenBuffers(1, &vbo[BITTANGENTS_BUFFER]);
glBindBuffer(GL_ARRAY_BUFFER, vbo[BITTANGENTS_BUFFER]);
glBufferData(GL_ARRAY_BUFFER, 3 * mesh->mNumVertices * sizeof(GLfloat), bittangents, GL_STATIC_DRAW);
glVertexAttribPointer(BITTANGENTS_BUFFER, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(BITTANGENTS_BUFFER);
delete[] tangents;
delete[] bittangents;
}
if (mesh->mMaterialIndex >= 0) {
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
@ -225,18 +258,6 @@ Mesh::MeshEntry::~MeshEntry() {
**/
void Mesh::MeshEntry::render(SceneContext &ctx, Shader *shd) {
glEnable(GL_TEXTURE_2D);
for (GLuint i = 0; i < parent->textures.size(); i++)
{
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(GL_TEXTURE_2D, parent->textures[i].tex_ref);
shd->applyTextureMaterial(parent->textures[i]);
shd->addUniform("tex[" + std::to_string(i) + "]", (int)i);
}
if (parent->textures.size() > 0)
shd->addUniform("TexCount", (int)parent->textures.size());
glBindVertexArray(vao);
if (renderType == NO_INDEX)
{
@ -249,7 +270,6 @@ void Mesh::MeshEntry::render(SceneContext &ctx, Shader *shd) {
glDrawElements(GL_TRIANGLES, size / sizeof(unsigned int), GL_UNSIGNED_INT, NULL);
}
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
}
/**
@ -265,7 +285,9 @@ Mesh::Mesh(const char *filename, Shader *sh)
dirname.resize(fullname.find_last_of('/'));
Assimp::Importer importer; //aiProcessPreset_TargetRealtime_Fast
const aiScene* scene = importer.ReadFile(fullname.c_str(), aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_GenSmoothNormals | aiProcess_OptimizeMeshes);
const aiScene* scene = importer.ReadFile(fullname.c_str(),
aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_GenSmoothNormals | aiProcess_OptimizeMeshes
| aiProcess_CalcTangentSpace);
// Check for errors
if (!scene || scene->mFlags == AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) // if is Not Zero
@ -340,9 +362,40 @@ void Mesh::disableCulling()
glDisable(GL_CULL_FACE);
}
void Mesh::textureUnbinding()
{
for (GLuint i = 0; i < textures.size(); i++)
{
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(GL_TEXTURE_2D, 0);
}
}
void Mesh::textureBinding(Shader *shd)
{
int nmap_counter = 0;
for (GLuint i = 0; i < textures.size(); i++)
{
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(GL_TEXTURE_2D, textures[i].tex_ref);
//shd->applyTextureMaterial(parent->textures[i]);
if (textures[i].isNmap)
{
shd->addUniform("nmap", (int)i);
nmap_counter++;
}
else
shd->addUniform("tex[" + std::to_string(i) + "]", (int)i - nmap_counter);
}
if (textures.size() > 0)
shd->addUniform("TexCount", (int)textures.size() - nmap_counter);
}
void Mesh::draw(SceneContext ctx) {
shader->enable();
textureBinding(shader);
enableCulling();
for (unsigned int i = 0; i < meshEntries.size(); ++i) {
@ -393,6 +446,7 @@ void Mesh::draw(SceneContext ctx) {
model.glPopMatrix();
}
disableCulling();
textureUnbinding();
shader->disable();
}

View File

@ -39,10 +39,11 @@ class Mesh
public:
struct MeshEntry {
enum BUFFERS {
VERTEX_BUFFER, NORMAL_BUFFER, COLOR_BUFFER, TEXCOORD_BUFFER, INDEX_BUFFER
VERTEX_BUFFER, NORMAL_BUFFER, COLOR_BUFFER, TEXCOORD_BUFFER, INDEX_BUFFER,
TANGENTS_BUFFER, BITTANGENTS_BUFFER
};
GLuint vao;
GLuint vbo[5];
GLuint vbo[7];
unsigned int elementCount;
RenderType renderType;
@ -52,7 +53,6 @@ public:
aiColor3D dcolor;
aiColor3D acolor;
aiColor3D scolor;
std::vector<Texture> textures;
float shininessStrength;
MeshEntry(aiMesh *mesh, const aiScene* scene, Mesh * m, std::string dirname);
@ -73,7 +73,9 @@ private:
std::vector<std::pair<glm::vec4, Transformation>> _transformations;
void enableCulling();
void textureBinding(Shader *shd);
void disableCulling();
void textureUnbinding();
public:
Model model;
CullFace cullMode = NONE;

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 872 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 694 KiB

View File

@ -65,6 +65,9 @@ void MyGlWindow::textureSetup()
_scnctx.textures.emplace("BrickTex", Texture("brick1.jpg"));
_scnctx.textures.emplace("MossTex", Texture("moss.png"));
_scnctx.textures.emplace("EarthTex", Texture("earth.jpg"));
_scnctx.textures.emplace("OgreTex", Texture("Models/ogre/ogre_diffuse.png"));
_scnctx.textures.emplace("OgreNmap", Texture("Models/ogre/ogre_normalmap.png"));
_scnctx.textures["OgreNmap"].isNmap = true;
}
void MyGlWindow::shaderSetup()
@ -76,6 +79,7 @@ void MyGlWindow::shaderSetup()
shaders["Fog"] = new Shader("fog.vert", "fog.frag");
shaders["TexBaseLight"] = new Shader("tex_base_light.vert", "tex_base_light.frag");
shaders["TexNmapLight"] = new Shader("nmap.vert", "nmap.frag");
shaders["SpotLight"] = new Shader("spotlight.vert", "spotlight.frag");
shaders["SpotLight"]->light_type = Light::LightType::SPOT;
@ -109,27 +113,37 @@ void MyGlWindow::lightSetup()
void MyGlWindow::setup()
{
glEnable(GL_DEPTH_TEST);
glEnable(GL_DEPTH_BUFFER);
glEnable(GL_TEXTURE_2D);
textureSetup();
shaderSetup();
lightSetup();
/*
meshes.emplace("Buddha", new Mesh("buddha.obj", shaders["BaseLight"]));
meshes["Buddha"]->addTranslation(glm::vec4(-4, 3, -4, 0));
meshes["Buddha"]->addScaling(glm::vec4(4, 4, 4, 0));
meshes["Buddha"]->addRotation(glm::vec4(0, 1, 0, 180));
//meshes.emplace("Ogre", new Mesh("ogre/ogre.obj", shaders["NmapBaseLight"]));
//meshes["Ogre"]->addTranslation(glm::vec4(0, 1, 0, 0));
//meshes["Ogre"]->assignTexture(_scnctx.textures["OgreTex"]);
//meshes["Ogre"]->assignTexture(_scnctx.textures["OgreNmap"]);
//meshes["Buddha"]->addScaling(glm::vec4(4, 4, 4, 0));
//meshes["Buddha"]->addRotation(glm::vec4(0, 1, 0, 180));
Dataset moddata;
moddata.simpleCube();
meshes.emplace("Cube", new Mesh(moddata, shaders["TexBaseLight"]));
meshes["Cube"]->assignTexture(_scnctx.textures["BrickTex"]);
meshes["Cube"]->assignTexture(_scnctx.textures["MossTex"]);
meshes["Cube"]->addTranslation(glm::vec4(4, 3, -4, 0));
//meshes.emplace("Buddha", new Mesh("buddha.obj", shaders["BaseLight"]));
//meshes["Buddha"]->addTranslation(glm::vec4(-4, 3, -4, 0));
//meshes["Buddha"]->addScaling(glm::vec4(4, 4, 4, 0));
//meshes["Buddha"]->addRotation(glm::vec4(0, 1, 0, 180));
meshes.emplace("Mountain", new Mesh("mountain/mount.blend1.obj", shaders["TexBaseLight"])); */
//Dataset moddata;
//moddata.simpleCube();
//meshes.emplace("Cube", new Mesh(moddata, shaders["TexBaseLight"]));
//meshes["Cube"]->assignTexture(_scnctx.textures["BrickTex"]);
//meshes["Cube"]->assignTexture(_scnctx.textures["MossTex"]);
//meshes["Cube"]->addTranslation(glm::vec4(4, 3, -4, 0));
//meshes.emplace("Mountain", new Mesh("mountain/mount.blend1.obj", shaders["TexBaseLight"]));
meshes.emplace("Sponza", new Mesh("sponza/sponza.obj", shaders["TexBaseLight"]));
meshes["Sponza"]->addScaling(glm::vec4(0.2, 0.2, 0.2, 1));
meshes["Sponza"]->cullMode = CullFace::BACK;
//meshes["Sponza"]->addScaling(glm::vec4(0.2, 0.2, 0.2, 1));
//meshes["Sponza"]->cullMode = CullFace::BACK;
@ -160,15 +174,13 @@ void MyGlWindow::draw()
{
glClearColor(_bgColor[0], _bgColor[1], _bgColor[2], 1);
glViewport(0, 0, m_width, m_height);
glEnable(GL_DEPTH_TEST);
glEnable(GL_DEPTH_BUFFER);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::vec3 eye(viewer.getViewPoint().x, viewer.getViewPoint().y, viewer.getViewPoint().z);
glm::vec3 look(viewer.getViewCenter().x, viewer.getViewCenter().y, viewer.getViewCenter().z);
glm::vec3 up(viewer.getUpVector().x, viewer.getUpVector().y, viewer.getUpVector().z);
glm::mat4 view = lookAt(eye, look, up); //Calculate view matrix from parameters of m_viewer
glm::mat4 projection = perspective(45.0f, (float)m_width / (float)m_height, 0.1f, 500.0f);
glm::mat4 projection = perspective(45.0f, (float)m_width / (float)m_height, 0.1f, 2000.0f);
_scnctx.viewMatrix = view;
_scnctx.projectionMatrix = projection;

View File

@ -0,0 +1,2 @@
#pragma once
#include "Texture.h"

View File

@ -5,7 +5,6 @@
#include <glm/vec3.hpp>
#include "Texture.h"
struct SceneContext
{
std::map<std::string, Light> lights;

View File

@ -17,6 +17,7 @@ class Texture
public:
Material mat;
GLuint tex_ref;
bool isNmap = false;
Texture(std::string file_name);
Texture(const Texture &other);

63
BaseGLProject/nmap.frag Normal file
View File

@ -0,0 +1,63 @@
#version 440
in vec3 f_color;
out vec4 FragColors;
uniform vec3 Kd;
uniform vec3 Ka;
uniform vec3 Ks;
uniform float Shininess;
struct LightInfo {
vec4 Position;
vec3 Intensity;
};
uniform LightInfo Light[64];
uniform int LightCount;
in vec3 fNormal;
in vec3 pos;
in mat3x3 tangentMatrix;
in vec2 texCoord;
uniform int TexCount;
uniform sampler2D tex[32];
uniform sampler2D nmap;
void main()
{
vec3 finalColor;
vec3 diffuse_sum;
vec3 specular_sum;
vec3 ambient;
ambient = Ka * Light[0].Intensity;
for (int i=0; i<LightCount; i++)
{
vec3 L = normalize(tangentMatrix * (Light[i].Position.xyz - pos));
vec3 N = texture(nmap, texCoord).xyz;
vec3 V = normalize(tangentMatrix * (-pos));
//vec3 R = normalize(reflect(-L, N));
vec3 H = normalize(V + L);
vec3 diffuse = Kd * Light[i].Intensity * max(dot(L, N), 0.0);
vec3 specular = Ks * Light[i].Intensity * pow(max(dot(H, N), 0.0), Shininess);
diffuse_sum += diffuse;
specular_sum += specular;
}
vec4 texColor = texture(tex[0], texCoord);
for (int i=1; i < TexCount; i++)
{
vec4 new_tex = texture(tex[i], texCoord);
texColor = mix(new_tex, texColor, new_tex.a);
}
FragColors = (vec4(diffuse_sum + ambient, 1) * texColor + vec4(specular_sum, 1.0));
}

34
BaseGLProject/nmap.vert Normal file
View File

@ -0,0 +1,34 @@
#version 440
layout(location=0) in vec3 coord3d;
layout(location=1) in vec3 v_normal;
layout(location=2) in vec3 v_color;
layout(location=3) in vec2 v_texmap;
layout(location=4) in vec3 v_tangent;
layout(location=5) in vec3 v_bittangent;
uniform mat4 mvp;
uniform mat3 NormalMatrix;
uniform mat4 ModelViewMatrix;
out vec3 fNormal;
out mat3x3 tangentMatrix;
out vec3 pos;
out vec2 texCoord;
void main(void)
{
vec3 fBittangent = normalize(NormalMatrix * v_bittangent);
vec3 fTangent = normalize(NormalMatrix * v_tangent);
fNormal = normalize(NormalMatrix * v_normal);
tangentMatrix = mat3(fTangent.x, fNormal.x, fBittangent.x,
fTangent.y, fNormal.y, fBittangent.y,
fTangent.z, fNormal.z, fBittangent.z);
pos = (ModelViewMatrix * vec4(coord3d, 1.0)).xyz;
texCoord = v_texmap;
gl_Position = mvp * vec4(coord3d, 1.0f);
}

View File

@ -31,24 +31,18 @@ void main()
vec3 diffuse_sum;
vec3 specular_sum;
vec3 ambient;
float D;
float attenuation;
D = distance(Light[0].Position.xyz, pos);
attenuation = 1 / (1 + 0.01 * D + 0.001 * D * D);
ambient = Ka * Light[0].Intensity * attenuation;
ambient = Ka * Light[0].Intensity;
for (int i=0; i<LightCount; i++)
{
D = distance(Light[i].Position.xyz, pos);
attenuation = 1 / (1 + 0.01 * D + 0.001 * D * D);
vec3 L = normalize(Light[i].Position.xyz - pos);
vec3 N = fNormal;
vec3 V = normalize(-pos);
//vec3 R = normalize(reflect(-L, N));
vec3 H = normalize(V + L);
vec3 diffuse = Kd * Light[i].Intensity * max(dot(L, N), 0.0) * attenuation;
vec3 specular = Ks * Light[i].Intensity * pow(max(dot(H, N), 0.0), Shininess) * attenuation;
vec3 diffuse = Kd * Light[i].Intensity * max(dot(L, N), 0.0);
vec3 specular = Ks * Light[i].Intensity * pow(max(dot(H, N), 0.0), Shininess);
diffuse_sum += diffuse;
specular_sum += specular;
}