diff --git a/BaseGLProject/BaseGLProject.vcxproj b/BaseGLProject/BaseGLProject.vcxproj index 97f3ed1..491ce96 100644 --- a/BaseGLProject/BaseGLProject.vcxproj +++ b/BaseGLProject/BaseGLProject.vcxproj @@ -158,6 +158,7 @@ + @@ -179,6 +180,7 @@ + @@ -210,6 +212,7 @@ + diff --git a/BaseGLProject/BaseGLProject.vcxproj.filters b/BaseGLProject/BaseGLProject.vcxproj.filters index 422e905..4f740ae 100644 --- a/BaseGLProject/BaseGLProject.vcxproj.filters +++ b/BaseGLProject/BaseGLProject.vcxproj.filters @@ -63,6 +63,9 @@ Models + + Source Files + @@ -122,6 +125,9 @@ imgui + + Header Files + @@ -168,5 +174,8 @@ Resource Files + + Resource Files + \ No newline at end of file diff --git a/BaseGLProject/Dataset.cpp b/BaseGLProject/Dataset.cpp index db9c2c8..226e27d 100644 --- a/BaseGLProject/Dataset.cpp +++ b/BaseGLProject/Dataset.cpp @@ -4,7 +4,7 @@ void Dataset::sphere(float radius, GLuint slices, GLuint stacks) { clear(); - // Generate vertexes and normals + // Generate vertexes, normals and texture mapping GLfloat theta, phi; GLfloat thetaFac = glm::two_pi() / slices; GLfloat phiFac = glm::pi() / stacks; @@ -21,6 +21,8 @@ void Dataset::sphere(float radius, GLuint slices, GLuint stacks) nz = cosf(phi); vertices.emplace_back(radius * nx, radius * ny, radius * nz); normals.emplace_back(nx, ny, nz); + + tex_mapping.emplace_back(s, t); idx++; } } @@ -65,18 +67,18 @@ void Dataset::simpleCube() { 1.0, 1.0, -1.0 },{ -1.0, 1.0, -1.0 },{ -1.0, 1.0, 1.0 } }; tex_mapping = { - { 0.0f, 0.0f },{ 1.0f, 0.0f },{ 1.0f, 1.0f }, // one triangle - { 0.0f, 0.0f },{ 1.0f, 1.0f },{ 0.0f, 1.0f }, //the other triangle + { 0.0f, 0.0f },{ 1.0f, 0.0f },{ 1.0f, 1.0f }, // one triangle + { 1.0f, 1.0f },{ 0.0f, 1.0f },{ 0.0f, 0.0f }, //the other triangle { 0.0f, 0.0f },{ 1.0f, 0.0f },{ 1.0f, 1.0f }, // one triangle - { 0.0f, 0.0f },{ 1.0f, 1.0f },{ 0.0f, 1.0f }, //the other triangle + { 1.0f, 1.0f },{ 0.0f, 1.0f },{ 0.0f, 0.0f }, //the other triangle { 0.0f, 0.0f },{ 1.0f, 0.0f },{ 1.0f, 1.0f }, // one triangle - { 0.0f, 0.0f },{ 1.0f, 1.0f },{ 0.0f, 1.0f }, //the other triangle + { 1.0f, 1.0f },{ 0.0f, 1.0f },{ 0.0f, 0.0f }, //the other triangle { 0.0f, 0.0f },{ 1.0f, 0.0f },{ 1.0f, 1.0f }, // one triangle - { 0.0f, 0.0f },{ 1.0f, 1.0f },{ 0.0f, 1.0f }, //the other triangle + { 1.0f, 1.0f },{ 0.0f, 1.0f },{ 0.0f, 0.0f }, //the other triangle { 0.0f, 0.0f },{ 1.0f, 0.0f },{ 1.0f, 1.0f }, // one triangle - { 0.0f, 0.0f },{ 1.0f, 1.0f },{ 0.0f, 1.0f }, //the other triangle + { 1.0f, 1.0f },{ 0.0f, 1.0f },{ 0.0f, 0.0f }, //the other triangle { 0.0f, 0.0f },{ 1.0f, 0.0f },{ 1.0f, 1.0f }, // one triangle - { 0.0f, 0.0f },{ 1.0f, 1.0f },{ 0.0f, 1.0f }, //the other triangle + { 1.0f, 1.0f },{ 0.0f, 1.0f },{ 0.0f, 0.0f }, //the other triangle }; colors = { diff --git a/BaseGLProject/Models/Mesh.cpp b/BaseGLProject/Models/Mesh.cpp index 419c20c..95082e2 100644 --- a/BaseGLProject/Models/Mesh.cpp +++ b/BaseGLProject/Models/Mesh.cpp @@ -226,9 +226,19 @@ Mesh::MeshEntry::~MeshEntry() { /** * Renders this MeshEntry **/ -void Mesh::MeshEntry::render(SceneContext ctx) { +void Mesh::MeshEntry::render(SceneContext &ctx, Shader *shd) { - glBindTexture(GL_TEXTURE_2D, ctx.textures); + glEnable(GL_TEXTURE_2D); + + for (GLuint i = 0; i < shd->textures.size(); i++) + { + glActiveTexture(GL_TEXTURE0 + i); + glBindTexture(GL_TEXTURE_2D, shd->textures[i].tex_ref); + shd->addUniform("tex[" + std::to_string(i) + "]", (int)i); + } + if (shd->textures.size() > 0) + shd->addUniform("TexCount", (int)shd->textures.size()); + glBindVertexArray(vao); if (renderType == NO_INDEX) { @@ -353,7 +363,7 @@ void Mesh::draw(SceneContext ctx) { shader->setUniforms(ctx); - meshEntries.at(i)->render(ctx); + meshEntries.at(i)->render(ctx, shader); model.glPopMatrix(); } disableCulling(); diff --git a/BaseGLProject/Models/Mesh.h b/BaseGLProject/Models/Mesh.h index e9815ff..4520a8e 100644 --- a/BaseGLProject/Models/Mesh.h +++ b/BaseGLProject/Models/Mesh.h @@ -58,7 +58,7 @@ public: MeshEntry(Dataset &set, Mesh *m); ~MeshEntry(); Mesh * parent; - void render(SceneContext ctx); + void render(SceneContext &ctx, Shader * shd); }; public: diff --git a/BaseGLProject/MyGLWindow.cpp b/BaseGLProject/MyGLWindow.cpp index f12578c..382f354 100644 --- a/BaseGLProject/MyGLWindow.cpp +++ b/BaseGLProject/MyGLWindow.cpp @@ -57,24 +57,14 @@ void MyGlWindow::setBgColor(float bgColor[3]) void MyGlWindow::textureSetup() { - glActiveTexture(GL_TEXTURE0); - glGenTextures(1, &_scnctx.textures); //tex_2d is a member variable - glBindTexture(GL_TEXTURE_2D, _scnctx.textures); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); - int width, height, channel; - unsigned char * image = stbi_load("brick1.jpg", &width, &height, &channel, 0); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, - GL_UNSIGNED_BYTE, image); - glGenerateMipmap(GL_TEXTURE_2D); - - stbi_image_free(image); - glBindTexture(GL_TEXTURE_2D, 0); + _scnctx.textures.emplace("BrickTex", Texture("brick1.jpg", GL_RGB)); + _scnctx.textures.emplace("MossTex", Texture(std::string("moss.png"), GL_RGBA)); + _scnctx.textures.emplace("EarthTex", Texture("earth.jpg", GL_RGB)); } void MyGlWindow::shaderSetup() @@ -85,8 +75,12 @@ void MyGlWindow::shaderSetup() shaders["BaseLight"] = new Shader("base_light.vert", "base_light.frag"); shaders["Fog"] = new Shader("fog.vert", "fog.frag"); - shaders["TexBaseLight"] = new Shader("tex_base_light.vert", "tex_base_light.frag"); - shaders["TexBaseLight"]->addUniform("tex1", 0); + shaders["BrickBaseLight"] = new Shader("tex_base_light.vert", "tex_base_light.frag"); + shaders["BrickBaseLight"]->assignTexture(_scnctx.textures["BrickTex"]); + shaders["BrickBaseLight"]->assignTexture(_scnctx.textures["MossTex"]); + + shaders["EarthBaseLight"] = new Shader("tex_base_light.vert", "tex_base_light.frag"); + shaders["EarthBaseLight"]->assignTexture(_scnctx.textures["EarthTex"]); shaders["Silhouette"] = new Shader("silhouette.vert", "silhouette.frag"); shaders["Silhouette"]->uniformFlags = ShaderFlags::MVP_FLAG; @@ -119,25 +113,25 @@ void MyGlWindow::setup() lightSetup(); Dataset moddata; - moddata.checkeredFloor(20, 20, glm::vec3(0.1, 0.1, 0.1), glm::vec3(0.7, 0.7, 0.7)); - meshes.push_back(new Mesh(moddata, shaders["Simple"])); - meshes.back()->addTranslation(glm::vec4(0, -0.05, 0, 1)); - meshes.back()->cullMode = BACK; + moddata.checkeredFloor(20, 20, glm::vec3(0.1, 0.1, 0.1), glm::vec3(0.7, 0.7, 0.7)); + meshes.emplace("Floor", new Mesh(moddata, shaders["Simple"])); + meshes["Floor"]->addTranslation(glm::vec4(0, -0.05, 0, 1)); + meshes["Floor"]->cullMode = BACK; moddata.simpleCube(); - meshes.push_back(new Mesh(moddata, shaders["TexBaseLight"])); - meshes.back()->addTranslation(glm::vec4(0, 1, 0, 1)); + meshes.emplace("Cube", new Mesh(moddata, shaders["BrickBaseLight"])); + meshes["Cube"]->addTranslation(glm::vec4(0, 1, 0, 1)); moddata.sphere(1, 100, 100); - meshes.push_back(new Mesh(moddata, shaders["BaseLight"])); - meshes.back()->addTranslation(glm::vec4(-5, 1, -3, 1)); + meshes.emplace("Sphere", new Mesh(moddata, shaders["EarthBaseLight"])); + meshes["Sphere"]->addTranslation(glm::vec4(-5, 1, -3, 1)); - meshes.push_back(new Mesh("teapot.obj", shaders["Silhouette"])); - meshes.back()->addTranslation(glm::vec4(5, 0 ,3, 1)); - meshes.back()->cullMode = FRONT; - meshes.push_back(new Mesh("teapot.obj", shaders["Toon"])); - meshes.back()->addTranslation(glm::vec4(5, 0, 3, 1)); - meshes.back()->cullMode = BACK; + meshes.emplace("TeapotSilhouette", new Mesh("teapot.obj", shaders["Silhouette"])); + meshes["TeapotSilhouette"]->addTranslation(glm::vec4(5, 0 ,3, 1)); + meshes["TeapotSilhouette"]->cullMode = FRONT; + meshes.emplace("Teapot", new Mesh("teapot.obj", shaders["Toon"])); + meshes["Teapot"]->addTranslation(glm::vec4(5, 0, 3, 1)); + meshes["Teapot"]->cullMode = BACK; } @@ -158,7 +152,7 @@ void MyGlWindow::draw() _scnctx.viewMatrix = view; _scnctx.projectionMatrix = projection; for (auto it = meshes.begin(); it != meshes.end(); it++) - (*it)->draw(_scnctx); + (*it).second->draw(_scnctx); } void MyGlWindow::resize(int w, int h) diff --git a/BaseGLProject/MyGLWindow.h b/BaseGLProject/MyGLWindow.h index dd0de53..7d5d7f8 100644 --- a/BaseGLProject/MyGLWindow.h +++ b/BaseGLProject/MyGLWindow.h @@ -26,7 +26,7 @@ public: void setBgColor(float bgColor[3]); std::map shaders; - std::vector meshes; + std::map meshes; void resize(int w, int h); Viewer viewer; diff --git a/BaseGLProject/SceneContext.h b/BaseGLProject/SceneContext.h index d2e22b1..4e2d1a0 100644 --- a/BaseGLProject/SceneContext.h +++ b/BaseGLProject/SceneContext.h @@ -2,6 +2,7 @@ #include #include #include +#include "Texture.h" struct SceneContext @@ -16,5 +17,5 @@ struct SceneContext glm::mat4x4 modelViewMatrix; glm::mat3x3 normalMatrix; - GLuint textures; + std::map textures; }; \ No newline at end of file diff --git a/BaseGLProject/Shader.h b/BaseGLProject/Shader.h index ca072d7..ed53b15 100644 --- a/BaseGLProject/Shader.h +++ b/BaseGLProject/Shader.h @@ -6,6 +6,7 @@ #include #include "glm/gtc/type_ptr.hpp" +#include "Texture.h" #include "Material.h" #include "Light.h" #include "SceneContext.h" @@ -31,6 +32,7 @@ public: Shader(const std::string vtx_name, const std::string frag_name); ~Shader(); + std::vector textures; int uniformFlags = KD_FLAG | KA_FLAG | KS_FLAG | SHINE_FLAG | MVP_FLAG | NORMAL_MAT_FLAG | MODELVIEW_FLAG | LIGHTS_FLAG; Material mat; @@ -42,15 +44,20 @@ public: void setUniforms(SceneContext ctx); void addUniform(const std::string name, glm::vec3 data) { - _program.use(); glUniform3fv(_program.addUniform(name), 1, glm::value_ptr(data)); ; _program.disable(); + _program.use(); glUniform3fv(_program.addUniform(name), 1, glm::value_ptr(data)); } void addUniform(const std::string name, int data) { - _program.use(); glUniform1i(_program.addUniform(name), data); _program.disable(); + _program.use(); glUniform1i(_program.addUniform(name), data); } void addUniform(const std::string name, float data) { - _program.use(); glUniform1fv(_program.addUniform(name), 1, &data); _program.disable(); + _program.use(); glUniform1fv(_program.addUniform(name), 1, &data); + } + + void assignTexture(Texture &texture) + { + textures.emplace_back(texture); } private: diff --git a/BaseGLProject/Texture.cpp b/BaseGLProject/Texture.cpp new file mode 100644 index 0000000..625c8aa --- /dev/null +++ b/BaseGLProject/Texture.cpp @@ -0,0 +1,28 @@ +#include "Texture.h" + +Texture::Texture(std::string file_name, GLuint enum_rgb) +{ + int width, height, channel; + unsigned char * image; + glActiveTexture(GL_TEXTURE0); + glGenTextures(1, &tex_ref); + glBindTexture(GL_TEXTURE_2D, tex_ref); + + image = stbi_load(file_name.c_str(), &width, &height, &channel, 0); + + glTexImage2D(GL_TEXTURE_2D, 0, enum_rgb, width, height, 0, enum_rgb, + GL_UNSIGNED_BYTE, image); + glGenerateMipmap(GL_TEXTURE_2D); + + stbi_image_free(image); + glBindTexture(GL_TEXTURE_2D, 0); +} + +Texture::Texture(const Texture &other) +{ + tex_ref = other.tex_ref; +} + +Texture::~Texture() +{ +} diff --git a/BaseGLProject/Texture.h b/BaseGLProject/Texture.h new file mode 100644 index 0000000..da6d9b5 --- /dev/null +++ b/BaseGLProject/Texture.h @@ -0,0 +1,19 @@ +#pragma once +#include +#include +#include +#include "imgui/stb_image.h" + +class Texture +{ +public: + GLuint tex_ref; + + Texture(std::string file_name, GLuint enum_rgb); + Texture(const Texture &other); + Texture() {}; + ~Texture(); + + void sendUniform(GLuint uni); +}; + diff --git a/BaseGLProject/base_light.frag b/BaseGLProject/base_light.frag index f176fb5..ace6e70 100644 --- a/BaseGLProject/base_light.frag +++ b/BaseGLProject/base_light.frag @@ -20,9 +20,6 @@ uniform int LightCount; in vec3 fNormal; in vec3 pos; -in vec2 texCoord; -uniform sampler2D tex1; - void main() { @@ -46,7 +43,5 @@ void main() specular_sum += specular; } - - vec4 texColor = texture(tex1, texCoord); - FragColors = (vec4(diffuse_sum + ambient, 1) * texColor + vec4(specular_sum, 1.0)); + FragColors = (vec4(diffuse_sum + ambient, 1) + vec4(specular_sum, 1.0)); } \ No newline at end of file diff --git a/BaseGLProject/moss.png b/BaseGLProject/moss.png new file mode 100644 index 0000000..8431ff8 Binary files /dev/null and b/BaseGLProject/moss.png differ diff --git a/BaseGLProject/tex_base_light.frag b/BaseGLProject/tex_base_light.frag index 4452a05..5ed7a0c 100644 --- a/BaseGLProject/tex_base_light.frag +++ b/BaseGLProject/tex_base_light.frag @@ -21,7 +21,8 @@ in vec3 fNormal; in vec3 pos; in vec2 texCoord; -uniform sampler2D tex1; +uniform int TexCount; +uniform sampler2D tex[32]; void main() { @@ -45,7 +46,15 @@ void main() diffuse_sum += diffuse; specular_sum += specular; } + + vec4 texColor = texture(tex[0], texCoord); - vec4 texColor = texture(tex1, texCoord); - FragColors = (vec4(diffuse_sum + ambient, 1) * texColor + vec4(specular_sum, 1.0)); + 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)); + }