diff --git a/Hazel/Hazel.vcxproj b/Hazel/Hazel.vcxproj index cda09e661..0e3fc1be5 100644 --- a/Hazel/Hazel.vcxproj +++ b/Hazel/Hazel.vcxproj @@ -156,6 +156,7 @@ + @@ -531,6 +532,7 @@ + diff --git a/Hazel/Hazel.vcxproj.filters b/Hazel/Hazel.vcxproj.filters index 32ad1ee90..0f1c8f29c 100644 --- a/Hazel/Hazel.vcxproj.filters +++ b/Hazel/Hazel.vcxproj.filters @@ -1187,6 +1187,7 @@ + @@ -1217,5 +1218,6 @@ src + \ No newline at end of file diff --git a/Hazel/src/Hazel/Application.cpp b/Hazel/src/Hazel/Application.cpp index a4337aa67..f424f6c08 100644 --- a/Hazel/src/Hazel/Application.cpp +++ b/Hazel/src/Hazel/Application.cpp @@ -46,6 +46,35 @@ namespace Hazel { unsigned int indices[3] = { 0, 1, 2 }; glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); + + std::string vertexSrc = R"( + #version 330 core + + layout(location = 0) in vec3 a_Position; + + out vec3 v_Position; + + void main() + { + v_Position = a_Position; + gl_Position = vec4(a_Position, 1.0); + } + )"; + + std::string fragmentSrc = R"( + #version 330 core + + layout(location = 0) out vec4 color; + + in vec3 v_Position; + + void main() + { + color = vec4(v_Position * 0.5 + 0.5, 1.0); + } + )"; + + m_Shader.reset(new Shader(vertexSrc, fragmentSrc)); } Application::~Application() @@ -84,6 +113,7 @@ namespace Hazel { glClearColor(0.1f, 0.1f, 0.1f, 1); glClear(GL_COLOR_BUFFER_BIT); + m_Shader->Bind(); glBindVertexArray(m_VertexArray); glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, nullptr); diff --git a/Hazel/src/Hazel/Application.h b/Hazel/src/Hazel/Application.h index 5128f71b9..993b6d2fa 100644 --- a/Hazel/src/Hazel/Application.h +++ b/Hazel/src/Hazel/Application.h @@ -9,6 +9,8 @@ #include "Hazel/ImGui/ImGuiLayer.h" +#include "Hazel/Renderer/Shader.h" + namespace Hazel { class HAZEL_API Application @@ -36,6 +38,7 @@ namespace Hazel { LayerStack m_LayerStack; unsigned int m_VertexArray, m_VertexBuffer, m_IndexBuffer; + std::unique_ptr m_Shader; private: static Application* s_Instance; }; diff --git a/Hazel/src/Hazel/Renderer/Shader.cpp b/Hazel/src/Hazel/Renderer/Shader.cpp new file mode 100644 index 000000000..a124671bf --- /dev/null +++ b/Hazel/src/Hazel/Renderer/Shader.cpp @@ -0,0 +1,127 @@ +#include "hzpch.h" +#include "Shader.h" + +#include + +namespace Hazel { + + Shader::Shader(const std::string& vertexSrc, const std::string& fragmentSrc) + { + // Create an empty vertex shader handle + GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); + + // Send the vertex shader source code to GL + // Note that std::string's .c_str is NULL character terminated. + const GLchar* source = vertexSrc.c_str(); + glShaderSource(vertexShader, 1, &source, 0); + + // Compile the vertex shader + glCompileShader(vertexShader); + + GLint isCompiled = 0; + glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &isCompiled); + if (isCompiled == GL_FALSE) + { + GLint maxLength = 0; + glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength); + + // The maxLength includes the NULL character + std::vector infoLog(maxLength); + glGetShaderInfoLog(vertexShader, maxLength, &maxLength, &infoLog[0]); + + // We don't need the shader anymore. + glDeleteShader(vertexShader); + + HZ_CORE_ERROR("{0}", infoLog.data()); + HZ_CORE_ASSERT(false, "Vertex shader compilation failure!"); + return; + } + + // Create an empty fragment shader handle + GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + + // Send the fragment shader source code to GL + // Note that std::string's .c_str is NULL character terminated. + source = fragmentSrc.c_str(); + glShaderSource(fragmentShader, 1, &source, 0); + + // Compile the fragment shader + glCompileShader(fragmentShader); + + glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &isCompiled); + if (isCompiled == GL_FALSE) + { + GLint maxLength = 0; + glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &maxLength); + + // The maxLength includes the NULL character + std::vector infoLog(maxLength); + glGetShaderInfoLog(fragmentShader, maxLength, &maxLength, &infoLog[0]); + + // We don't need the shader anymore. + glDeleteShader(fragmentShader); + // Either of them. Don't leak shaders. + glDeleteShader(vertexShader); + + HZ_CORE_ERROR("{0}", infoLog.data()); + HZ_CORE_ASSERT(false, "Fragment shader compilation failure!"); + return; + } + + // Vertex and fragment shaders are successfully compiled. + // Now time to link them together into a program. + // Get a program object. + m_RendererID = glCreateProgram(); + GLuint program = m_RendererID; + + // Attach our shaders to our program + glAttachShader(program, vertexShader); + glAttachShader(program, fragmentShader); + + // Link our program + glLinkProgram(program); + + // Note the different functions here: glGetProgram* instead of glGetShader*. + GLint isLinked = 0; + glGetProgramiv(program, GL_LINK_STATUS, (int*)&isLinked); + if (isLinked == GL_FALSE) + { + GLint maxLength = 0; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); + + // The maxLength includes the NULL character + std::vector infoLog(maxLength); + glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]); + + // We don't need the program anymore. + glDeleteProgram(program); + // Don't leak shaders either. + glDeleteShader(vertexShader); + glDeleteShader(fragmentShader); + + HZ_CORE_ERROR("{0}", infoLog.data()); + HZ_CORE_ASSERT(false, "Shader link failure!"); + return; + } + + // Always detach shaders after a successful link. + glDetachShader(program, vertexShader); + glDetachShader(program, fragmentShader); + } + + Shader::~Shader() + { + glDeleteProgram(m_RendererID); + } + + void Shader::Bind() const + { + glUseProgram(m_RendererID); + } + + void Shader::Unbind() const + { + glUseProgram(0); + } + +} \ No newline at end of file diff --git a/Hazel/src/Hazel/Renderer/Shader.h b/Hazel/src/Hazel/Renderer/Shader.h new file mode 100644 index 000000000..e88501747 --- /dev/null +++ b/Hazel/src/Hazel/Renderer/Shader.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +namespace Hazel { + + class Shader + { + public: + Shader(const std::string& vertexSrc, const std::string& fragmentSrc); + ~Shader(); + + void Bind() const; + void Unbind() const; + private: + uint32_t m_RendererID; + }; + +} \ No newline at end of file diff --git a/Sandbox/imgui.ini b/Sandbox/imgui.ini new file mode 100644 index 000000000..7ab1d61ac --- /dev/null +++ b/Sandbox/imgui.ini @@ -0,0 +1,18 @@ +[Window][Debug##Default] +Pos=60,60 +Size=400,400 +Collapsed=0 + +[Window][Test] +Pos=60,60 +Size=92,48 +Collapsed=0 + +[Window][ImGui Demo] +ViewportPos=1404,134 +ViewportId=0x080FC883 +Size=550,680 +Collapsed=0 + +[Docking][Data] +