From d4876bbba52bdd5ebab9ec9aa040e4964e814394 Mon Sep 17 00:00:00 2001 From: Benjamin Kyd Date: Sun, 24 Feb 2019 18:34:10 +0000 Subject: [PATCH] Rendering works but somthing's wrong with the indexing --- include/OBJLoader.h | 204 ++++++++-------------------- legacy/resources/shaders/phong.vert | 9 +- src/display.cpp | 18 +++ src/display.h | 14 +- src/main.cpp | 16 ++- src/mesh.cpp | 51 ++++++- src/mesh.h | 4 +- src/shader.cpp | 165 ++++++++++++++++++++++ src/shader.h | 33 +++++ src/util/util.cpp | 8 +- 10 files changed, 351 insertions(+), 171 deletions(-) diff --git a/include/OBJLoader.h b/include/OBJLoader.h index 758ec6f..fce5133 100644 --- a/include/OBJLoader.h +++ b/include/OBJLoader.h @@ -36,15 +36,30 @@ namespace objl // Variable Set Constructor Vector2(float X_, float Y_); // Bool Equals Operator Overload - bool operator==(const Vector2& other); + bool operator==(const Vector2& other) const + { + return (this->X == other.X && this->Y == other.Y); + } // Bool Not Equals Operator Overload - bool operator!=(const Vector2& other); + bool operator!=(const Vector2& other) const + { + return !(this->X == other.X && this->Y == other.Y); + } // Addition Operator Overload - Vector2 operator+(const Vector2& right); + Vector2 operator+(const Vector2& right) const + { + return Vector2(this->X + right.X, this->Y + right.Y); + } // Subtraction Operator Overload - Vector2 operator-(const Vector2& right); + Vector2 operator-(const Vector2& right) const + { + return Vector2(this->X - right.X, this->Y - right.Y); + } // Float Multiplication Operator Overload - Vector2 operator*(const float& other); + Vector2 operator*(const float& other) const + { + return Vector2(this->X *other, this->Y * other); + } // Positional Variables float X; @@ -61,17 +76,35 @@ namespace objl // Variable Set Constructor Vector3(float X_, float Y_, float Z_); // Bool Equals Operator Overload - bool operator==(const Vector3& other); + bool operator==(const Vector3& other) const + { + return (this->X == other.X && this->Y == other.Y && this->Z == other.Z); + } // Bool Not Equals Operator Overload - bool operator!=(const Vector3& other); + bool operator!=(const Vector3& other) const + { + return !(this->X == other.X && this->Y == other.Y && this->Z == other.Z); + } // Addition Operator Overload - Vector3 operator+(const Vector3& right); + Vector3 operator+(const Vector3& right) const + { + return Vector3(this->X + right.X, this->Y + right.Y, this->Z + right.Z); + } // Subtraction Operator Overload - Vector3 operator-(const Vector3& right); + Vector3 operator-(const Vector3& right) const + { + return Vector3(this->X - right.X, this->Y - right.Y, this->Z - right.Z); + } // Float Multiplication Operator Overload - Vector3 operator*(const float& other); + Vector3 operator*(const float& other) const + { + return Vector3(this->X * other, this->Y * other, this->Z * other); + } // Float Division Operator Overload - Vector3 operator/(const float& other); + Vector3 operator/(const float& other) const + { + return Vector3(this->X / other, this->Y / other, this->Z / other); + } // Positional Variables float X; @@ -259,134 +292,53 @@ namespace objl }; } + + #ifdef OBJL_IMPLIMENTATION #undef OBJL_IMPLIMENTATION + + namespace objl { // Structure: Vector2 // // Description: A 2D Vector that Holds Positional Data - struct Vector2 - { // Default Constructor - Vector2() + Vector2::Vector2() { X = 0.0f; Y = 0.0f; } // Variable Set Constructor - Vector2(float X_, float Y_) + Vector2::Vector2(float X_, float Y_) { X = X_; Y = Y_; } - // Bool Equals Operator Overload - bool operator==(const Vector2& other) const - { - return (this->X == other.X && this->Y == other.Y); - } - // Bool Not Equals Operator Overload - bool operator!=(const Vector2& other) const - { - return !(this->X == other.X && this->Y == other.Y); - } - // Addition Operator Overload - Vector2 operator+(const Vector2& right) const - { - return Vector2(this->X + right.X, this->Y + right.Y); - } - // Subtraction Operator Overload - Vector2 operator-(const Vector2& right) const - { - return Vector2(this->X - right.X, this->Y - right.Y); - } - // Float Multiplication Operator Overload - Vector2 operator*(const float& other) const - { - return Vector2(this->X *other, this->Y * other); - } - // Positional Variables - float X; - float Y; - }; // Structure: Vector3 // // Description: A 3D Vector that Holds Positional Data - struct Vector3 - { // Default Constructor - Vector3() + Vector3::Vector3() { X = 0.0f; Y = 0.0f; Z = 0.0f; } // Variable Set Constructor - Vector3(float X_, float Y_, float Z_) + Vector3::Vector3(float X_, float Y_, float Z_) { X = X_; Y = Y_; Z = Z_; } - // Bool Equals Operator Overload - bool operator==(const Vector3& other) const - { - return (this->X == other.X && this->Y == other.Y && this->Z == other.Z); - } - // Bool Not Equals Operator Overload - bool operator!=(const Vector3& other) const - { - return !(this->X == other.X && this->Y == other.Y && this->Z == other.Z); - } - // Addition Operator Overload - Vector3 operator+(const Vector3& right) const - { - return Vector3(this->X + right.X, this->Y + right.Y, this->Z + right.Z); - } - // Subtraction Operator Overload - Vector3 operator-(const Vector3& right) const - { - return Vector3(this->X - right.X, this->Y - right.Y, this->Z - right.Z); - } - // Float Multiplication Operator Overload - Vector3 operator*(const float& other) const - { - return Vector3(this->X * other, this->Y * other, this->Z * other); - } - // Float Division Operator Overload - Vector3 operator/(const float& other) const - { - return Vector3(this->X / other, this->Y / other, this->Z / other); - } + - // Positional Variables - float X; - float Y; - float Z; - }; - // Structure: Vertex - // - // Description: Model Vertex object that holds - // a Position, Normal, and Texture Coordinate - struct Vertex - { - // Position Vector - Vector3 Position; - - // Normal Vector - Vector3 Normal; - - // Texture Coordinate Vector - Vector2 TextureCoordinate; - }; - - struct Material - { - Material() + Material::Material() { name; Ns = 0.0f; @@ -395,63 +347,21 @@ namespace objl illum = 0; } - // Material Name - std::string name; - // Ambient Color - Vector3 Ka; - // Diffuse Color - Vector3 Kd; - // Specular Color - Vector3 Ks; - // Specular Exponent - float Ns; - // Optical Density - float Ni; - // Dissolve - float d; - // Illumination - int illum; - // Ambient Texture Map - std::string map_Ka; - // Diffuse Texture Map - std::string map_Kd; - // Specular Texture Map - std::string map_Ks; - // Specular Hightlight Map - std::string map_Ns; - // Alpha Texture Map - std::string map_d; - // Bump Map - std::string map_bump; - }; - // Structure: Mesh // // Description: A Simple Mesh Object that holds // a name, a vertex list, and an index list - struct Mesh - { // Default Constructor - Mesh() + Mesh::Mesh() { } // Variable Set Constructor - Mesh(std::vector& _Vertices, std::vector& _Indices) + Mesh::Mesh(std::vector& _Vertices, std::vector& _Indices) { Vertices = _Vertices; Indices = _Indices; } - // Mesh Name - std::string MeshName; - // Vertex List - std::vector Vertices; - // Index List - std::vector Indices; - - // Material - Material MeshMaterial; - }; // Namespace: Math // @@ -680,7 +590,7 @@ namespace objl bool listening = false; std::string meshname; - Mesh tempMesh; + objl::Mesh tempMesh; #ifdef OBJL_CONSOLE_OUTPUT const unsigned int outputEveryNth = 1000; diff --git a/legacy/resources/shaders/phong.vert b/legacy/resources/shaders/phong.vert index d987119..ac66227 100644 --- a/legacy/resources/shaders/phong.vert +++ b/legacy/resources/shaders/phong.vert @@ -1,21 +1,18 @@ #version 330 -in vec3 position; -in vec3 normal; +layout(location = 0) in vec3 position; +layout(location = 1) in vec3 normal; +layout(location = 2) in vec3 texCoord; out vec3 Normal; out vec3 FragPos; -out vec4 FragPosLightSpace; uniform mat4 model; uniform mat4 view; uniform mat4 proj; -uniform mat4 lightSpaceMatrix; - void main() { gl_Position = proj * view * model * vec4(position, 1.0); FragPos = vec3(model * vec4(position, 1.0)); - FragPosLightSpace = lightSpaceMatrix * vec4(FragPos, 1.0); Normal = mat3(model) * normal; } diff --git a/src/display.cpp b/src/display.cpp index 4f8d0f6..51385fc 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -37,6 +37,10 @@ Display::Display(std::string name, Logger& logger, int w, int h, mxaaLevel = 8; smxaaLevel = "8"; break; + case MXAA_16X: + mxaaLevel = 16; + smxaaLevel = "16"; + break; default: mxaaLevel = 2; smxaaLevel = "2"; @@ -78,6 +82,7 @@ Display::Display(std::string name, Logger& logger, int w, int h, // Load OpenGL gladLoadGLLoader(SDL_GL_GetProcAddress); + glEnable(GL_MULTISAMPLE); logger << LOGGER_INFO << "Loaded OpenGL" << LOGGER_ENDL; logger << LOGGER_ENDL; isClosed = false; @@ -124,6 +129,10 @@ Display::Display(std::string name, Logger& logger, int w, int h, mxaaLevel = 8; smxaaLevel = "8"; break; + case MXAA_16X: + mxaaLevel = 16; + smxaaLevel = "16"; + break; default: mxaaLevel = 2; smxaaLevel = "2"; @@ -165,6 +174,7 @@ Display::Display(std::string name, Logger& logger, int w, int h, // Load OpenGL gladLoadGLLoader(SDL_GL_GetProcAddress); + glEnable(GL_MULTISAMPLE); logger << LOGGER_INFO << "Loaded OpenGL" << LOGGER_ENDL; logger << LOGGER_ENDL; isClosed = false; @@ -174,6 +184,14 @@ void Display::setName(std::string name) { SDL_SetWindowTitle(window, name.c_str()); } +void Display::update() { + SDL_GL_SwapWindow(window); + + glClear(GL_DEPTH_BUFFER_BIT); + const float clear[] = { 0.1f, 0.45f, 0.9f, 1.0f }; + glClearBufferfv(GL_COLOR, 0, clear); +} + Display::~Display() { SDL_DestroyWindow(window); } diff --git a/src/display.h b/src/display.h index dea0488..773aa3e 100644 --- a/src/display.h +++ b/src/display.h @@ -23,12 +23,13 @@ typedef enum { } SMH_VSYNC_DISPLAY_MODE; typedef enum { - MXAA_DEFAULT, - MXAA_DISABLED, - MXAA_ENABLED, - MXAA_2X, - MXAA_4X, - MXAA_8X + MXAA_DEFAULT, + MXAA_DISABLED, + MXAA_ENABLED, + MXAA_2X, + MXAA_4X, + MXAA_8X, + MXAA_16X } SMH_MXAA_MODE; class Display { @@ -42,6 +43,7 @@ public: SMH_VSYNC_DISPLAY_MODE vsyncMode = VSYNC_DEFAULT); void setName(std::string name); + void update(); bool isClosed = true; diff --git a/src/main.cpp b/src/main.cpp index e06c467..4f6e7a7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,11 +7,12 @@ // #include // Custom includes -#define OBJL_DEFINITION +#define OBJL_IMPLIMENTATION #define LOGGER_DEFINITION #include #include "display.h" +#include "shader.h" #include "model.h" int main (int argc, char** argv) { @@ -24,7 +25,13 @@ int main (int argc, char** argv) { Logger logger; - Display display {"SMH Engine", logger, 1280, 720, MXAA_4X, VSYNC_ENABLED}; + Display display{"SMH Engine", logger, 1280, 720, MXAA_16X, VSYNC_ENABLED}; + + Shader shader; + shader.load("./resources/shaders/phong").attatch().link().use(); + + Mesh mesh{ "./resources/dragon.obj" }; + mesh.setup(); SDL_Event e; while (!display.isClosed) { @@ -32,8 +39,11 @@ int main (int argc, char** argv) { if (e.type == SDL_QUIT || e.key.keysym.sym == SDLK_ESCAPE) display.isClosed = true; + mesh.bind(); + mesh.render(shader); + mesh.unbind(); - SDL_GL_SwapWindow(display.window); + display.update(); } return 0; diff --git a/src/mesh.cpp b/src/mesh.cpp index 8ec0e89..f0d1f6f 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -14,20 +14,29 @@ Mesh::Mesh(std::string objPath) { return; } - OBJLtoGLM(loader.LoadedMeshes[0].Vertices, vertices, normals, texCoords); + logger << LOGGER_INFO << "Loaded: " << objPath << LOGGER_ENDL; + + loadFromObj(loader.LoadedMeshes[0]); } Mesh::Mesh(objl::Mesh objMesh) { - OBJLtoGLM(objMesh.Vertices, vertices, normals, texCoords); - UintToGLuint(objMesh.Indices, indices); + loadFromObj(objMesh); } void Mesh::loadFromObj(objl::Mesh objMesh) { OBJLtoGLM(objMesh.Vertices, vertices, normals, texCoords); UintToGLuint(objMesh.Indices, indices); + name = objMesh.MeshName; + + Logger logger; + for (int i = 0; i < 100; i++) { + logger << LOGGER_DEBUG << normals[i].x << " " << normals[i].y << " " << normals[i].z << LOGGER_ENDL; + } } void Mesh::setup() { + Logger logger; + glGenVertexArrays(1, &VAOid); glGenBuffers(1, &vertexBuffer); glGenBuffers(1, &indexBuffer); @@ -42,7 +51,7 @@ void Mesh::setup() { toGpu.insert(toGpu.end(), texCoords.begin(), texCoords.end()); glBufferData(GL_ARRAY_BUFFER, toGpu.size() * sizeof(glm::vec3), - &vertices[0], GL_STATIC_DRAW); + &toGpu[0], GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), @@ -63,6 +72,8 @@ void Mesh::setup() { glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (const void*)((vertices.size() + texCoords.size()) * sizeof(glm::vec3))); + logger << LOGGER_INFO << "Mesh " << name << " setup" << LOGGER_ENDL; + glBindVertexArray(0); } @@ -71,6 +82,38 @@ void Mesh::bind() { } void Mesh::render(Shader& shader) { + + // Model matrice + glm::mat4 model = glm::mat4(1.0f); + model = glm::translate(model, { -17.0f, -17.0f, -17.0f }); + model = glm::rotate(model, glm::radians(-160.0f), glm::vec3(0.0f, 1.0f, 0.0f)); + // Gets uniform for model matrice, to be used later + GLint uniTrans = glGetUniformLocation(shader.getProgram(), "model"); + glUniformMatrix4fv(uniTrans, 1, GL_FALSE, glm::value_ptr(model)); + + + // View matrice + glm::mat4 view = glm::lookAt( + glm::vec3(1.0f, 1.0f, 1.0f), + glm::vec3(0.0f, 0.4f, 0.0f), + glm::vec3(0.0f, 1.0f, 0.0f) + ); + // Get uniform and send it to the GPU + GLint uniView = glGetUniformLocation(shader.getProgram(), "view"); + glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(view)); + + // Projection matrice + glm::mat4 proj = glm::perspective(glm::radians(45.0f), 1280.0f / 720.0f, 1.0f, 1000.0f);//camera.perspective; + // Get uniform and send it to the GPU + GLint uniProj = glGetUniformLocation(shader.getProgram(), "proj"); + glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(proj)); + + + glm::vec3 lightPos = { -2.0f, 4.0f, -1.0f }; + + GLint uniLight = glGetUniformLocation(shader.getProgram(), "lightpos"); + glUniformMatrix3fv(uniLight, 1, GL_FALSE, glm::value_ptr(lightPos)); + glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0); } diff --git a/src/mesh.h b/src/mesh.h index 1b723f7..4aa24b2 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -13,10 +13,9 @@ #include #include +#include "shader.h" #include "./util/util.h" -class Shader; - class Mesh { public: Mesh(); @@ -32,6 +31,7 @@ public: GLuint VAOid; + std::string name; std::vector vertices; std::vector normals; // This is a vec3 so it can all pop into diff --git a/src/shader.cpp b/src/shader.cpp index 5795d27..d131ce2 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -1,3 +1,168 @@ #include "shader.h" +#include +#include +Shader::Shader() + : logger(*new Logger) { + m_program = glCreateProgram(); +} + +Shader& Shader::use() { + glUseProgram(m_program); + return *this; +} + +Shader& Shader::link() { + glLinkProgram(m_program); + return *this; +} + +Shader& Shader::attatch() { + glAttachShader(m_program, m_vert); + glAttachShader(m_program, m_frag); + return *this; +} + +std::string readShader(std::string source) { + std::ifstream t(source); + std::string shaderCode((std::istreambuf_iterator(t)), + std::istreambuf_iterator()); + return shaderCode; +} + +Shader& Shader::load(GLenum type, std::string sourceLoc) { + const char* source = readShader(sourceLoc).c_str(); + + if (type == GL_VERTEX_SHADER) { + m_vertLoc = sourceLoc; + m_vertSource = (std::string)source; + m_vert = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(m_vert, 1, &source, NULL); + glCompileShader(m_vert); + + glGetShaderiv(m_vert, GL_COMPILE_STATUS, &m_status); + if (m_status == GL_FALSE) { + char buf[512]; + glGetShaderInfoLog(m_vert, 512, NULL, buf); + logger << LOGGER_ERROR << buf << LOGGER_ENDL; + } + + logger << LOGGER_INFO << "Vertex shader at '" << sourceLoc << "' compiled..." << LOGGER_ENDL; + } + else if (type == GL_FRAGMENT_SHADER) { + m_fragLoc = sourceLoc; + m_fragSource = (std::string)source; + m_frag = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(m_frag, 1, &source, NULL); + glCompileShader(m_frag); + + glGetShaderiv(m_frag, GL_COMPILE_STATUS, &m_status); + if (m_status == GL_FALSE) { + char buf[512]; + glGetShaderInfoLog(m_frag, 512, NULL, buf); + logger << LOGGER_ERROR << buf << LOGGER_ENDL; + } + + logger << LOGGER_INFO << "Vertex shader at '" << sourceLoc << "' compiled..." << LOGGER_ENDL; + } + + return *this; +} + +Shader& Shader::load(std::string sourceLoc) { + m_vertLoc = sourceLoc + ".vert"; + m_fragLoc = sourceLoc + ".frag"; + + m_vertSource = readShader(m_vertLoc); + m_fragSource = readShader(m_fragLoc); + + m_vert = glCreateShader(GL_VERTEX_SHADER); + m_frag = glCreateShader(GL_FRAGMENT_SHADER); + + const char* vertSource = m_vertSource.c_str(); + glShaderSource(m_vert, 1, &vertSource, NULL); + glCompileShader(m_vert); + + const char* fragSource = m_fragSource.c_str(); + glShaderSource(m_frag, 1, &fragSource, NULL); + glCompileShader(m_frag); + + glGetShaderiv(m_vert, GL_COMPILE_STATUS, &m_status); + if (m_status == GL_FALSE) { + char buf[512]; + glGetShaderInfoLog(m_vert, 512, NULL, buf); + logger << LOGGER_ERROR << buf << LOGGER_ENDL; + } + + glGetShaderiv(m_frag, GL_COMPILE_STATUS, &m_status); + if (m_status == GL_FALSE) { + char buf[512]; + glGetShaderInfoLog(m_frag, 512, NULL, buf); + logger << LOGGER_ERROR << buf << LOGGER_ENDL; + } + + logger << LOGGER_INFO << "Vertex shader at '" << m_vertLoc << "' compiled..." << LOGGER_ENDL; + logger << LOGGER_INFO << "Fragment shader at '" << m_fragLoc << "' compiled..." << LOGGER_ENDL; + return *this; +} + +Shader& Shader::reload() { + glDeleteProgram(m_program); + glDeleteShader(m_vert); + glDeleteShader(m_frag); + + m_vertSource = readShader(m_vertLoc); + m_fragSource = readShader(m_fragLoc); + + m_vert = glCreateShader(GL_VERTEX_SHADER); + m_frag = glCreateShader(GL_FRAGMENT_SHADER); + + const char* vertSource = m_vertSource.c_str(); + glShaderSource(m_vert, 1, &vertSource, NULL); + glCompileShader(m_vert); + + const char* fragSource = m_fragSource.c_str(); + glShaderSource(m_frag, 1, &fragSource, NULL); + glCompileShader(m_frag); + + glGetShaderiv(m_vert, GL_COMPILE_STATUS, &m_status); + if (m_status == GL_FALSE) { + char buf[512]; + glGetShaderInfoLog(m_vert, 512, NULL, buf); + logger << LOGGER_ERROR << buf << LOGGER_ENDL; + } + + glGetShaderiv(m_frag, GL_COMPILE_STATUS, &m_status); + if (m_status == GL_FALSE) { + char buf[512]; + glGetShaderInfoLog(m_frag, 512, NULL, buf); + logger << LOGGER_ERROR << buf << LOGGER_ENDL; + } + + logger << LOGGER_INFO << "Vertex shader at '" << m_vertLoc << "' compiled..." << LOGGER_ENDL; + logger << LOGGER_INFO << "Fragment shader at '" << m_fragLoc << "' compiled..." << LOGGER_ENDL; + + link(); + attatch(); + + return *this; +} + +GLuint Shader::getProgram() { + return m_program; +} + +GLuint Shader::getVertex() { + return m_vert; +} + +GLuint Shader::getFragment() { + return m_frag; +} + +Shader::~Shader() { + glDeleteProgram(m_program); + glDeleteShader(m_vert); + glDeleteShader(m_frag); +} diff --git a/src/shader.h b/src/shader.h index 418fc14..9e5d174 100644 --- a/src/shader.h +++ b/src/shader.h @@ -1,9 +1,42 @@ #ifndef SMHENGINE_SRC_SHADER_H_ #define SMHENGINE_SRC_SHADER_H_ +#include +#include +#include class Shader { +public: + Shader(); + Shader& use(); + Shader& link(); + Shader& attatch(); + Shader& load(GLenum type, std::string sourceLoc); + Shader& load(std::string sourceLoc); + Shader& reload(); + + GLuint getProgram(); + GLuint getVertex(); + GLuint getFragment(); + + virtual ~Shader(); +private: + Shader(Shader const &) = delete; + Shader & operator=(Shader const &) = delete; + + GLuint m_program; + GLuint m_vert; + GLuint m_frag; + + std::string m_vertSource; + std::string m_fragSource; + std::string m_vertLoc; + std::string m_fragLoc; + + Logger& logger; + + GLint m_status; }; #endif diff --git a/src/util/util.cpp b/src/util/util.cpp index 4d9bf87..b003f62 100644 --- a/src/util/util.cpp +++ b/src/util/util.cpp @@ -1,13 +1,15 @@ #include "util.h" +#include + void OBJLtoGLM(std::vector& inVertArr, std::vector& outVert, std::vector& outNorm, std::vector& outTexCoord) { - for (int i = 0; i < inVertArr.size(); i++) { - - glm::vec3 tempVert {inVertArr[i].Position.X, inVertArr[i].Position.Y, inVertArr[i].Position.Z}; + for (int i = 0; i < inVertArr.size() - 1; i++) { + + glm::vec3 tempVert {inVertArr[i].Position.X, inVertArr[i].Position.Y, inVertArr[i].Position.Z}; outVert.push_back(tempVert); glm::vec3 tempNorm {inVertArr[i].Normal.X, inVertArr[i].Normal.Y, inVertArr[i].Normal.Z};