diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000..a93a3b1
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ xmlns:android
+
+ ^$
+
+
+
+
+
+
+
+
+ xmlns:.*
+
+ ^$
+
+
+ BY_NAME
+
+
+
+
+
+
+ .*:id
+
+ http://schemas.android.com/apk/res/android
+
+
+
+
+
+
+
+
+ .*:name
+
+ http://schemas.android.com/apk/res/android
+
+
+
+
+
+
+
+
+ name
+
+ ^$
+
+
+
+
+
+
+
+
+ style
+
+ ^$
+
+
+
+
+
+
+
+
+ .*
+
+ ^$
+
+
+ BY_NAME
+
+
+
+
+
+
+ .*
+
+ http://schemas.android.com/apk/res/android
+
+
+ ANDROID_ATTRIBUTE_ORDER
+
+
+
+
+
+
+ .*
+
+ .*
+
+
+ BY_NAME
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000..79ee123
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
index d862e72..3b435b3 100644
--- a/.idea/deploymentTargetSelector.xml
+++ b/.idea/deploymentTargetSelector.xml
@@ -4,10 +4,10 @@
-
+
-
+
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 8978d23..adb8ae0 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,9 +1,4 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 94a25f7..35eb1dd 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index d2365ea..db89423 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -11,8 +11,8 @@ android {
applicationId = "com.drawgestures.learnopengl"
minSdk = 30
targetSdk = 34
- versionCode = 1
- versionName = "1.0"
+ versionCode = 2
+ versionName = "0.0.2"
ndk {
abiFilters.add("arm64-v8a")
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 04de584..9f38186 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,7 +1,7 @@
-
+
render();
GLenum err;
- Utility::checkAndLogGlError();
+ CHECK_GL_ERROR();
scene_->update();
@@ -141,10 +143,12 @@ void Renderer::initRenderer() {
eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
EGLSurface surface = eglCreateWindowSurface(display, config, app_->window, nullptr);
+
// Create a GLES 3 context
EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};
EGLContext context = eglCreateContext(display, config, nullptr, contextAttribs);
-
+ auto versionDetails = glGetString(GL_SHADING_LANGUAGE_VERSION);
+ // aout << "VERSION " << *versionDetails << std::endl;
// get some window metrics
auto madeCurrent = eglMakeCurrent(display, surface, surface, context);
assert(madeCurrent);
@@ -160,6 +164,7 @@ void Renderer::initRenderer() {
PRINT_GL_STRING(GL_VENDOR);
PRINT_GL_STRING(GL_RENDERER);
PRINT_GL_STRING(GL_VERSION);
+ PRINT_GL_STRING(GL_SHADING_LANGUAGE_VERSION);
PRINT_GL_STRING_AS_LIST(GL_EXTENSIONS);
glEnable(GL_CULL_FACE);
@@ -174,6 +179,8 @@ void Renderer::initRenderer() {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ shaderLoader_ = std::make_shared();
}
void Renderer::updateRenderArea() {
@@ -210,29 +217,40 @@ void Renderer::createModels() {
importer->SetIOHandler(ioSystem);
- std::shared_ptr modelImporter = std::make_shared(assetManager);
+ std::shared_ptr modelImporter = std::make_shared(assetManager, shaderLoader_.get());
//Load one model
std::shared_ptr environment = modelImporter->import(importer,
- "ceres/scene.gltf");
- environment->transform->setPosition(0, -1, 4);
- environment->transform->setScale(0.5, 0.5, 0.5);
- environment->transform->setRotation(90, 0, 0);
-
-
-
- std::shared_ptr sphereRenderer = std::make_shared();
- std::shared_ptr sphere = std::make_shared(2, 20, 20);
- sphereRenderer->addMesh(sphere);
+ "megatron__transformers_dotm/scene.gltf");
+ float scale = 0.2;
+ environment->transform->setPosition(0, 0, 4);
+ environment->transform->setScale(scale, scale, scale);
+ environment->transform->setRotation(0, 0, 0);
scene_->addObject(environment);
std::shared_ptr light = std::make_shared();
light->ambientIntensity = 0.8f;
light->direction = { 4, 2, 6};
- light->intensity = 1.0f;
+ light->diffuseIntensity = 1.0f;
light->color = {1, 1, 1, 1};
+
+ /* std::shared_ptr light = std::make_shared();
+ light->transform->position = { 2, 0, 12};
+ light->color = {0.8, 0.2, 0.2, 1.0};
+ light->attenuation.constant = 0.9;
+ light->attenuation.linear = 0.01;
+ light->attenuation.exp = 0.0;
+ // light->cutOff = 20.0;
+ //light->transform->position = {0.0, 0.0, 0.0};
+ //light->direction = {0.0, 2.0, 0.0};
+ shaderLoader_->setNumOfLights(1);*/
+
scene_->addObject(light);
+ scene_->getMainCamera()->setPosition(0, 4, 0);
+ glm::vec3 target = environment->transform->position;
+ target.y = 3;
+ scene_->getMainCamera()->setTarget(target);
}
void Renderer::handleInput() {
@@ -294,7 +312,7 @@ void Renderer::handleInput() {
float deltaY = y - lastY;
aout << "deltaX : " << deltaX;
aout << "deltaY : " << deltaY;
- scene_->getMainCamera()->OnMove(deltaX, deltaY);
+ scene_->getMainCamera()->onMove(deltaX, deltaY);
}
@@ -318,10 +336,10 @@ void Renderer::handleInput() {
float movedX = (x1 - lastX) / width_;
float movedY = (y1 - lastY) / height_;
// Move the camera left or right based on the x movement
- scene_->getMainCamera()->MoveLeft(movedX); // Scale the movement for smoother panning
- scene_->getMainCamera()->MoveUp( - movedY); // Scale the movement for smoother panning
+ scene_->getMainCamera()->moveLeft(movedX); // Scale the movement for smoother panning
+ scene_->getMainCamera()->moveUp(-movedY); // Scale the movement for smoother panning
}else if(abs(initialDistance) > 0){
- scene_->getMainCamera()->MoveForward(distanceMoved);
+ scene_->getMainCamera()->moveForward(distanceMoved);
}
initialDistance = currentDistance;
diff --git a/app/src/main/cpp/Renderer.h b/app/src/main/cpp/Renderer.h
index b4a3961..cc97d96 100644
--- a/app/src/main/cpp/Renderer.h
+++ b/app/src/main/cpp/Renderer.h
@@ -85,6 +85,7 @@ class Renderer {
bool shaderNeedsNewProjectionMatrix_;
std::shared_ptr scene_;
+ std::shared_ptr shaderLoader_;
};
diff --git a/app/src/main/cpp/Utility.cpp b/app/src/main/cpp/Utility.cpp
index 0491ee7..4ffd8ff 100644
--- a/app/src/main/cpp/Utility.cpp
+++ b/app/src/main/cpp/Utility.cpp
@@ -5,28 +5,8 @@
#include
-#define CHECK_ERROR(e) case e: aout << "GL Error: "#e << std::endl; break;
-bool Utility::checkAndLogGlError(bool alwaysLog) {
- GLenum error = glGetError();
- if (error == GL_NO_ERROR) {
- if (alwaysLog) {
- aout << "No GL error" << std::endl;
- }
- return true;
- } else {
- switch (error) {
- CHECK_ERROR(GL_INVALID_ENUM);
- CHECK_ERROR(GL_INVALID_VALUE);
- CHECK_ERROR(GL_INVALID_OPERATION);
- CHECK_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
- CHECK_ERROR(GL_OUT_OF_MEMORY);
- default:
- aout << "Unknown GL error: " << error << std::endl;
- }
- return false;
- }
-}
+
Mat4f *
Utility::buildOrthographicMatrix(Mat4f *outMatrix, float halfHeight, float aspect, float near,
float far) {
@@ -34,7 +14,7 @@ Utility::buildOrthographicMatrix(Mat4f *outMatrix, float halfHeight, float aspec
float A = -2.f / (far - near);
float B = -(far + near) / (far - near);
- outMatrix->InitIdentity();
+ outMatrix->initIdentity();
outMatrix->m[0][0] = 1/aspect;
outMatrix->m[1][1] = 1/aspect;
outMatrix->m[2][2] = A;
@@ -54,7 +34,7 @@ Utility::buildPerspectiveMat(Mat4f *outMatrix, float halfHeight, float aspect, f
float zRange = (near - far);
float A = (-far - near) / zRange;
float B = 2 * far * near / zRange;
- outMatrix->InitIdentity();
+ outMatrix->initIdentity();
outMatrix->m[0][0] = d/aspect;
outMatrix->m[1][1] = d;
outMatrix->m[2][2] = A;
diff --git a/app/src/main/cpp/Utility.h b/app/src/main/cpp/Utility.h
index cfff6ca..26f2295 100644
--- a/app/src/main/cpp/Utility.h
+++ b/app/src/main/cpp/Utility.h
@@ -2,14 +2,39 @@
#define ANDROIDGLINVESTIGATIONS_UTILITY_H
#include
+#include
#include "math/quaternion.h"
#include "math/mat4f.h"
+#include "AndroidOut.h"
+
+#define CHECK_ERROR(e) case e: aout << "GL Error: "#e << " at " << file << ":" << line << " in function " << func << std::endl; break;
class Utility {
public:
- static bool checkAndLogGlError(bool alwaysLog = false);
+ static inline bool checkAndLogGlError(const char* file, const char* func, int line, bool alwaysLog = false) {
+ GLenum error = glGetError();
+ if (error == GL_NO_ERROR) {
+ if (alwaysLog) {
+ aout << "No GL error in " << file << ":" << line << " in function " << func << std::endl;
+ }
+ return true;
+ } else {
+ switch (error) {
+ CHECK_ERROR(GL_INVALID_ENUM);
+ CHECK_ERROR(GL_INVALID_VALUE);
+ CHECK_ERROR(GL_INVALID_OPERATION);
+ CHECK_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
+ CHECK_ERROR(GL_OUT_OF_MEMORY);
+ default:
+ aout << "Unknown GL error: " << error << " at " << file << ":" << line << " in function " << func << std::endl;
+ }
+ return false;
+ }
+ }
- static inline void assertGlError() { assert(checkAndLogGlError()); }
+ static inline void assertGlError(const char* file, const char* func, int line) {
+ assert(checkAndLogGlError(file, func, line));
+ }
/**
* Generates an orthographic projection matrix given the half height, aspect ratio, near, and far
@@ -35,4 +60,7 @@ class Utility {
float far);
};
-#endif //ANDROIDGLINVESTIGATIONS_UTILITY_H
\ No newline at end of file
+#define CHECK_GL_ERROR() Utility::checkAndLogGlError(__FILE__, __FUNCTION__, __LINE__)
+#define ASSERT_GL_ERROR() Utility::assertGlError(__FILE__, __FUNCTION__, __LINE__)
+
+#endif //ANDROIDGLINVESTIGATIONS_UTILITY_H
diff --git a/app/src/main/cpp/camera/Camera.cpp b/app/src/main/cpp/camera/Camera.cpp
index 1eaebdd..58393ea 100644
--- a/app/src/main/cpp/camera/Camera.cpp
+++ b/app/src/main/cpp/camera/Camera.cpp
@@ -4,24 +4,25 @@
#include "Camera.h"
#include "glm/geometric.hpp"
+#include "trigonometric.hpp"
-void Camera::SetPosition(float x, float y, float z) {
- pos_.x = x;
- pos_.y = y;
- pos_.z = z;
+void Camera::setPosition(float x, float y, float z) {
+ transform->position.x = x;
+ transform->position.y = y;
+ transform->position.z = z;
}
-void Camera::OnUp() {
+void Camera::onUp() {
// pos_ += (target_ * speed_);
m_OnUpperEdge = true;
}
-void Camera::OnDown() {
+void Camera::onDown() {
// pos_ -= (target_ * speed_);
m_OnUpperEdge = true;
}
-void Camera::OnLeft() {
+void Camera::onLeft() {
/* glm::vec3 left = target_.cross(up_);
left.Normalize();
left *= speed_;
@@ -30,7 +31,7 @@ void Camera::OnLeft() {
}
-void Camera::OnRight() {
+void Camera::onRight() {
/* glm::vec3 right = up_.cross(target_);
right.Normalize();
right *= speed_;
@@ -38,34 +39,34 @@ void Camera::OnRight() {
m_OnRightEdge = true;
}
-void Camera::PanUp() {
- pos_.y += speed_;
+void Camera::panUp() {
+ transform->position.y += speed_;
}
-void Camera::PanDown() {
- pos_.y -= speed_;
+void Camera::panDown() {
+ transform->position.y -= speed_;
}
-void Camera::OnMove() {
+void Camera::onMove() {
}
-void Camera::OnZoomIn() {
+void Camera::onZoomIn() {
}
-void Camera::OnZoomOut() {
+void Camera::onZoomOut() {
}
-Mat4f Camera::Matrix() {
+Mat4f Camera::matrix() {
Mat4f cameraMat;
- cameraMat.InitCamera(target_, pos_, up_);
+ cameraMat.lookAt(target_, transform->position, up_);
return cameraMat;
}
-void Camera::Init() {
+void Camera::init() {
glm::vec3 HTarget = glm::normalize(glm::vec3(target_.x, 0, target_.z));
auto Angle = ToDegree(asinf(abs(HTarget.z)));
@@ -87,23 +88,37 @@ void Camera::Init() {
m_AngleV = -ToDegree(asinf(target_.y));
}
-void Camera::OnMove(int deltaX, int deltaY) {
- m_AngleH += (float) deltaX / 20;
- m_AngleV += (float) deltaY / 20;
+void Camera::onMove(float deltaX, float deltaY) {
+ float radius = glm::length(transform->position - target_);
+
+ angleX += deltaX;
+ angleY += deltaY;
+
+ // Constrain the vertical angle to avoid flipping
+ angleY = glm::clamp(angleY, -0.0f, 90.0f);
+
+ float radAngleX = glm::radians(angleX) * speed_;
+ float radAngleY = glm::radians(angleY) * speed_;
+
+ transform->position.x = target_.x + radius * cosf(radAngleX) * cosf(radAngleY);
+ transform->position.y = target_.y + radius * cosf(radAngleX) * sinf(radAngleY);
+ transform->position.z = target_.z + radius * sinf(radAngleX);
+
+
}
-void Camera::MoveForward(float distance) {
- pos_.z += distance * speed_;
+void Camera::moveForward(float distance) {
+ transform->position.z += distance * speed_;
}
-void Camera::MoveLeft(float distance) {
- pos_.x += distance * speed_;
+void Camera::moveLeft(float distance) {
+ transform->position.x += distance * speed_;
}
-void Camera::MoveUp(float distance) {
- pos_.y += distance * speed_;
+void Camera::moveUp(float distance) {
+ transform->position.y += distance * speed_;
}
-void Camera::Update() {
- glm::vec3 YAxis(0, 1, 0);
+void Camera::update() {
+ /*glm::vec3 YAxis(0, 1, 0);
glm::vec3 View(1, 0, 0);
Rotate(m_AngleH, YAxis, View);
@@ -116,12 +131,16 @@ void Camera::Update() {
target_ = glm::normalize(View);
- up_ = glm::normalize(glm::cross(target_, U));
+ up_ = glm::normalize(glm::cross(target_, U));*/
+
+
+
+
}
-void Camera::OnRender() {
- Update();
+void Camera::onRender() {
+ update();
m_OnUpperEdge = false;
m_OnUpperEdge = false;
m_OnLeftEdge = false;
@@ -129,7 +148,7 @@ void Camera::OnRender() {
}
-void Camera::Rotate(float Angle, const glm::vec3 &V, glm::vec3 &target) {
+void Camera::rotate(float Angle, const glm::vec3 &V, glm::vec3 &target) {
Quaternion RotationQ(Angle, V);
Quaternion ConjugateQ = RotationQ.Conjugate();
Quaternion W = RotationQ * target * ConjugateQ;
@@ -139,17 +158,27 @@ void Camera::Rotate(float Angle, const glm::vec3 &V, glm::vec3 &target) {
target.z = W.z;
}
-Camera::Camera(const glm::vec3 &Pos, const glm::vec3 &Target, const glm::vec3 &Up) {
- pos_ = Pos;
- target_ = Target;
- up_ = Up;
+Camera::Camera(const glm::vec3 &pos, const glm::vec3 &target, const glm::vec3 &up) {
+ transform->setPosition(pos.x, pos.y, pos.z);
+ target_ = target;
+ up_ = up;
+
+ init();
+}
- Init();
+glm::vec3 Camera::getTarget() {
+ return target_;
}
glm::vec3 &Camera::getPos() {
- return pos_;
+ return transform->position;
}
+void Camera::setTarget(const glm::vec3& target) {
+ target_ = target;
+ angleY = glm::degrees(glm::dot(target, up_));
+}
+
+
diff --git a/app/src/main/cpp/camera/Camera.h b/app/src/main/cpp/camera/Camera.h
index 86f56be..6f9173a 100644
--- a/app/src/main/cpp/camera/Camera.h
+++ b/app/src/main/cpp/camera/Camera.h
@@ -14,36 +14,41 @@
class Camera : public Component {
public:
- Camera(const glm::vec3& Pos, const glm::vec3& Target, const glm::vec3& Up);
- void Init();
-
- void SetPosition(float x, float y, float z);
- void OnUp();
- void Update();
- void OnDown();
- void OnLeft();
- void OnRight();
- void OnMove(int deltaX, int deltaY);
- void MoveForward(float distance);
- void MoveLeft(float distance);
- void MoveUp(float distance);
- void OnMove();
- void OnZoomIn();
- void OnRender();
- void OnZoomOut();
- void PanUp();
- void PanDown();
- Mat4f Matrix();
-
- static void Rotate(float Angle, const glm::vec3& V, glm::vec3& target);
+ Camera(const glm::vec3& pos, const glm::vec3& target, const glm::vec3& up);
+ void init();
+
+ void setPosition(float x, float y, float z);
+ void onUp();
+ void update();
+ void onDown();
+ void onLeft();
+ void onRight();
+ void onMove(float deltaX, float deltaY);
+ void moveForward(float distance);
+ void moveLeft(float distance);
+ void moveUp(float distance);
+ void onMove();
+ void onZoomIn();
+ void onRender();
+ void onZoomOut();
+ void panUp();
+ void panDown();
+ Mat4f matrix();
+
+ static void rotate(float Angle, const glm::vec3& V, glm::vec3& target);
glm::vec3& getPos();
+ glm::vec3 getTarget();
+
+ void setTarget(const glm::vec3& target);
+
private :
glm::vec3 target_{};
- glm::vec3 pos_{};
glm::vec3 up_{};
float speed_ = 3;
+ float angleX = 0;
+ float angleY = 0;
float m_AngleH{};
float m_AngleV{};
diff --git a/app/src/main/cpp/core/Scene.cpp b/app/src/main/cpp/core/Scene.cpp
index ded90f5..edc126a 100644
--- a/app/src/main/cpp/core/Scene.cpp
+++ b/app/src/main/cpp/core/Scene.cpp
@@ -10,6 +10,7 @@
#include "mesh/MeshRenderer.h"
#include "Behaviour.h"
#include "light/Light.h"
+#include "light/PointLight.h"
/*!
* Half the height of the projection matrix. This gives you a renderable area of height 4 ranging
@@ -40,9 +41,9 @@ Camera *Scene::getMainCamera() const {
}
void Scene::render() {
- mainCamera_->OnRender();
-
- Mat4f View = mainCamera_->Matrix();
+ mainCamera_->onRender();
+ CHECK_GL_ERROR();
+ Mat4f View = mainCamera_->matrix();
std::vector meshRenderers;
std::vector lights;
for (const auto &component: components_) {
@@ -59,6 +60,10 @@ void Scene::render() {
}
}
for (const auto &pLight: lights) {
+ if( pLight->transform->position.y > 10 || pLight->transform->position.y < -10){
+ deltaY = -deltaY;
+ }
+ // pLight->transform->setYPosition(pLight->transform->position.y + deltaY);
for (const auto &component: meshRenderers) {
component->transform->rotate(0, rotation_, 0);
Mat4f model = component->transform->matrix();
@@ -72,9 +77,10 @@ void Scene::render() {
void Scene::update() {
for (const auto &component: components_) {
if (component && component->transform) {
+
component->update();
} else {
- aout << "Update::Component transform is gone " << component << std::endl;
+ aout << "update::Component transform is gone " << component << std::endl;
}
}
}
@@ -88,7 +94,7 @@ void Scene::onDestroy() {
if (component && component->transform) {
component->onDestroy();
} else {
- aout << "Update::Component transform is gone " << component << std::endl;
+ aout << "update::Component transform is gone " << component << std::endl;
}
}
}
diff --git a/app/src/main/cpp/core/Scene.h b/app/src/main/cpp/core/Scene.h
index f3b4e68..7909b45 100644
--- a/app/src/main/cpp/core/Scene.h
+++ b/app/src/main/cpp/core/Scene.h
@@ -35,6 +35,7 @@ class Scene {
std::shared_ptr mainCamera_;
std::shared_ptr projectionMatrix_;
float rotation_ = 0.2;
+ float deltaY = 0.2;
};
diff --git a/app/src/main/cpp/importer/ModelImporter.cpp b/app/src/main/cpp/importer/ModelImporter.cpp
index 56fbf19..398dba4 100644
--- a/app/src/main/cpp/importer/ModelImporter.cpp
+++ b/app/src/main/cpp/importer/ModelImporter.cpp
@@ -44,12 +44,14 @@ void ModelImporter::loadSingleMesh(const aiMesh *aiMesh, std::vector &ve
for (int index = 0; index < aiMesh->mNumVertices; ++index) {
const aiVector3D &aPos = aiMesh->mVertices[index];
const aiVector3D &aNormal = aiMesh->mNormals[index];
+ const aiVector3D &aTangent = aiMesh->mTangents[index];
const auto aTextCoor = aiMesh->HasTextureCoords(0) ? aiMesh->mTextureCoords[0][index]
: zero;
vertices.emplace_back(glm::vec3(aPos.x, aPos.y, aPos.z),
glm::vec2(aTextCoor.x, aTextCoor.y),
- glm::vec3(aNormal.x, aNormal.y, aNormal.z)
+ glm::vec3(aNormal.x, aNormal.y, aNormal.z),
+ glm::vec3(aTangent.x, aTangent.y, aTangent.z)
);
}
@@ -68,21 +70,26 @@ std::shared_ptr ModelImporter::loadMaterial(const aiScene *pScene,
const aiMesh *aiMesh,
const std::string& path) {
- auto material = std::make_shared();
+ auto material = std::make_shared(shaderLoader_);
if (pScene->mMaterials) {
auto aiMaterial = pScene->mMaterials[aiMesh->mMaterialIndex];
- auto diffuseTexture = getDiffuseTexture(aiMaterial, path, aiTextureType_DIFFUSE);
+ auto diffuseTexture = getTexture(aiMaterial, path, aiTextureType_DIFFUSE);
if(diffuseTexture){
material->diffuseTexture = diffuseTexture;
}
- auto specularTexture = getDiffuseTexture(aiMaterial, path, aiTextureType_SHININESS, GL_RED);
+ auto specularTexture = getTexture(aiMaterial, path, aiTextureType_SHININESS, GL_RED);
if(specularTexture){
material->specularTexture = specularTexture;
}
+ auto normalTexture = getTexture(aiMaterial, path, aiTextureType_NORMALS);
+ if(normalTexture){
+ material->normalTexture = normalTexture;
+ }
+
if (aiMaterial->mNumProperties > 0) {
- aiColor3D diffuseColor(1.f, 1.f, 1.f);
+ aiColor3D diffuseColor(0.f, 0.f, 0.f);
if(aiMaterial->Get(AI_MATKEY_COLOR_DIFFUSE, diffuseColor) == AI_SUCCESS){
material->diffuseColor = {diffuseColor.r, diffuseColor.g, diffuseColor.b};
}
@@ -97,10 +104,11 @@ std::shared_ptr ModelImporter::loadMaterial(const aiScene *pScene,
return material;
}
-std::shared_ptr ModelImporter::getDiffuseTexture(const aiMaterial *aiMaterial,
- const std::string& path, aiTextureType type, GLint format ) {
+std::shared_ptr ModelImporter::getTexture(const aiMaterial *aiMaterial,
+ const std::string& path, aiTextureType type, GLint format ) {
- if (aiMaterial->GetTextureCount(type) == 0) {
+ unsigned int textureCount = aiMaterial->GetTextureCount(type);
+ if (textureCount == 0) {
return nullptr;
}
@@ -155,7 +163,7 @@ std::string ModelImporter::getStringAfterAssets(const std::string &filePath) {
return ""; // Return an empty string if "assets" is not found
}
-ModelImporter::ModelImporter(AAssetManager *aAssetManager) : assetManager(aAssetManager) {
+ModelImporter::ModelImporter(AAssetManager *aAssetManager, ShaderLoader* shaderLoader) : assetManager(aAssetManager), shaderLoader_(shaderLoader) {
}
diff --git a/app/src/main/cpp/importer/ModelImporter.h b/app/src/main/cpp/importer/ModelImporter.h
index 79789b7..9b01997 100644
--- a/app/src/main/cpp/importer/ModelImporter.h
+++ b/app/src/main/cpp/importer/ModelImporter.h
@@ -16,9 +16,10 @@
class ModelImporter {
private:
AAssetManager *assetManager;
+ ShaderLoader *shaderLoader_;
std::unordered_map> textures_;
public:
- ModelImporter(AAssetManager *aAssetManager);
+ ModelImporter(AAssetManager *aAssetManager, ShaderLoader* shaderLoader);
std::shared_ptr import(Assimp::Importer *importer, const char *modelPath);
@@ -35,7 +36,7 @@ class ModelImporter {
static std::string getStringAfterAssets(const std::string &filePath);
std::shared_ptr
- getDiffuseTexture(const aiMaterial *aiMaterial, const std::string& path, aiTextureType type, GLint format = GL_RGBA);
+ getTexture(const aiMaterial *aiMaterial, const std::string& path, aiTextureType type, GLint format = GL_RGBA);
};
diff --git a/app/src/main/cpp/light/DirectionalLight.cpp b/app/src/main/cpp/light/DirectionalLight.cpp
index e9f2e24..4e73e45 100644
--- a/app/src/main/cpp/light/DirectionalLight.cpp
+++ b/app/src/main/cpp/light/DirectionalLight.cpp
@@ -3,28 +3,31 @@
//
#include "DirectionalLight.h"
+#include "Utility.h"
const glm::vec3 &DirectionalLight::GetLocalDirection() {
return localDirection;
}
-void DirectionalLight::CalLocalDirection(Mat4f worldMat) {
+void DirectionalLight::calLocalDirection(const Transform& worldTransform) {
//glm::mat3 world(glm::inverse(worldMat));
- Mat3f world3Mat(worldMat);
- localDirection = -glm::normalize( world3Mat.Transpose() * direction);
+ localDirection = worldTransform.worldDirectionToLocal(direction);
}
-void DirectionalLight::bind(Shader *shader, const glm::vec3 & cameraLocalPos) {
+void DirectionalLight::bind(Shader *shader, const glm::vec3 &cameraLocalPos) {
Light::bind(shader, cameraLocalPos);
glUniform1f(shader->lightTypeLocation, 1);
- if (shader->lightDirectionLocation != -1)
- glUniform3f(shader->lightDirectionLocation, localDirection.x, localDirection.y,
+ if (shader->getLightDirectionLocation() != -1)
+ glUniform3f(shader->getLightDirectionLocation(), localDirection.x, localDirection.y,
localDirection.z);
- if (shader->diffuseIntensityLocation != -1)
- glUniform1f(shader->diffuseIntensityLocation, intensity);
+ if (shader->getDiffuseIntensityLocation() != -1)
+ glUniform1f(shader->getDiffuseIntensityLocation(), diffuseIntensity);
+ if (shader->getAmbientIntensityLocation() != -1)
+ glUniform1f(shader->getAmbientIntensityLocation(), ambientIntensity);
+ CHECK_GL_ERROR();
}
diff --git a/app/src/main/cpp/light/DirectionalLight.h b/app/src/main/cpp/light/DirectionalLight.h
index c0ef62a..59089df 100644
--- a/app/src/main/cpp/light/DirectionalLight.h
+++ b/app/src/main/cpp/light/DirectionalLight.h
@@ -13,9 +13,8 @@ class DirectionalLight : public Light {
glm::vec3 localDirection = {0, 0, 0};
public :
glm::vec3 direction = {0, 0, 0};
- float intensity = 1.0;
- void CalLocalDirection(Mat4f worldMat);
+ void calLocalDirection(const Transform& worldTransform);
void bind(Shader *shader, const glm::vec3 & cameraLocalPos) override;
const glm::vec3 &GetLocalDirection();
diff --git a/app/src/main/cpp/light/Light.cpp b/app/src/main/cpp/light/Light.cpp
index 56a90a9..7955bd5 100644
--- a/app/src/main/cpp/light/Light.cpp
+++ b/app/src/main/cpp/light/Light.cpp
@@ -3,6 +3,7 @@
//
#include "Light.h"
+#include "Utility.h"
void Light::bind(Shader *shader, const glm::vec3& cameraLocalPos) {
@@ -12,8 +13,10 @@ void Light::bind(Shader *shader, const glm::vec3& cameraLocalPos) {
if (shader->getAmbientIntensityLocation() != -1)
glUniform1f(shader->getAmbientIntensityLocation(), ambientIntensity);
glUniform1f(shader->lightTypeLocation, 0);
-
+ CHECK_GL_ERROR();
glUniform3f(shader->getCameraLocalPosLocation(), cameraLocalPos.x, cameraLocalPos.y, cameraLocalPos.z);
+
+ CHECK_GL_ERROR();
}
Light::Light() {
diff --git a/app/src/main/cpp/light/Light.h b/app/src/main/cpp/light/Light.h
index 5701b01..6b8a2cc 100644
--- a/app/src/main/cpp/light/Light.h
+++ b/app/src/main/cpp/light/Light.h
@@ -19,6 +19,7 @@ class Light : public Behaviour {
Light();
glm::vec4 color = {1.0, 1.0, 1.0, 1.0};
float ambientIntensity = 1.0;
+ float diffuseIntensity = 1.0;
void bind(Shader *shader, const glm::vec3 & cameraLocalPos) override;
};
diff --git a/app/src/main/cpp/light/PointLight.cpp b/app/src/main/cpp/light/PointLight.cpp
new file mode 100644
index 0000000..7e9b0c2
--- /dev/null
+++ b/app/src/main/cpp/light/PointLight.cpp
@@ -0,0 +1,27 @@
+//
+// Created by Dark Matter on 6/4/24.
+//
+
+#include "PointLight.h"
+
+glm::vec3 PointLight::getLocalPosition() {
+ return localPosition_;
+}
+
+void PointLight::bind(Shader *shader, const glm::vec3 &cameraLocalPos) {
+ Light::bind(shader, cameraLocalPos);
+
+ glUniform3f(shader->getPointLightColor(index), color.r, color.g, color.b);
+ glUniform1f(shader->getPointLightAmbientIntensity(index), ambientIntensity );
+ glUniform1f(shader->getPointLightDiffuseIntensity(index), diffuseIntensity );
+ glUniform3f(shader->getPointLightLocalPosition(index), localPosition_.x, localPosition_.y, localPosition_.z );
+ glUniform1f(shader->getPointLightAttenuationConstant(index), attenuation.constant);
+ glUniform1f(shader->getPointLightAttenuationLinear(index), attenuation.linear);
+ glUniform1f(shader->getPointLightAttenuationExp(index), attenuation.exp);
+}
+
+void PointLight::calculateLocalPosition(const Transform& worldTransform) {
+ localPosition_ = worldTransform.worldToLocal(this->transform->position);
+}
+
+
diff --git a/app/src/main/cpp/light/PointLight.h b/app/src/main/cpp/light/PointLight.h
new file mode 100644
index 0000000..52ec565
--- /dev/null
+++ b/app/src/main/cpp/light/PointLight.h
@@ -0,0 +1,34 @@
+//
+// Created by Dark Matter on 6/4/24.
+//
+
+#ifndef LEARNOPENGL_POINTLIGHT_H
+#define LEARNOPENGL_POINTLIGHT_H
+
+
+#include "Light.h"
+
+struct LightAttenuation {
+ float constant = 1.0;
+ float linear = 0.0;
+ float exp = 0.0;
+};
+
+class PointLight : public Light {
+
+public :
+ int index = 0;
+ LightAttenuation attenuation;
+
+ void calculateLocalPosition(const Transform &worldTransform);
+
+ glm::vec3 getLocalPosition();
+
+ void bind(Shader *shader, const glm::vec3 &cameraLocalPos) override;
+
+protected:
+ glm::vec3 localPosition_;
+};
+
+
+#endif //LEARNOPENGL_POINTLIGHT_H
diff --git a/app/src/main/cpp/light/SpotLight.cpp b/app/src/main/cpp/light/SpotLight.cpp
new file mode 100644
index 0000000..3c3a12a
--- /dev/null
+++ b/app/src/main/cpp/light/SpotLight.cpp
@@ -0,0 +1,31 @@
+//
+// Created by Dark Matter on 6/7/24.
+//
+
+#include "SpotLight.h"
+
+void SpotLight::calculateDirectionAndPosition(const Transform &transform) {
+ calculateLocalPosition(transform);
+ localDirection = transform.worldDirectionToLocal(direction);
+}
+
+glm::vec3 SpotLight::getLocalDirection() {
+ return localDirection;
+}
+
+void SpotLight::bind(Shader *shader, const glm::vec3 &cameraLocalPos) {
+ Light::bind(shader, cameraLocalPos);
+
+ glUniform3f(shader->getSpotLightColor(index), color.r, color.g, color.b);
+ glUniform1f(shader->getSpotLightAmbientIntensity(index), ambientIntensity );
+ glUniform1f(shader->getSpotLightDiffuseIntensity(index), diffuseIntensity );
+ glUniform3f(shader->getSpotLightLocalPosition(index), localPosition_.x, localPosition_.y, localPosition_.z );
+ glUniform1f(shader->getSpotLightAttenuationConstant(index), attenuation.constant);
+ glUniform1f(shader->getSpotLightAttenuationLinear(index), attenuation.linear);
+ glUniform1f(shader->getSpotLightAttenuationExp(index), attenuation.exp);
+
+ glm::vec3 localDirectionNorm = glm::normalize(localDirection);
+ glUniform3f(shader->getSpotLightDirection(index), localDirectionNorm.x, localDirectionNorm.y, localDirectionNorm.z);
+ glUniform1f(shader->getSpotLightDirection(index), cutOff);
+}
+
diff --git a/app/src/main/cpp/light/SpotLight.h b/app/src/main/cpp/light/SpotLight.h
new file mode 100644
index 0000000..48be72f
--- /dev/null
+++ b/app/src/main/cpp/light/SpotLight.h
@@ -0,0 +1,27 @@
+//
+// Created by Dark Matter on 6/7/24.
+//
+
+#ifndef LEARNOPENGL_SPOTLIGHT_H
+#define LEARNOPENGL_SPOTLIGHT_H
+
+
+#include "PointLight.h"
+
+class SpotLight : public PointLight {
+public:
+ glm::vec3 direction;
+ float cutOff = 0.0;
+
+ void calculateDirectionAndPosition(const Transform &transform);
+
+ glm::vec3 getLocalDirection();
+
+ void bind(Shader *shader, const glm::vec3 &cameraLocalPos) override;
+
+private:
+ glm::vec3 localDirection;
+};
+
+
+#endif //LEARNOPENGL_SPOTLIGHT_H
diff --git a/app/src/main/cpp/math/mat4f.cpp b/app/src/main/cpp/math/mat4f.cpp
index 115408f..5936e16 100644
--- a/app/src/main/cpp/math/mat4f.cpp
+++ b/app/src/main/cpp/math/mat4f.cpp
@@ -37,8 +37,8 @@ Mat4f::Mat4f(float a00, float a01, float a02, float a03,
}
// Initialize scale matrix
-void Mat4f::InitScaleMatrix(float scaleX, float scaleY, float scaleZ) {
- InitIdentity();
+void Mat4f::initScaleMatrix(float scaleX, float scaleY, float scaleZ) {
+ initIdentity();
m[0][0] = scaleX;
m[0][1] = 0.0f;
m[0][2] = 0.0f;
@@ -58,8 +58,8 @@ void Mat4f::InitScaleMatrix(float scaleX, float scaleY, float scaleZ) {
}
// Initialize rotation matrix around X axis
-void Mat4f::InitRotationX(float x) {
- InitIdentity();
+void Mat4f::initRotationX(float x) {
+ initIdentity();
m[1][1] = cosf(x);
m[1][2] = sinf(x);
m[2][1] = -sinf(x);
@@ -67,8 +67,8 @@ void Mat4f::InitRotationX(float x) {
}
// Initialize rotation matrix around Y axis
-void Mat4f::InitRotationY(float y) {
- InitIdentity();
+void Mat4f::initRotationY(float y) {
+ initIdentity();
m[0][0] = cosf(y);
m[0][2] = -sinf(y);
m[2][0] = sinf(y);
@@ -76,8 +76,8 @@ void Mat4f::InitRotationY(float y) {
}
// Initialize rotation matrix around Z axis
-void Mat4f::InitRotationZ(float z) {
- InitIdentity();
+void Mat4f::initRotationZ(float z) {
+ initIdentity();
m[0][0] = cosf(z);
m[0][1] = sinf(z);
m[1][0] = -sinf(z);
@@ -85,30 +85,30 @@ void Mat4f::InitRotationZ(float z) {
}
// Initialize rotation matrix for combined rotations
-void Mat4f::InitRotationMatrix(float rotationX, float rotationY, float rotationZ) {
+void Mat4f::initRotationMatrix(float rotationX, float rotationY, float rotationZ) {
Mat4f rx, ry, rz;
float x = ToRadian(rotationX);
float y = ToRadian(rotationY);
float z = ToRadian(rotationZ);
- rx.InitRotationX(x);
- ry.InitRotationY(y);
- rz.InitRotationZ(z);
+ rx.initRotationX(x);
+ ry.initRotationY(y);
+ rz.initRotationZ(z);
*this = rz * ry * rx;
}
// Initialize translation matrix
-void Mat4f::InitTranslation(float x, float y, float z) {
- InitIdentity();
+void Mat4f::initTranslation(float x, float y, float z) {
+ initIdentity();
m[0][3] = x;
m[1][3] = y;
m[2][3] = z;
}
// Initialize camera transformation matrix
-void Mat4f::InitCameraTransform(glm::vec3 Target, glm::vec3 Up) {
+void Mat4f::initCameraTransform(glm::vec3 Target, glm::vec3 Up) {
glm::vec3 N = glm::normalize(Target);
glm::vec3 UpNorm = Up;
@@ -138,20 +138,45 @@ void Mat4f::InitCameraTransform(glm::vec3 Target, glm::vec3 Up) {
}
// Initialize camera matrix with position and target
-void Mat4f::InitCamera(glm::vec3 target, glm::vec3 pos, glm::vec3 up) {
+void Mat4f::initCamera(glm::vec3 target, glm::vec3 pos, glm::vec3 up) {
Mat4f translation;
- translation.InitIdentity();
- translation.InitTranslation(-pos.x, -pos.y, -pos.z);
+ translation.initIdentity();
+ translation.initTranslation(-pos.x, -pos.y, -pos.z);
Mat4f camMat;
- camMat.InitIdentity();
- camMat.InitCameraTransform(target, up);
+ camMat.initIdentity();
+ camMat.initCameraTransform(target, up);
*this = camMat * translation;
}
+// Initialize camera matrix with position and target
+void Mat4f::lookAt(glm::vec3 target, glm::vec3 pos, glm::vec3 up) {
+ glm::vec3 forward = glm::normalize(target - pos);
+ glm::vec3 right = glm::normalize(glm::cross(glm::normalize(up), forward));
+ glm::vec3 cameraUp = glm::cross(forward, right);
+
+ Mat4f translation;
+ translation.initTranslation(-pos.x, -pos.y, -pos.z);
+
+ // Create a rotation matrix to align the camera's axes with the world's axes
+ Mat4f rotation;
+ rotation.initIdentity();
+ rotation.m[0][0] = right.x;
+ rotation.m[0][1] = right.y;
+ rotation.m[0][2] = right.z;
+ rotation.m[1][0] = cameraUp.x;
+ rotation.m[1][1] = cameraUp.y;
+ rotation.m[1][2] = cameraUp.z;
+ rotation.m[2][0] = forward.x;
+ rotation.m[2][1] = forward.y;
+ rotation.m[2][2] = forward.z;
+
+ *this = rotation * translation;
+}
+
// Initialize identity matrix
-void Mat4f::InitIdentity() {
+void Mat4f::initIdentity() {
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
m[i][j] = (i == j) ? 1.0f : 0.0f;
@@ -184,13 +209,14 @@ glm::vec4 Mat4f::operator*(const glm::vec4 &other) const {
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
ret[j] = m[i][0] * other[0] +
- m[i][1] * other[1] +
- m[i][2] * other[2] +
- m[i][3] * other[3];
+ m[i][1] * other[1] +
+ m[i][2] * other[2] +
+ m[i][3] * other[3];
}
}
return ret;
}
+
Mat4f Mat4f::inverse() {
Mat4f invMat;
glm::mat4 mat = glm::mat4(1.0);
diff --git a/app/src/main/cpp/math/mat4f.h b/app/src/main/cpp/math/mat4f.h
index eca1e73..7f77c4b 100644
--- a/app/src/main/cpp/math/mat4f.h
+++ b/app/src/main/cpp/math/mat4f.h
@@ -24,15 +24,15 @@ struct Mat4f {
float a30, float a31, float a32, float a33);
// Member functions
- void InitScaleMatrix(float scaleX, float scaleY, float scaleZ);
- void InitRotationX(float x);
- void InitRotationY(float y);
- void InitRotationZ(float z);
- void InitRotationMatrix(float rotationX, float rotationY, float rotationZ);
- void InitTranslation(float x, float y, float z);
- void InitCameraTransform(glm::vec3 Target, glm::vec3 Up);
- void InitCamera(glm::vec3 target, glm::vec3 pos, glm::vec3 up);
- void InitIdentity();
+ void initScaleMatrix(float scaleX, float scaleY, float scaleZ);
+ void initRotationX(float x);
+ void initRotationY(float y);
+ void initRotationZ(float z);
+ void initRotationMatrix(float rotationX, float rotationY, float rotationZ);
+ void initTranslation(float x, float y, float z);
+ void initCameraTransform(glm::vec3 Target, glm::vec3 Up);
+ void initCamera(glm::vec3 target, glm::vec3 pos, glm::vec3 up);
+ void initIdentity();
// Static method to create an identity matrix and return a unique_ptr
static std::unique_ptr Identity();
@@ -42,6 +42,8 @@ struct Mat4f {
glm::vec4 operator*(const glm::vec4 &other) const;
Mat4f inverse();
+
+ void lookAt(glm::vec3 target, glm::vec3 pos, glm::vec3 up);
};
diff --git a/app/src/main/cpp/math/math.h b/app/src/main/cpp/math/math.h
index 4299080..351bb30 100644
--- a/app/src/main/cpp/math/math.h
+++ b/app/src/main/cpp/math/math.h
@@ -11,19 +11,21 @@
struct Vertex {
constexpr Vertex(const glm::vec3 &inPosition,
- const glm::vec2 &inUV)
+ const glm::vec2 &inUV, const glm::vec3 &tangent)
: position(inPosition),
- uv(inUV), normal(glm::vec3{}) {};
+ uv(inUV), normal(glm::vec3{}), tangent(tangent) {};
constexpr Vertex(const glm::vec3 &inPosition,
const glm::vec2 &inUV,
- const glm::vec3 &inNormal)
+ const glm::vec3 &inNormal, const glm::vec3 &tangent)
: position(inPosition),
- uv(inUV), normal(inNormal) {}
+ uv(inUV), normal(inNormal), tangent(tangent) {}
glm::vec3 position;
glm::vec3 normal;
glm::vec2 uv;
+ glm::vec3 tangent;
+ glm::vec3 biTangent;
};
#endif // LEARNOPENGL_MATH_H
diff --git a/app/src/main/cpp/mesh/Material.cpp b/app/src/main/cpp/mesh/Material.cpp
index eb43fc5..41c81e9 100644
--- a/app/src/main/cpp/mesh/Material.cpp
+++ b/app/src/main/cpp/mesh/Material.cpp
@@ -6,22 +6,15 @@
#include "string"
#include "AndroidOut.h"
#include "utils.h"
+#include "Utility.h"
Shader *Material::getShader() const {
- return shader_.get();
+ return shader_;
}
void Material::loadShader() {
- std::string vertexShaderPath = "shaders/base_frag.vert";
- std::string fragmentShaderPath = "shaders/base_frag.frag";
-
- shader_ = std::__ndk1::make_shared(vertexShaderPath, fragmentShaderPath);
-}
-
-
-Material::Material(glm::vec3 diffuseColor) : diffuseColor(diffuseColor) {
- loadShader();
+ shader_ = shaderLoader_->load(shaderPath);
}
@@ -32,9 +25,10 @@ Material::~Material() {
void Material::unbindTexture() const {
glBindTexture(GL_TEXTURE_2D, 0);
+ CHECK_GL_ERROR();
}
-Material::Material() {
+Material::Material(ShaderLoader *shaderLoader) : shaderLoader_(shaderLoader) {
diffuseColor = glm::vec4(0, 0, 0, 1);
loadShader();
}
@@ -49,18 +43,34 @@ void Material::bindTexture() const {
glUniform1i(shader_->getDiffColorLocation(), COLOR_TEXTURE_UNIT_INDEX);
}
+ CHECK_GL_ERROR();
+
if (specularTexture) {
glActiveTexture(SPECULAR_EXPONENT_UNIT);
glBindTexture(GL_TEXTURE_2D, specularTexture->getTextureID());
glUniform1i(shader_->getSpecularExponentLocation(), SPECULAR_EXPONENT_UNIT_INDEX);
}
+ CHECK_GL_ERROR();
+
+ if (normalTexture) {
+ glActiveTexture(NORMAL_UNIT);
+ glBindTexture(GL_TEXTURE_2D, normalTexture->getTextureID());
+ glUniform1i(shader_->getNormalTexLocation(), NORMAL_UNIT_INDEX);
+ }
+
//Push Color to fragment shader
glUniform3fv(shader_->getAmbientColorLocation(), 1, (const GLfloat *) &ambientColor.x);
+ CHECK_GL_ERROR();
+
glUniform3fv(shader_->getDiffColorLocation(), 1, (const GLfloat *) &diffuseColor.x);
+ CHECK_GL_ERROR();
+
glUniform3fv(shader_->getSpecularColorLocation(), 1, (const GLfloat *) &specularColor.x);
+
+ CHECK_GL_ERROR();
}
diff --git a/app/src/main/cpp/mesh/Material.h b/app/src/main/cpp/mesh/Material.h
index 3707bec..ec0840d 100644
--- a/app/src/main/cpp/mesh/Material.h
+++ b/app/src/main/cpp/mesh/Material.h
@@ -8,20 +8,21 @@
#include "shader/Shader.h"
#include "TextureAsset.h"
+#include "string"
+#include "shader/ShaderLoader.h"
class Material {
public:
std::string materialName;
std::shared_ptr diffuseTexture;
std::shared_ptr specularTexture;
+ std::shared_ptr normalTexture;
- glm::vec3 diffuseColor = {1.0, 1.0, 1.0};
- glm::vec3 specularColor = {1.0, 1.0, 1.0};
+ glm::vec3 diffuseColor = {0.0, 0.0, 0.0};
+ glm::vec3 specularColor = {0.0, 0.0, 0.0};
glm::vec3 ambientColor = {0.0, 0.0, 0.0};
- Material();
-
- explicit Material(glm::vec3 diffuseColor);
+ Material(ShaderLoader* shaderLoader);
~Material();
@@ -33,7 +34,9 @@ class Material {
private :
- std::shared_ptr shader_;
+ Shader* shader_;
+ std::shared_ptr shaderLoader_;
+ const char* shaderPath = "default";
void loadShader();
};
diff --git a/app/src/main/cpp/mesh/MeshRenderer.cpp b/app/src/main/cpp/mesh/MeshRenderer.cpp
index d46791d..0eb38bd 100644
--- a/app/src/main/cpp/mesh/MeshRenderer.cpp
+++ b/app/src/main/cpp/mesh/MeshRenderer.cpp
@@ -7,6 +7,9 @@
#include "core/Behaviour.h"
#include "light/DirectionalLight.h"
#include "camera/Camera.h"
+#include "light/PointLight.h"
+#include "light/SpotLight.h"
+#include "Utility.h"
MeshRenderer::MeshRenderer() {
transform->setRotation(0, 0, 0);
@@ -17,26 +20,33 @@ MeshRenderer::MeshRenderer() {
void MeshRenderer::render(Mat4f *projectionMatrix,Camera* camera, Light *light) {
unsigned int textureN = 0;
+ Mat4f modelMatrix = transform->matrix();
+ CHECK_GL_ERROR();
for (const auto &mesh: meshes_) {
Material *material = mesh->getMaterial();
+ CHECK_GL_ERROR();
Shader *shader = material->getShader();
shader->setProjectionMatrix(projectionMatrix);
- shader->bind();
-
+ shader->setModelMatrix(modelMatrix);
material->bindTexture();
-
+ CHECK_GL_ERROR();
auto* pDirectionalLight = dynamic_cast(light);
if(pDirectionalLight){
- pDirectionalLight->CalLocalDirection(this->transform->matrix());
+ pDirectionalLight->calLocalDirection(*transform);
}
-
- Mat4f cameraToLocalTranslation = transform->getReversedTranslation();
- Mat4f cameraToLocalRotation = transform->getReversedRotation();
- Mat4f cameraToLocalTransformation = cameraToLocalRotation * cameraToLocalTranslation;
- glm::vec4 cameraWorldPos = glm::vec4 (camera->getPos(), 1.0);
- glm::vec4 cameraLocalPos = cameraToLocalTransformation * cameraWorldPos;
- auto cameraLocalPos3f = glm::vec3 (cameraWorldPos);
-
+ CHECK_GL_ERROR();
+ auto* pSpotLight = dynamic_cast(light);
+ if(pSpotLight){
+
+ pSpotLight->calculateDirectionAndPosition(*this->transform);
+ }else{
+ auto* pPointLight = dynamic_cast(light);
+ if(pPointLight){
+ pPointLight->calculateLocalPosition(*this->transform);
+ }
+ }
+ CHECK_GL_ERROR();
+ auto cameraLocalPos3f = transform->worldToLocal(camera->transform->position);
light->bind(shader, cameraLocalPos3f);
@@ -45,6 +55,8 @@ void MeshRenderer::render(Mat4f *projectionMatrix,Camera* camera, Light *light)
glBindVertexArray(0);
material->unbindTexture();
textureN++;
+ // aout << "textureN : " << textureN << std::endl;
+ CHECK_GL_ERROR();
// shader->unbind();
}
}
@@ -95,6 +107,17 @@ void MeshRenderer::initMesh(Mesh *mesh) const {
(void *) offsetof(Vertex, normal)
);
+ GLint tangentAttribute = mesh->getMaterial()->getShader()->tangentAttribute;
+ glEnableVertexAttribArray(tangentAttribute);
+ glVertexAttribPointer(
+ tangentAttribute,
+ 3,
+ GL_FLOAT,
+ GL_FALSE,
+ sizeof(Vertex),
+ (void *) offsetof(Vertex, tangent)
+ );
+
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
@@ -135,7 +158,8 @@ void MeshRenderer::update() {
void MeshRenderer::addMesh(const std::shared_ptr &mesh) {
meshes_.push_back(mesh);
- mesh->getMaterial()->getShader()->bind();
+ CHECK_GL_ERROR();
+ // mesh->getMaterial()->getShader()->bind();
initMesh(mesh.get());
}
diff --git a/app/src/main/cpp/mesh/primitives/Cube.cpp b/app/src/main/cpp/mesh/primitives/Cube.cpp
index 842a4c3..90caeee 100644
--- a/app/src/main/cpp/mesh/primitives/Cube.cpp
+++ b/app/src/main/cpp/mesh/primitives/Cube.cpp
@@ -81,9 +81,9 @@ void Cube::generateIndices() {
};
}
-Cube::Cube(float size) {
+Cube::Cube(float size, ShaderLoader* shaderLoader) {
size_ = size;
generateVertices();
generateIndices();
- material_ = std::make_shared();
+ material_ = std::make_shared(shaderLoader);
}
diff --git a/app/src/main/cpp/mesh/primitives/Cube.h b/app/src/main/cpp/mesh/primitives/Cube.h
index 3426795..2ed6d5b 100644
--- a/app/src/main/cpp/mesh/primitives/Cube.h
+++ b/app/src/main/cpp/mesh/primitives/Cube.h
@@ -10,7 +10,7 @@
class Cube : public Mesh{
public :
- Cube(float size);
+ Cube(float size, ShaderLoader *shaderLoader);
private:
float size_;
void generateVertices();
diff --git a/app/src/main/cpp/mesh/primitives/Sphere.cpp b/app/src/main/cpp/mesh/primitives/Sphere.cpp
index 30cee51..62f04ae 100644
--- a/app/src/main/cpp/mesh/primitives/Sphere.cpp
+++ b/app/src/main/cpp/mesh/primitives/Sphere.cpp
@@ -5,11 +5,11 @@
#include "Sphere.h"
Sphere::Sphere(float radius, int latitudeSegments,
- int longitudeSegments) {
+ int longitudeSegments, ShaderLoader* shaderLoader) {
radius_ = radius;
latitudeSegments_ = latitudeSegments;
longitudeSegments_ = longitudeSegments;
- material_ = std::make_shared(glm::vec3(1, 0, 0));
+ material_ = std::make_shared(shaderLoader);
generateVertices();
generateIndices();
}
diff --git a/app/src/main/cpp/mesh/primitives/Sphere.h b/app/src/main/cpp/mesh/primitives/Sphere.h
index 7273775..6e0ba7d 100644
--- a/app/src/main/cpp/mesh/primitives/Sphere.h
+++ b/app/src/main/cpp/mesh/primitives/Sphere.h
@@ -11,7 +11,7 @@
class Sphere : public Mesh {
public :
Sphere(float radius, int latitudeSegments,
- int longitudeSegments);
+ int longitudeSegments, ShaderLoader* shaderLoader);
private:
float radius_;
diff --git a/app/src/main/cpp/shader/Shader.cpp b/app/src/main/cpp/shader/Shader.cpp
index 458b1d5..211a6a9 100644
--- a/app/src/main/cpp/shader/Shader.cpp
+++ b/app/src/main/cpp/shader/Shader.cpp
@@ -5,13 +5,17 @@
#include "Shader.h"
#include "AndroidOut.h"
#include "gtc/type_ptr.hpp"
+#include "utils.h"
+#include "Utility.h"
#include
#include
#include
#include
+#include
+#include
-Shader::Shader(std::string &vertexShaderPath, std::string &fragmentShaderPath) {
+Shader::Shader() {
program_ = glCreateProgram();
GLuint vertexShader = compileShader(vertexShaderSource, GL_VERTEX_SHADER);
GLuint fragmentShader = compileShader(fragmentShaderSource, GL_FRAGMENT_SHADER);
@@ -37,34 +41,128 @@ Shader::Shader(std::string &vertexShaderPath, std::string &fragmentShaderPath) {
glDeleteProgram(program_);
} else {
projectionMatrixLocation_ = glGetUniformLocation(program_, "uProjection");
- diffuseColorLocation_ = glGetUniformLocation(program_, "uMaterial.diffuseColor");
- useDiffText_ = glGetUniformLocation(program_, "uMaterial.useTexture");
- ambientColorLocation_ = glGetUniformLocation(program_, "uMaterial.ambientColor");
- lightColorLocation_ = glGetUniformLocation(program_, "uLight.color");
- lightAmbientIntensityLocation_ = glGetUniformLocation(program_, "uLight.ambientIntensity");
- diffuseIntensityLocation = glGetUniformLocation(program_, "uLight.diffuseIntensity");
- lightDirectionLocation = glGetUniformLocation(program_, "uLight.direction");
- lightTypeLocation = glGetUniformLocation(program_, "uLight.type");
+ modelProjectionMatrixLocation_ = glGetUniformLocation(program_, "uModelProjection");
+ materialLoc.diffuseColor = glGetUniformLocation(program_, "uMaterial.diffuseColor");
+ materialLoc.useDiffText_ = glGetUniformLocation(program_, "uMaterial.useTexture");
+ materialLoc.ambientColor = glGetUniformLocation(program_, "uMaterial.ambientColor");
+ lightLoc.color = glGetUniformLocation(program_, "uLight.light.color");
+ lightLoc.ambientIntensity = glGetUniformLocation(program_, "uLight.light.ambientIntensity");
+ lightLoc.diffuseIntensity = glGetUniformLocation(program_, "uLight.light.diffuseIntensity");
+ lightLoc.direction = glGetUniformLocation(program_, "uLight.direction");
+ lightTypeLocation = glGetUniformLocation(program_, "uLight.light.type");
positionAttribute_ = glGetAttribLocation(program_, "inPosition");
normalAttribute = glGetAttribLocation(program_, "inNormal");
+ tangentAttribute = glGetAttribLocation(program_, "inTangent");
uvAttribute_ = glGetAttribLocation(program_, "inUV");
- samplerSpecularExponentLocation = glGetUniformLocation(program_, "uSpecTexture");
- specularColorLocation = glGetUniformLocation(program_, "uMaterial.specularColor");
- cameraLocalPosLocation = glGetUniformLocation(program_, "uCameraLocalPos");
- if (projectionMatrixLocation_ == -1
- || positionAttribute_ == -1
- || useDiffText_ == -1
- || diffuseColorLocation_ == -1
- || uvAttribute_ == -1) {
+ materialLoc.samplerSpecularExponentLocation = glGetUniformLocation(program_,
+ "uSpecTexture");
+ materialLoc.normalTextureLocation = glGetUniformLocation(program_,
+ "uNormalTexture");
+ materialLoc.specularColor = glGetUniformLocation(program_, "uMaterial.specularColor");
+ cameraLocalPosLocation_ = glGetUniformLocation(program_, "uCameraLocalPos");
+ numberOfPointLightLocation_ = glGetUniformLocation(program_, "uNumOfLights");
+ numberOfSpotLightLocation_ = glGetUniformLocation(program_, "uNumOfSpotLights");
+
+ loadPointLightUniforms();
+
+ if (projectionMatrixLocation_ == INVALID_UNIFORM_LOCATION
+ || positionAttribute_ == INVALID_UNIFORM_LOCATION
+ || materialLoc.useDiffText_ == INVALID_UNIFORM_LOCATION
+ || materialLoc.diffuseColor == INVALID_UNIFORM_LOCATION
+ || uvAttribute_ == INVALID_UNIFORM_LOCATION) {
glDeleteProgram(program_);
}
}
-
+ bind();
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}
+void Shader::loadSpotLightUniforms() {
+ for (int i = 0; i < ARRAY_SIZE_IN_ELEMENTS(spotLightLocation); ++i) {
+ char name[128];
+ memset(name, 0, sizeof(name));
+ SNPRINTF(name, sizeof(name), "uSpotLights[%d].light.color", i);
+ spotLightLocation[i].color = glGetUniformLocation(program_, name);
+
+ SNPRINTF(name, sizeof(name), "uSpotLights[%d].light.ambientIntensity", i);
+ spotLightLocation[i].ambientIntensity = glGetUniformLocation(program_, name);
+
+ SNPRINTF(name, sizeof(name), "uSpotLights[%d].localPos", i);
+ spotLightLocation[i].localPosition = glGetUniformLocation(program_, name);
+
+ SNPRINTF(name, sizeof(name), "uSpotLights[%d].light.diffuseIntensity", i);
+ spotLightLocation[i].diffuseIntensity = glGetUniformLocation(program_, name);
+
+ SNPRINTF(name, sizeof(name), "uSpotLights[%d].atten.constant", i);
+ spotLightLocation[i].attenuation.constant = glGetUniformLocation(program_, name);
+
+ SNPRINTF(name, sizeof(name), "uSpotLights[%d].atten.linear", i);
+ spotLightLocation[i].attenuation.linear = glGetUniformLocation(program_, name);
+
+ SNPRINTF(name, sizeof(name), "uSpotLights[%d].atten.exp", i);
+ spotLightLocation[i].attenuation.exp = glGetUniformLocation(program_, name);
+
+ SNPRINTF(name, sizeof(name), "uSpotLights[%d].direction", i);
+ spotLightLocation[i].direction = glGetUniformLocation(program_, name);
+
+ SNPRINTF(name, sizeof(name), "uSpotLights[%d].cutOff", i);
+ spotLightLocation[i].cutOff = glGetUniformLocation(program_, name);
+
+ if (
+ spotLightLocation[i].color == INVALID_UNIFORM_LOCATION ||
+ spotLightLocation[i].ambientIntensity == INVALID_UNIFORM_LOCATION ||
+ spotLightLocation[i].localPosition == INVALID_UNIFORM_LOCATION ||
+ spotLightLocation[i].diffuseIntensity == INVALID_UNIFORM_LOCATION ||
+ spotLightLocation[i].attenuation.constant == INVALID_UNIFORM_LOCATION ||
+ spotLightLocation[i].attenuation.linear == INVALID_UNIFORM_LOCATION ||
+ spotLightLocation[i].attenuation.exp == INVALID_UNIFORM_LOCATION
+ ) {
+ glDeleteProgram(program_);
+ }
+ }
+}
+
+void Shader::loadPointLightUniforms() {
+ for (int i = 0; i < ARRAY_SIZE_IN_ELEMENTS(pointLightLocation); ++i) {
+ char name[128];
+ memset(name, 0, sizeof(name));
+ SNPRINTF(name, sizeof(name), "uPointLights[%d].light.color", i);
+ pointLightLocation[i].color = glGetUniformLocation(program_, name);
+
+ SNPRINTF(name, sizeof(name), "uPointLights[%d].light.ambientIntensity", i);
+ pointLightLocation[i].ambientIntensity = glGetUniformLocation(program_, name);
+
+ SNPRINTF(name, sizeof(name), "uPointLights[%d].localPos", i);
+ pointLightLocation[i].localPosition = glGetUniformLocation(program_, name);
+
+ SNPRINTF(name, sizeof(name), "uPointLights[%d].light.diffuseIntensity", i);
+ pointLightLocation[i].diffuseIntensity = glGetUniformLocation(program_, name);
+
+ SNPRINTF(name, sizeof(name), "uPointLights[%d].atten.constant", i);
+ pointLightLocation[i].attenuation.constant = glGetUniformLocation(program_, name);
+
+ SNPRINTF(name, sizeof(name), "uPointLights[%d].atten.linear", i);
+ pointLightLocation[i].attenuation.linear = glGetUniformLocation(program_, name);
+
+ SNPRINTF(name, sizeof(name), "uPointLights[%d].atten.exp", i);
+ pointLightLocation[i].attenuation.exp = glGetUniformLocation(program_, name);
+
+ if (
+ pointLightLocation[i].color == INVALID_UNIFORM_LOCATION ||
+ pointLightLocation[i].ambientIntensity == INVALID_UNIFORM_LOCATION ||
+ pointLightLocation[i].localPosition == INVALID_UNIFORM_LOCATION ||
+ pointLightLocation[i].diffuseIntensity == INVALID_UNIFORM_LOCATION ||
+ pointLightLocation[i].attenuation.constant == INVALID_UNIFORM_LOCATION ||
+ pointLightLocation[i].attenuation.linear == INVALID_UNIFORM_LOCATION ||
+ pointLightLocation[i].attenuation.exp == INVALID_UNIFORM_LOCATION
+ ) {
+ glDeleteProgram(program_);
+ }
+ }
+}
+
GLint Shader::getPositionAttrib() const {
return positionAttribute_;
}
@@ -101,47 +199,174 @@ std::string Shader::readFile(std::string &fileName) const {
void Shader::bind() const {
+ CHECK_GL_ERROR();
glUseProgram(program_);
+ CHECK_GL_ERROR();
}
void Shader::unbind() const {
glUseProgram(0);
}
-void Shader::setProjectionMatrix(const Mat4f *projectionMatrix) const{
+void Shader::setProjectionMatrix(const Mat4f *projectionMatrix) const {
glUniformMatrix4fv(projectionMatrixLocation_, 1, GL_TRUE, &projectionMatrix->m[0][0]);
}
+void Shader::setModelMatrix(const Mat4f &matrix) const {
+ glUniformMatrix4fv(modelProjectionMatrixLocation_, 1, GL_TRUE, &matrix.m[0][0]);
+}
+
GLint Shader::getDiffColorLocation() const {
- return diffuseColorLocation_;
+ return materialLoc.diffuseColor;
}
GLint Shader::getAmbientColorLocation() const {
- return ambientColorLocation_;
+ return materialLoc.ambientColor;
}
GLint Shader::getUseDiffTextureLocation() const {
- return useDiffText_;
+ return materialLoc.useDiffText_;
}
GLint Shader::getLightColorLocation() const {
- return lightColorLocation_;
+ return lightLoc.color;
}
GLint Shader::getAmbientIntensityLocation() const {
- return lightAmbientIntensityLocation_;
+ return lightLoc.ambientIntensity;
}
GLint Shader::getSpecularExponentLocation() const {
- return samplerSpecularExponentLocation;
+ return materialLoc.samplerSpecularExponentLocation;
+}
+GLint Shader::getNormalTexLocation() const {
+ return materialLoc.normalTextureLocation;
}
GLint Shader::getSpecularColorLocation() const {
- return specularColorLocation;
+ return materialLoc.specularColor;
}
GLint Shader::getCameraLocalPosLocation() const {
- return cameraLocalPosLocation;
+ return cameraLocalPosLocation_;
+}
+
+GLint Shader::getLightDirectionLocation() const {
+ return lightLoc.direction;
+}
+
+GLint Shader::getDiffuseIntensityLocation() const {
+ return lightLoc.diffuseIntensity;
+}
+
+bool Shader::isValidIndex(int index) const {
+ if (index >= 0 && index < MAX_POINT_LIGHTS) {
+ return true;
+ } else {
+ std::cerr << "Index out of bounds: " << index << std::endl;
+ return false;
+ }
+}
+
+GLint Shader::getPointLightColor(int index) const {
+ if (isValidIndex(index)) {
+ return pointLightLocation[index].color;
+ } else {
+ return -1; // or appropriate error value
+ }
+}
+
+GLint Shader::getPointLightAmbientIntensity(int index) const {
+ if (isValidIndex(index)) {
+ return pointLightLocation[index].ambientIntensity;
+ } else {
+ return -1; // or appropriate error value
+ }
+}
+
+GLint Shader::getPointLightDiffuseIntensity(int index) const {
+ if (isValidIndex(index)) {
+ return pointLightLocation[index].diffuseIntensity;
+ } else {
+ return -1; // or appropriate error value
+ }
+}
+
+
+GLint Shader::getPointLightLocalPosition(int index) const {
+ if (isValidIndex(index)) {
+ return pointLightLocation[index].localPosition;
+ } else {
+ return -1; // or appropriate error value
+ }
+}
+
+GLint Shader::getPointLightAttenuationConstant(int index) const {
+ if (isValidIndex(index)) {
+ return pointLightLocation[index].attenuation.constant;
+ } else {
+ return 0; // or appropriate error value
+ }
+}
+
+GLint Shader::getPointLightAttenuationLinear(int index) const {
+ if (isValidIndex(index)) {
+ return pointLightLocation[index].attenuation.linear;
+ } else {
+ return 0; // or appropriate error value
+ }
+}
+
+GLint Shader::getPointLightAttenuationExp(int index) const {
+ if (isValidIndex(index)) {
+ return pointLightLocation[index].attenuation.exp;
+ } else {
+ return 0; // or appropriate error value
+ }
+}
+
+GLint Shader::getNumberOfLightsLocation() const {
+ return numberOfPointLightLocation_;
+}
+
+GLint Shader::getNumberOfSpotLightsLocation() const {
+ return numberOfSpotLightLocation_;
+}
+
+GLint Shader::getSpotLightColor(int index) const {
+ return spotLightLocation->color;
+}
+
+GLint Shader::getSpotLightAmbientIntensity(int index) const {
+ return spotLightLocation->ambientIntensity;
+}
+
+GLint Shader::getSpotLightDiffuseIntensity(int index) const {
+ return spotLightLocation->diffuseIntensity;
+}
+
+GLint Shader::getSpotLightLocalPosition(int index) const {
+ return spotLightLocation->localPosition;
+}
+
+GLint Shader::getSpotLightAttenuationConstant(int index) const {
+ return spotLightLocation->attenuation.constant;
+}
+
+GLint Shader::getSpotLightAttenuationLinear(int index) const {
+ return spotLightLocation->attenuation.linear;
+}
+
+GLint Shader::getSpotLightAttenuationExp(int index) const {
+ return spotLightLocation->attenuation.exp;
+}
+
+GLint Shader::getSpotLightDirection(int index) const {
+ return spotLightLocation->direction;
+}
+
+GLint Shader::getSpotLightCutOff(int index) const {
+ return spotLightLocation->cutOff;
}
diff --git a/app/src/main/cpp/shader/Shader.h b/app/src/main/cpp/shader/Shader.h
index b85004a..f90bbae 100644
--- a/app/src/main/cpp/shader/Shader.h
+++ b/app/src/main/cpp/shader/Shader.h
@@ -11,15 +11,18 @@
#include "detail/type_mat4x4.hpp"
#include "math/mat4f.h"
+const int MAX_POINT_LIGHTS = 10;
+const int MAX_SPOT_LIGHTS = 10;
+
class Shader {
public:
- GLint diffuseIntensityLocation = 0;
- GLint lightDirectionLocation = 0;
+
GLint lightTypeLocation = 0;
GLint normalAttribute = 0;
+ GLint tangentAttribute = 0;
- Shader(std::string &vertexShaderPath, std::string &fragmentShaderPath);
+ Shader();
void bind() const;
@@ -47,24 +50,113 @@ class Shader {
GLint getCameraLocalPosLocation() const;
+ GLint getLightDirectionLocation() const;
+
+ GLint getDiffuseIntensityLocation() const;
+
+ GLint getNumberOfLightsLocation() const;
+
+ GLint getPointLightColor(int index) const;
+
+ GLint getPointLightAmbientIntensity(int index) const;
+
+ GLint getPointLightDiffuseIntensity(int index) const;
+
+ GLint getPointLightLocalPosition(int index) const;
+
+ GLint getPointLightAttenuationConstant(int index) const;
+
+ GLint getPointLightAttenuationLinear(int index) const;
+
+ GLint getPointLightAttenuationExp(int index) const;
+
+
+ GLint getNumberOfSpotLightsLocation() const;
+
+ GLint getSpotLightColor(int index) const;
+
+ GLint getSpotLightAmbientIntensity(int index) const;
+
+ GLint getSpotLightDiffuseIntensity(int index) const;
+
+ GLint getSpotLightLocalPosition(int index) const;
+
+ GLint getSpotLightAttenuationConstant(int index) const;
+
+ GLint getSpotLightAttenuationLinear(int index) const;
+
+ GLint getSpotLightAttenuationExp(int index) const;
+
+ GLint getSpotLightDirection(int index) const;
+
+ GLint getSpotLightCutOff(int index) const;
+
+ GLint getNormalTexLocation() const;
+
+ void setModelMatrix(const Mat4f &matrix) const;
private:
GLuint program_ = 0;
GLint projectionMatrixLocation_ = 0;
+ GLint modelProjectionMatrixLocation_ = 0;
GLint positionAttribute_ = 0;
GLint uvAttribute_ = 0;
- GLint diffuseColorLocation_ = 0;
- GLint useDiffText_ = 0;
- GLint ambientColorLocation_ = 0;
- GLint lightColorLocation_ = 0;
- GLint lightAmbientIntensityLocation_ = 0;
- GLint samplerSpecularExponentLocation = 0;
- GLint specularColorLocation = 0;
- GLint cameraLocalPosLocation = 0;
+ GLint cameraLocalPosLocation_ = 0;
+ GLint numberOfPointLightLocation_ = 0;
+ GLint numberOfSpotLightLocation_ = 0;
+
+ struct {
+ GLint diffuseColor = 0;
+ GLint useDiffText_ = 0;
+ GLint ambientColor = 0;
+ GLint samplerSpecularExponentLocation = 0;
+ GLint normalTextureLocation = 0;
+ GLint specularColor = 0;
+ } materialLoc;
+
+ struct {
+ GLint color = 0;
+ GLint ambientIntensity = 0;
+ GLint diffuseIntensity = 0;
+ GLint direction = 0;
+ } lightLoc;
+
+ struct {
+ GLint color = 0;
+ GLint ambientIntensity = 0;
+ GLint diffuseIntensity = 0;
+ GLint localPosition = 0;
+ struct {
+ GLint constant = 1.0;
+ GLint linear = 0.0;
+ GLint exp = 0.0;
+ } attenuation;
+ } pointLightLocation[MAX_POINT_LIGHTS];
+
+ struct {
+ GLint color = 0;
+ GLint ambientIntensity = 0;
+ GLint diffuseIntensity = 0;
+ GLint localPosition = 0;
+ GLint direction = 0;
+ GLint cutOff = 0;
+ struct {
+ GLint constant = 1.0;
+ GLint linear = 0.0;
+ GLint exp = 0.0;
+ } attenuation;
+ } spotLightLocation[MAX_SPOT_LIGHTS];
std::string readFile(std::string &fileName) const;
static GLuint compileShader(const char *shaderCode, GLenum shaderType);
+ bool isValidIndex(int index) const;
+
+ void loadPointLightUniforms();
+
+ void loadSpotLightUniforms();
+
+
};
diff --git a/app/src/main/cpp/shader/ShaderLoader.cpp b/app/src/main/cpp/shader/ShaderLoader.cpp
new file mode 100644
index 0000000..f543c01
--- /dev/null
+++ b/app/src/main/cpp/shader/ShaderLoader.cpp
@@ -0,0 +1,32 @@
+//
+// Created by Dark Matter on 6/6/24.
+//
+
+#include "ShaderLoader.h"
+ShaderLoader::ShaderLoader() : shaders_() {
+ std::shared_ptr shader = std::make_shared();
+ std::string name("default");
+ shaders_.insert(std::make_pair(name, shader));
+}
+
+ Shader* ShaderLoader::load(const char* name) {
+ std::string shaderName(name);
+ auto it = shaders_.find(shaderName);
+ if (it != shaders_.end()) {
+ return it->second.get();
+ } else {
+ return nullptr; // or handle the case where the shader is not found
+ }
+}
+
+void ShaderLoader::setNumOfLights(int count) const {
+ for (const auto &item: shaders_){
+ glUniform1i(item.second->getNumberOfLightsLocation(), count);
+ }
+}
+
+void ShaderLoader::setNumOfSpotLights(int count) const {
+ for (const auto &item: shaders_){
+ glUniform1i(item.second->getNumberOfSpotLightsLocation(), count);
+ }
+}
diff --git a/app/src/main/cpp/shader/ShaderLoader.h b/app/src/main/cpp/shader/ShaderLoader.h
new file mode 100644
index 0000000..2e2ae47
--- /dev/null
+++ b/app/src/main/cpp/shader/ShaderLoader.h
@@ -0,0 +1,25 @@
+//
+// Created by Dark Matter on 6/6/24.
+//
+
+#ifndef LEARNOPENGL_SHADERLOADER_H
+#define LEARNOPENGL_SHADERLOADER_H
+
+#include "Shader.h"
+#include
+#include
+#include
+
+class ShaderLoader {
+private:
+ std::unordered_map> shaders_;
+
+public:
+ ShaderLoader();
+ void setNumOfLights(int count) const;
+ void setNumOfSpotLights(int count) const;
+ Shader *load(const char *name);
+};
+
+
+#endif //LEARNOPENGL_SHADERLOADER_H
diff --git a/app/src/main/cpp/shader/frag.frag b/app/src/main/cpp/shader/frag.frag
index c1b4acd..754bc76 100644
--- a/app/src/main/cpp/shader/frag.frag
+++ b/app/src/main/cpp/shader/frag.frag
@@ -1,9 +1,12 @@
#version 300 es
precision mediump float;
-
+const int MAX_POINT_LIGHTS = 10;
+const int MAX_SPOT_LIGHTS = 10;
in vec2 fragUV;
in vec3 normal0;
in vec3 localPos0;
+in vec3 tangent0;
+in vec3 worldPos0;
struct Material {
vec3 diffuseColor;
@@ -17,52 +20,134 @@ struct Light {
float ambientIntensity;
float type;
float diffuseIntensity;
+
+};
+
+struct DirectionalLight {
+ Light light;
vec3 direction;
};
+struct Attenuation {
+ float constant;
+ float linear;
+ float exp;
+};
+struct PointLight {
+ Light light;
+ Attenuation atten;
+ vec3 localPos;
+};
+
+struct SpotLight {
+ PointLight pointLight;
+ vec3 direction;
+ float cutOff;
+};
+
+
uniform sampler2D uTexture;
uniform sampler2D uSpecTexture;
+uniform sampler2D uNormalTexture;
uniform Material uMaterial;
-uniform Light uLight;
+uniform DirectionalLight uLight;
+uniform int uNumOfLights;
+uniform PointLight uPointLights[MAX_POINT_LIGHTS];
+uniform int uNumOfSpotLights;
+uniform SpotLight uSpotLights[MAX_SPOT_LIGHTS];
uniform vec3 uCameraLocalPos;
out vec4 outColor;
-void main() {
- vec4 finalColor = vec4(1.0, 1.0, 1.0, 1.0);
+vec3 calculateBumpedNormal(){
+ vec3 normal = normalize(normal0);
+ vec3 tangent = normalize(tangent0);
+ tangent = normalize(tangent - dot(tangent, normal) * normal);
+ vec3 biTangent = cross(tangent, normal);
+ vec3 bumpedNormal = texture(uNormalTexture, fragUV).xyz;
+ bumpedNormal = 2.0 * bumpedNormal - vec3(1.0, 1.0,1.0);
+ vec3 newNormal;
+ mat3 tbn = mat3(tangent, biTangent, normal);
+ newNormal = tbn * bumpedNormal;
+ newNormal = normalize(newNormal);
+ return newNormal;
+
+}
+
+vec4 calculateLightInternal(Light light, vec3 direction, vec3 normal) {
+
+ vec3 ambientColor = uMaterial.ambientColor * light.color * light.ambientIntensity;
+
vec4 diffuseColor = vec4(0.0, 0.0, 0.0, 1.0);
vec4 specularColor = vec4(0.0, 0.0, 0.0, 1.0);
-
- if (uMaterial.useTexture) {
- vec4 textureColor = texture(uTexture, fragUV);
- finalColor = textureColor;
+ float diffuseFactor = max(dot(normal, normalize(direction)), 0.0);
+
+ if (diffuseFactor > 0.0) {
+ diffuseColor = vec4(light.color, 1.0) * light.diffuseIntensity * diffuseFactor * vec4(uMaterial.diffuseColor, 1.0);
+ vec3 pixelToCamera = normalize(uCameraLocalPos - localPos0);
+ vec3 lightReflect = normalize(reflect(direction, normal));
+ float specularFactor = dot(pixelToCamera, lightReflect);
+ if (specularFactor > 0.0) {
+ float specularExponent = texture(uSpecTexture, fragUV).r * 255.0;
+ specularFactor = pow(specularFactor, specularExponent);
+ specularColor = vec4(light.color, 1.0) * vec4(uMaterial.specularColor, 1.0) * specularFactor;
+ }
}
- vec3 ambientColor = uMaterial.ambientColor * uLight.color * uLight.ambientIntensity;
+ vec4 color = clamp((vec4(ambientColor, 1.0) + diffuseColor + specularColor), 0.0, 1.0);
+ return color;
+}
- vec3 Normal = normalize(normal0);
+vec4 calculateDirectionalLight(vec3 normal) {
+ vec4 color = calculateLightInternal(uLight.light, uLight.direction, normal);
+ return color;
+}
- if (uLight.type == 1.0) {
- float diffuseFactor = max(dot(Normal, normalize(uLight.direction)), 0.0);
- if(diffuseFactor > 0.0){
+vec4 calculatePointLight(PointLight pointLight, vec3 normal) {
+ vec3 direction = localPos0 - pointLight.localPos;
+ float distance = length(direction);
+ direction = normalize(direction);
+ vec4 color = calculateLightInternal(pointLight.light, direction, normal);
+ float attenuation = pointLight.atten.constant + pointLight.atten.linear * distance + pointLight.atten.exp * distance * distance;
- diffuseColor = vec4(uLight.color, 1.0) * uLight.diffuseIntensity * diffuseFactor * vec4(uMaterial.diffuseColor, 1.0);
+ return color / attenuation;
+}
- vec3 pixelToCamera = normalize(uCameraLocalPos - localPos0);
- vec3 lightReflect = normalize(reflect(uLight.direction , Normal));
+vec4 calculateSpotLight(SpotLight spotLight, vec3 normal) {
+ vec3 lightToPixel = normalize(localPos0 - spotLight.pointLight.localPos);
+ float spotLightFactor = dot(lightToPixel, spotLight.direction);
+ if(spotLightFactor > spotLight.cutOff){
+ vec4 color = calculatePointLight(spotLight.pointLight, normal);
+ float spotLightIntensity = (1.0 - (1.0 - spotLightFactor)/ (1.0 - cos(spotLight.cutOff)));
+ return color * spotLightIntensity;
+ }
+ return vec4(0.0, 0.0, 0.0, 0.0);
+}
- float specularFactor = dot(pixelToCamera, lightReflect);
- if(specularFactor > 0.0){
- float specularExponent = texture(uSpecTexture, fragUV).r * 255.0;
- specularFactor = pow(specularFactor, specularExponent);
- specularColor = vec4(uLight.color , 1.0) * vec4(uMaterial.specularColor, 1.0) * specularFactor;
- }
+void main() {
- }
- }else{
- diffuseColor = vec4(uMaterial.diffuseColor, 1.0);
+ vec4 finalColor = vec4(1.0, 1.0, 1.0, 1.0);
+ vec4 diffuseColor = vec4(0.0, 0.0, 0.0, 1.0);
+ vec4 specularColor = vec4(0.0, 0.0, 0.0, 1.0);
+
+ if (uMaterial.useTexture) {
+ vec4 textureColor = texture(uTexture, fragUV);
+ finalColor = textureColor;
}
+ vec3 normal = calculateBumpedNormal();
+ vec4 lighColor = calculateDirectionalLight(normal);
+
+ for(int i = 0 ; i < uNumOfLights; i++){
+ PointLight pointLight = uPointLights[i];
+ lighColor += calculatePointLight(pointLight, normal);
+ }
+
+ for(int i = 0 ; i < uNumOfSpotLights; i++){
+ SpotLight spotLight = uSpotLights[i];
+ lighColor += calculateSpotLight(spotLight, normal);
+ }
+
+ outColor = finalColor * lighColor;
- outColor = finalColor * clamp((vec4(ambientColor, 1.0) + diffuseColor + specularColor), 0.0, 1.0 );
}
diff --git a/app/src/main/cpp/shader/vert.vert b/app/src/main/cpp/shader/vert.vert
index 2bf5b1c..7fbeff2 100644
--- a/app/src/main/cpp/shader/vert.vert
+++ b/app/src/main/cpp/shader/vert.vert
@@ -2,16 +2,22 @@
in vec3 inPosition;
in vec2 inUV;
in vec3 inNormal;
+in vec3 inTangent;
out vec2 fragUV;
out vec3 normal0;
out vec3 localPos0;
+out vec3 tangent0;
+out vec3 worldPos0;
uniform mat4 uProjection;
+uniform mat4 uModelProjection;
void main() {
fragUV = inUV;
gl_Position = uProjection * vec4(inPosition, 1.0);
- normal0 = inNormal;
localPos0 = inPosition;
+ normal0 = (uModelProjection * vec4(inNormal, 0.0)).xyz;
+ tangent0 = (uModelProjection * vec4(inTangent, 0.0)).xyz;
+ worldPos0 = (uModelProjection * vec4(inPosition, 1.0)).xyz;
}
\ No newline at end of file
diff --git a/app/src/main/cpp/third_party/assimp/Exporter.hpp b/app/src/main/cpp/third_party/assimp/Exporter.hpp
index fc713ed..840290d 100644
--- a/app/src/main/cpp/third_party/assimp/Exporter.hpp
+++ b/app/src/main/cpp/third_party/assimp/Exporter.hpp
@@ -161,7 +161,7 @@ class ASSIMP_API Exporter {
// -------------------------------------------------------------------
/** Supplies a custom progress handler to the exporter. This
- * interface exposes an #Update() callback, which is called
+ * interface exposes an #update() callback, which is called
* more or less periodically (please don't sue us if it
* isn't as periodically as you'd like it to have ...).
* This can be used to implement progress bars and loading
diff --git a/app/src/main/cpp/third_party/assimp/Importer.hpp b/app/src/main/cpp/third_party/assimp/Importer.hpp
index a3a0d9e..4d81f4a 100644
--- a/app/src/main/cpp/third_party/assimp/Importer.hpp
+++ b/app/src/main/cpp/third_party/assimp/Importer.hpp
@@ -347,7 +347,7 @@ class ASSIMP_API Importer {
// -------------------------------------------------------------------
/** Supplies a custom progress handler to the importer. This
- * interface exposes an #Update() callback, which is called
+ * interface exposes an #update() callback, which is called
* more or less periodically (please don't sue us if it
* isn't as periodically as you'd like it to have ...).
* This can be used to implement progress bars and loading
diff --git a/app/src/main/cpp/transform/Transform.cpp b/app/src/main/cpp/transform/Transform.cpp
index 1ea4d56..d68990c 100644
--- a/app/src/main/cpp/transform/Transform.cpp
+++ b/app/src/main/cpp/transform/Transform.cpp
@@ -4,6 +4,7 @@
#include "Transform.h"
#include "AndroidOut.h"
+#include "geometric.hpp"
void Transform::setScale(float scaleX, float scaleY, float scaleZ) {
this->scale_.x = scaleX;
@@ -12,11 +13,12 @@ void Transform::setScale(float scaleX, float scaleY, float scaleZ) {
}
void Transform::setPosition(float x, float y, float z) {
- this->position_.x = x;
- this->position_.y = y;
- this->position_.z = z;
+ this->position.x = x;
+ this->position.y = y;
+ this->position.z = z;
}
+
void Transform::setRotation(float x, float y, float z) {
this->rotation_.x = x;
this->rotation_.y = y;
@@ -31,32 +33,61 @@ void Transform::rotate(float x, float y, float z) {
Mat4f Transform::getReversedTranslation() const {
Mat4f reversedTranslation;
- reversedTranslation.InitTranslation(-position_.x, - position_.y, -position_.z );
+ reversedTranslation.initTranslation(-position.x, -position.y, -position.z);
return reversedTranslation;
}
+glm::vec3 Transform::worldToLocal(glm::vec3 worldPosition) const{
+ Mat4f cameraToLocalTranslation = getReversedTranslation();
+ Mat4f cameraToLocalRotation = getReversedRotation();
+ Mat4f cameraToLocalTransformation = cameraToLocalRotation * cameraToLocalTranslation;
+ glm::vec4 cameraWorldPos = glm::vec4 (worldPosition, 1.0);
+ glm::vec4 cameraLocalPos = cameraToLocalTransformation * cameraWorldPos;
+ return cameraWorldPos;
+}
+
Mat4f Transform::getReversedRotation() const{
Mat4f reversedTranslation;
- reversedTranslation.InitRotationMatrix(-rotation_.x, - rotation_.y, -rotation_.z );
+ reversedTranslation.initRotationMatrix(-rotation_.x, -rotation_.y, -rotation_.z);
return reversedTranslation;
}
-Mat4f Transform::matrix() {
+Mat4f Transform::matrix() const {
Mat4f rotMat;
- rotMat.InitRotationMatrix(rotation_.x, rotation_.y, rotation_.z);
+ rotMat.initRotationMatrix(rotation_.x, rotation_.y, rotation_.z);
Mat4f transMat;
- transMat.InitTranslation(position_.x, position_.y, position_.z);
+ transMat.initTranslation(position.x, position.y, position.z);
Mat4f scaleMat;
- scaleMat.InitScaleMatrix(scale_.x, scale_.y, scale_.z);
+ scaleMat.initScaleMatrix(scale_.x, scale_.y, scale_.z);
return transMat * rotMat * scaleMat;
}
Transform::Transform() :
- position_(0, 0, 0),
+ position(0, 0, 0),
rotation_(0, 0, 0, 0),
scale_(1, 1, 1) {
}
+
+glm::vec3 Transform::getPosition() {
+ return position;
+}
+
+void Transform::setYPosition(float y) {
+ this->position.y = y;
+}
+
+float Transform::getPositionY() {
+ return position.y;
+}
+
+glm::vec3 Transform::worldDirectionToLocal(glm::vec3 direction) const {
+ Mat3f world3Mat(matrix());
+
+ //TODO non-uniform scaling is not supported yet. Calculate the inverse of the matrix instead of using transpose
+ return -glm::normalize(world3Mat.Transpose() *
+ direction);
+}
diff --git a/app/src/main/cpp/transform/Transform.h b/app/src/main/cpp/transform/Transform.h
index 288ddf2..d259925 100644
--- a/app/src/main/cpp/transform/Transform.h
+++ b/app/src/main/cpp/transform/Transform.h
@@ -12,20 +12,27 @@
class Transform {
public :
+ glm::vec3 position;
+
Transform();
void setScale(float scaleX, float scaleY, float scaleZ);
void setPosition(float x, float y, float z);
+ void setYPosition( float y);
+ float getPositionY();
void setRotation(float x, float y, float z);
void rotate(float x, float y, float z);
- Mat4f matrix();
+ Mat4f matrix() const;
+ glm::vec3 getPosition();
Mat4f getReversedRotation() const;
Mat4f getReversedTranslation() const;
-private:
- glm::vec3 position_;
+ glm::vec3 worldToLocal(glm::vec3 worldPosition) const;
+
+ glm::vec3 worldDirectionToLocal(glm::vec3 direction) const;
+
+protected:
Quaternion rotation_;
glm::vec3 scale_;
-
};
diff --git a/app/src/main/cpp/unused/ShaderBase.cpp b/app/src/main/cpp/unused/ShaderBase.cpp
index 6224d0b..812f8cf 100644
--- a/app/src/main/cpp/unused/ShaderBase.cpp
+++ b/app/src/main/cpp/unused/ShaderBase.cpp
@@ -77,7 +77,7 @@ ShaderBase *ShaderBase::loadShader(
}
GLuint ShaderBase::loadShader(GLenum shaderType, const std::string &shaderSource) {
- Utility::assertGlError();
+ CHECK_GL_ERROR();
GLuint shader = glCreateShader(shaderType);
if (shader) {
auto *shaderRawString = (GLchar *) shaderSource.c_str();
diff --git a/app/src/main/cpp/utils.h b/app/src/main/cpp/utils.h
index a145f43..33b3843 100644
--- a/app/src/main/cpp/utils.h
+++ b/app/src/main/cpp/utils.h
@@ -6,13 +6,23 @@
#define LEARNOPENGL_UTILS_H
#include
#include
-#define ASSIMP_LOAD_FLAGS (aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_FlipUVs | aiProcess_JoinIdenticalVertices )
+#define ASSIMP_LOAD_FLAGS (aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_FlipUVs | aiProcess_JoinIdenticalVertices | aiProcess_CalcTangentSpace )
#define COLOR_TEXTURE_UNIT GL_TEXTURE0
#define COLOR_TEXTURE_UNIT_INDEX 0
-
+#define NORMAL_UNIT GL_TEXTURE1
+#define NORMAL_UNIT_INDEX 1
#define SPECULAR_EXPONENT_UNIT GL_TEXTURE6
#define SPECULAR_EXPONENT_UNIT_INDEX 6
+
+#define ARRAY_SIZE_IN_ELEMENTS(a) (sizeof(a)/sizeof(a[0]))
+
+#define INVALID_UNIFORM_LOCATION -1
+
+#ifdef ANDROID
+#define SNPRINTF snprintf
+#endif
+
#endif //LEARNOPENGL_UTILS_H
diff --git a/readme.md b/readme.md
index eadda23..d3b2f92 100644
--- a/readme.md
+++ b/readme.md
@@ -55,7 +55,7 @@ Welcome to the 3D Model Viewer for Android! This project aims to provide a light
## Usage (Under Development)
1. **Load a Model:** (Currently loaded from assets folder)
- Put 3d model in assets folder. Update the path in ModelImporter.
+ Put 3d model in assets folder. update the path in ModelImporter.
2. **View Controls:**
- ~~**rotate:** Use one finger to rotate the model.~~
diff --git a/screenshots/Screenshot_20240606_190823.png b/screenshots/Screenshot_20240606_190823.png
new file mode 100644
index 0000000..e9b681f
Binary files /dev/null and b/screenshots/Screenshot_20240606_190823.png differ