glClear is causing stack corrpution
This commit is contained in:
		 Submodule lib/Catch2 updated: a8cf3e6710...32d9ae24bc
									
								
							
							
								
								
									
										2
									
								
								lib/SDL
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								lib/SDL
									
									
									
									
									
								
							 Submodule lib/SDL updated: ac6b32bb02...4722269fb6
									
								
							 Submodule lib/freetype updated: dc519d06ea...e969289f88
									
								
							
							
								
								
									
										2
									
								
								lib/glfw
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								lib/glfw
									
									
									
									
									
								
							 Submodule lib/glfw updated: 3eaf1255b2...a87acd8c1f
									
								
							
							
								
								
									
										2
									
								
								lib/glm
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								lib/glm
									
									
									
									
									
								
							 Submodule lib/glm updated: 47585fde0c...586a402397
									
								
							 Submodule lib/openal-soft updated: 6420bc86cd...d6d572df66
									
								
							| @@ -12,7 +12,7 @@ | |||||||
| #include "component/display/MeshRenderer.hpp" | #include "component/display/MeshRenderer.hpp" | ||||||
|  |  | ||||||
| namespace Dawn { | namespace Dawn { | ||||||
|   struct IRenderPass { |   class IRenderPass { | ||||||
|     public: |     public: | ||||||
|       std::shared_ptr<Mesh> mesh; |       std::shared_ptr<Mesh> mesh; | ||||||
|  |  | ||||||
| @@ -43,14 +43,17 @@ namespace Dawn { | |||||||
|   }; |   }; | ||||||
|  |  | ||||||
|   template<class S, typename D> |   template<class S, typename D> | ||||||
|   struct RenderPass : public IRenderPass { |   class RenderPass : public IRenderPass { | ||||||
|     private: |     private: | ||||||
|       std::shared_ptr<S> shader; |       std::shared_ptr<S> shader; | ||||||
|       const D data; |       const std::unordered_map< | ||||||
|  |         shadertexturebinding_t, std::shared_ptr<Texture> | ||||||
|  |       > &textures; | ||||||
|       std::shared_ptr<Mesh> mesh; |       std::shared_ptr<Mesh> mesh; | ||||||
|       const enum MeshDrawMode drawMode; |       const enum MeshDrawMode drawMode; | ||||||
|       const int32_t indiceStart; |       const int32_t indiceStart; | ||||||
|       const int32_t indiceCount; |       const int32_t indiceCount; | ||||||
|  |       const D data; | ||||||
|  |  | ||||||
|     public: |     public: | ||||||
|       /** |       /** | ||||||
| @@ -66,12 +69,16 @@ namespace Dawn { | |||||||
|       RenderPass( |       RenderPass( | ||||||
|         SceneComponent &self, |         SceneComponent &self, | ||||||
|         const D d, |         const D d, | ||||||
|  |         const std::unordered_map< | ||||||
|  |           shadertexturebinding_t, std::shared_ptr<Texture> | ||||||
|  |         > textures, | ||||||
|         const std::shared_ptr<Mesh> mesh, |         const std::shared_ptr<Mesh> mesh, | ||||||
|         const enum MeshDrawMode drawMode, |         const enum MeshDrawMode drawMode, | ||||||
|         const int32_t indiceStart, |         const int32_t indiceStart, | ||||||
|         const int32_t indiceCount |         const int32_t indiceCount | ||||||
|       ) : |       ) : | ||||||
|         data(d), |         data(d), | ||||||
|  |         textures(textures), | ||||||
|         mesh(mesh), |         mesh(mesh), | ||||||
|         drawMode(drawMode), |         drawMode(drawMode), | ||||||
|         indiceStart(indiceStart), |         indiceStart(indiceStart), | ||||||
| @@ -91,6 +98,7 @@ namespace Dawn { | |||||||
|       } |       } | ||||||
|  |  | ||||||
|       void bind() override { |       void bind() override { | ||||||
|  |         std::cout << "textures: " << textures.size() << "\n"; | ||||||
|         shader->bind(); |         shader->bind(); | ||||||
|       } |       } | ||||||
|  |  | ||||||
| @@ -99,6 +107,10 @@ namespace Dawn { | |||||||
|       } |       } | ||||||
|  |  | ||||||
|       void upload() override { |       void upload() override { | ||||||
|  |         for(auto &pair : textures) { | ||||||
|  |           assertNotNull(pair.second, "Texture cannot be null!"); | ||||||
|  |           pair.second->bind(pair.first); | ||||||
|  |         } | ||||||
|         shader->upload(); |         shader->upload(); | ||||||
|       } |       } | ||||||
|  |  | ||||||
| @@ -139,17 +151,21 @@ namespace Dawn { | |||||||
|    * @return Created render pass. |    * @return Created render pass. | ||||||
|    */ |    */ | ||||||
|   template<class S, typename D> |   template<class S, typename D> | ||||||
|   std::shared_ptr<struct IRenderPass> createRenderPass( |   std::shared_ptr<IRenderPass> createRenderPass( | ||||||
|     SceneComponent &self, |     SceneComponent &self, | ||||||
|     const D data, |     const D data, | ||||||
|  |     const std::unordered_map< | ||||||
|  |       shadertexturebinding_t, std::shared_ptr<Texture> | ||||||
|  |     > textures = {}, | ||||||
|     const std::shared_ptr<Mesh> mesh = nullptr, |     const std::shared_ptr<Mesh> mesh = nullptr, | ||||||
|     const enum MeshDrawMode drawMode = MeshDrawMode::TRIANGLES, |     const enum MeshDrawMode drawMode = MeshDrawMode::TRIANGLES, | ||||||
|     int32_t indiceStart = 0, |     int32_t indiceStart = 0, | ||||||
|     int32_t indiceCount = -1 |     int32_t indiceCount = -1 | ||||||
|   ) { |   ) { | ||||||
|     return std::make_shared<struct RenderPass<S,D>>( |     return std::make_shared<RenderPass<S,D>>( | ||||||
|       self, |       self, | ||||||
|       data, |       data, | ||||||
|  |       textures, | ||||||
|       mesh, |       mesh, | ||||||
|       drawMode, |       drawMode, | ||||||
|       indiceStart, |       indiceStart, | ||||||
|   | |||||||
| @@ -11,7 +11,16 @@ struct Color SimpleTexturedMaterial::getColor() { | |||||||
|   return this->data.color; |   return this->data.color; | ||||||
| } | } | ||||||
|  |  | ||||||
| void SimpleTexturedMaterial::setColor(struct Color color) { | std::shared_ptr<Texture> SimpleTexturedMaterial::getTexture() { | ||||||
|  |   return this->texture; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void SimpleTexturedMaterial::setTexture(std::shared_ptr<Texture> texture) { | ||||||
|  |   this->texture = texture; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void SimpleTexturedMaterial::setColor(const struct Color color) { | ||||||
|   this->data.color = color; |   this->data.color = color; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -22,11 +31,23 @@ std::vector<std::shared_ptr<IRenderPass>> SimpleTexturedMaterial::getPasses( | |||||||
|   this->data.projection = ctx.camera->getProjection(); |   this->data.projection = ctx.camera->getProjection(); | ||||||
|   this->data.view = ctx.camera->getItem()->getWorldTransform(); |   this->data.view = ctx.camera->getItem()->getWorldTransform(); | ||||||
|   this->data.color = COLOR_RED; |   this->data.color = COLOR_RED; | ||||||
|  |   auto textures = std::unordered_map< | ||||||
|  |     shadertexturebinding_t, std::shared_ptr<Texture> | ||||||
|  |   >(); | ||||||
|  |    | ||||||
|  |   if(this->texture) { | ||||||
|  |     this->data.hasTexture = true; | ||||||
|  |     this->data.texture = 0; | ||||||
|  |     textures[this->data.texture] = this->texture; | ||||||
|  |   } else { | ||||||
|  |     this->data.hasTexture = false; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   return { |   return { | ||||||
|     createRenderPass<SimpleTexturedShader, struct SimpleTexturedShaderData>( |     createRenderPass<SimpleTexturedShader, struct SimpleTexturedShaderData>( | ||||||
|       *this, |       *this, | ||||||
|       data |       data, | ||||||
|  |       textures | ||||||
|     ) |     ) | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -6,11 +6,13 @@ | |||||||
| #pragma once | #pragma once | ||||||
| #include "component/display/material/Material.hpp" | #include "component/display/material/Material.hpp" | ||||||
| #include "display/shader/SimpleTexturedShader.hpp" | #include "display/shader/SimpleTexturedShader.hpp" | ||||||
|  | #include "display/Texture.hpp" | ||||||
|  |  | ||||||
| namespace Dawn { | namespace Dawn { | ||||||
|   class SimpleTexturedMaterial : public Material { |   class SimpleTexturedMaterial : public Material { | ||||||
|     private: |     private: | ||||||
|       struct SimpleTexturedShaderData data; |       struct SimpleTexturedShaderData data; | ||||||
|  |       std::shared_ptr<Texture> texture; | ||||||
|  |  | ||||||
|     public: |     public: | ||||||
|       /** |       /** | ||||||
| @@ -18,12 +20,26 @@ namespace Dawn { | |||||||
|        */ |        */ | ||||||
|       struct Color getColor(); |       struct Color getColor(); | ||||||
|  |  | ||||||
|  |       /** | ||||||
|  |        * Returns the texture of this material. | ||||||
|  |        *  | ||||||
|  |        * @return The texture of this material. | ||||||
|  |        */ | ||||||
|  |       std::shared_ptr<Texture> getTexture(); | ||||||
|  |  | ||||||
|  |       /** | ||||||
|  |        * Sets the texture of this material. | ||||||
|  |        *  | ||||||
|  |        * @param texture The texture to set. | ||||||
|  |        */ | ||||||
|  |       void setTexture(std::shared_ptr<Texture> texture); | ||||||
|  |  | ||||||
|       /** |       /** | ||||||
|        * Sets the color of this material. |        * Sets the color of this material. | ||||||
|        *  |        *  | ||||||
|        * @param color The color to set. |        * @param color The color to set. | ||||||
|        */ |        */ | ||||||
|       void setColor(struct Color color); |       void setColor(const struct Color color); | ||||||
|  |  | ||||||
|       std::vector<std::shared_ptr<IRenderPass>> getPasses( |       std::vector<std::shared_ptr<IRenderPass>> getPasses( | ||||||
|         struct RenderPassContext &ctx |         struct RenderPassContext &ctx | ||||||
|   | |||||||
							
								
								
									
										109
									
								
								src/dawn/display/ITexture.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								src/dawn/display/ITexture.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,109 @@ | |||||||
|  | // Copyright (c) 2023 Dominic Masters | ||||||
|  | //  | ||||||
|  | // This software is released under the MIT License. | ||||||
|  | // https://opensource.org/licenses/MIT | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  | #include "display/Color.hpp" | ||||||
|  |  | ||||||
|  | namespace Dawn { | ||||||
|  |   enum TextureFormat { | ||||||
|  |     TEXTURE_FORMAT_R = 1, | ||||||
|  |     TEXTURE_FORMAT_RG = 2, | ||||||
|  |     TEXTURE_FORMAT_RGB = 3, | ||||||
|  |     TEXTURE_FORMAT_RGBA = 4 | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   enum TextureWrapMode { | ||||||
|  |     TEXTURE_WRAP_MODE_REPEAT = 0, | ||||||
|  |     TEXTURE_WRAP_MODE_MIRRORED_REPEAT = 1, | ||||||
|  |     TEXTURE_WRAP_MODE_CLAMP_TO_EDGE = 2, | ||||||
|  |     TEXTURE_WRAP_MODE_CLAMP_TO_BORDER = 3 | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   enum TextureFilterMode { | ||||||
|  |     TEXTURE_FILTER_MODE_NEAREST = 0, | ||||||
|  |     TEXTURE_FILTER_MODE_LINEAR = 1 | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   enum TextureDataFormat { | ||||||
|  |     TEXTURE_DATA_FORMAT_UNSIGNED_BYTE = 0, | ||||||
|  |     TEXTURE_DATA_FORMAT_FLOAT = 1 | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   class ITexture { | ||||||
|  |     public: | ||||||
|  |       enum TextureWrapMode wrapModeX = TEXTURE_WRAP_MODE_REPEAT; | ||||||
|  |       enum TextureWrapMode wrapModeY = TEXTURE_WRAP_MODE_REPEAT; | ||||||
|  |       enum TextureFilterMode filterModeMin = TEXTURE_FILTER_MODE_NEAREST; | ||||||
|  |       enum TextureFilterMode filterModeMag = TEXTURE_FILTER_MODE_NEAREST; | ||||||
|  |       enum TextureFilterMode mipMapFilterModeMin = TEXTURE_FILTER_MODE_NEAREST; | ||||||
|  |       enum TextureFilterMode mipMapFilterModeMag = TEXTURE_FILTER_MODE_NEAREST; | ||||||
|  |  | ||||||
|  |       /** | ||||||
|  |        * Returns the width of the texture. | ||||||
|  |        *  | ||||||
|  |        * @return Width of the texture. | ||||||
|  |        */ | ||||||
|  |       virtual int32_t getWidth() = 0; | ||||||
|  |  | ||||||
|  |       /** | ||||||
|  |        * Returns the height of the texture. | ||||||
|  |        *  | ||||||
|  |        * @return Height of the texture. | ||||||
|  |        */ | ||||||
|  |       virtual int32_t getHeight() = 0; | ||||||
|  |  | ||||||
|  |       /** | ||||||
|  |        * Initializes a texture. | ||||||
|  |        *  | ||||||
|  |        * @param width Width of the texture (in pixels). | ||||||
|  |        * @param height Height of the texture (in pixels). | ||||||
|  |        * @param format Data format of the texture to use. | ||||||
|  |        * @param dataFormat Data format of the texture to use. | ||||||
|  |        */ | ||||||
|  |       virtual void setSize( | ||||||
|  |         const int32_t width, | ||||||
|  |         const int32_t height, | ||||||
|  |         const enum TextureFormat format, | ||||||
|  |         const enum TextureDataFormat dataFormat | ||||||
|  |       ) = 0; | ||||||
|  |  | ||||||
|  |       /** | ||||||
|  |        * Returns true only when the texture has been loaded, sized and put on | ||||||
|  |        * the gpu for rendering. | ||||||
|  |        *  | ||||||
|  |        * @return True if ready, otherwise false. | ||||||
|  |        */ | ||||||
|  |       // virtual bool_t isReady() = 0; | ||||||
|  |  | ||||||
|  |       /** | ||||||
|  |        * Buffer pixel data onto the GPU. Pixel buffering is rather costly so | ||||||
|  |        * avoid doing this too often. | ||||||
|  |        *  | ||||||
|  |        * @param pixels Array of pixels you're trying to buffer. | ||||||
|  |        */ | ||||||
|  |       virtual void buffer(const struct ColorU8 pixels[]) = 0; | ||||||
|  |  | ||||||
|  |       /** | ||||||
|  |        * Buffer pixel data onto the GPU. Pixel buffering is rather costly so | ||||||
|  |        * avoid doing this too often. | ||||||
|  |        *  | ||||||
|  |        * @param pixels Array of pixels you're trying to buffer. | ||||||
|  |        */ | ||||||
|  |       virtual void buffer(const uint8_t pixels[]) = 0; | ||||||
|  |  | ||||||
|  |       /** | ||||||
|  |        * Binds the texture to the given slot (for use by the shaders). | ||||||
|  |        *  | ||||||
|  |        * @param slot Slot to bind to. | ||||||
|  |        */ | ||||||
|  |       virtual void bind(const uint8_t slot) = 0; | ||||||
|  |  | ||||||
|  |       /** | ||||||
|  |        * Disposes of the texture. | ||||||
|  |        */ | ||||||
|  |       virtual ~ITexture() { | ||||||
|  |       } | ||||||
|  |   }; | ||||||
|  | } | ||||||
| @@ -68,6 +68,7 @@ void RenderPipeline::renderSceneCamera( | |||||||
|   assertNotNull(game, "Game cannot be null"); |   assertNotNull(game, "Game cannot be null"); | ||||||
|   assertNotNull(scene, "Scene cannot be null");  |   assertNotNull(scene, "Scene cannot be null");  | ||||||
|   assertNotNull(camera, "Camera cannot be null"); |   assertNotNull(camera, "Camera cannot be null"); | ||||||
|  |   assertNotNull(renderTarget, "RenderTarget cannot be null"); | ||||||
|  |  | ||||||
|   struct RenderPassContext ctx = { |   struct RenderPassContext ctx = { | ||||||
|     game, |     game, | ||||||
| @@ -77,14 +78,15 @@ void RenderPipeline::renderSceneCamera( | |||||||
|   }; |   }; | ||||||
|  |  | ||||||
|   // Get list of renderables |   // Get list of renderables | ||||||
|   std::vector<std::shared_ptr<struct IRenderPass>> renderPasses; |   std::vector<std::shared_ptr<IRenderPass>> renderPasses; | ||||||
|   auto renderables = scene->findComponents<IRenderableComponent>(); |   auto renderables = scene->findComponents<IRenderableComponent>(); | ||||||
|   for(auto renderable : renderables) { |   for(auto renderable : renderables) { | ||||||
|     auto rp = renderable->getPasses(ctx); |     auto rp = renderable->getPasses(ctx); | ||||||
|     renderPasses.insert(renderPasses.end(), rp.begin(), rp.end()); |     renderPasses.insert(renderPasses.end(), rp.begin(), rp.end()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // Sort the render passes |   auto rp = renderPasses[0]; | ||||||
|  |   rp->bind(); | ||||||
|    |    | ||||||
|   // TODO: Make clearing the buffers editable! |   // TODO: Make clearing the buffers editable! | ||||||
|   renderTarget->bind(); |   renderTarget->bind(); | ||||||
| @@ -92,17 +94,15 @@ void RenderPipeline::renderSceneCamera( | |||||||
|     RENDER_TARGET_CLEAR_COLOR | |     RENDER_TARGET_CLEAR_COLOR | | ||||||
|     RENDER_TARGET_CLEAR_DEPTH |     RENDER_TARGET_CLEAR_DEPTH | ||||||
|   ); |   ); | ||||||
|  |  | ||||||
|  |   rp->bind(); | ||||||
|    |    | ||||||
|   std::for_each( |   for(auto renderPass : renderPasses) { | ||||||
|     renderPasses.begin(), |     renderPass->bind(); | ||||||
|     renderPasses.end(), |     renderPass->setData(); | ||||||
|     [&](std::shared_ptr<struct IRenderPass> pass) { |     renderPass->upload(); | ||||||
|       pass->bind(); |     renderPass->draw(); | ||||||
|       pass->setData(); |   } | ||||||
|       pass->upload(); |  | ||||||
|       pass->draw(); |  | ||||||
|     } |  | ||||||
|   ); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| RenderPipeline::~RenderPipeline() { | RenderPipeline::~RenderPipeline() { | ||||||
|   | |||||||
| @@ -6,8 +6,8 @@ | |||||||
| #pragma once | #pragma once | ||||||
| #include "event/Event.hpp" | #include "event/Event.hpp" | ||||||
|  |  | ||||||
| #define RENDER_TARGET_CLEAR_COLOR 1 << 0 | #define RENDER_TARGET_CLEAR_COLOR (1 << 0) | ||||||
| #define RENDER_TARGET_CLEAR_DEPTH 1 << 1 | #define RENDER_TARGET_CLEAR_DEPTH (1 << 1) | ||||||
|  |  | ||||||
| namespace Dawn { | namespace Dawn { | ||||||
|   class RenderTarget { |   class RenderTarget { | ||||||
|   | |||||||
| @@ -123,6 +123,12 @@ glm::quat SceneItemTransform::getLocalRotation() { | |||||||
|   return this->localRotation; |   return this->localRotation; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void SceneItemTransform::setLocalTransform(const glm::mat4 transform) { | ||||||
|  |   this->transformLocal = transform; | ||||||
|  |   this->updateLocalValuesFromLocalTransform(); | ||||||
|  |   this->updateWorldTransformFromLocalTransform(); | ||||||
|  | } | ||||||
|  |  | ||||||
| void SceneItemTransform::setWorldTransform(const glm::mat4 transform) { | void SceneItemTransform::setWorldTransform(const glm::mat4 transform) { | ||||||
|   this->transformWorld = transform; |   this->transformWorld = transform; | ||||||
|   this->updateLocalTransformFromWorldTransform(); |   this->updateLocalTransformFromWorldTransform(); | ||||||
|   | |||||||
| @@ -106,6 +106,13 @@ namespace Dawn { | |||||||
|        * @return Local rotation of this item. |        * @return Local rotation of this item. | ||||||
|        */ |        */ | ||||||
|       glm::quat getLocalRotation(); |       glm::quat getLocalRotation(); | ||||||
|  |  | ||||||
|  |       /** | ||||||
|  |        * Sets the transform of this item within local space (relative to parent) | ||||||
|  |        *  | ||||||
|  |        * @param transform Transform of this item in local space. | ||||||
|  |        */ | ||||||
|  |       void setLocalTransform(const glm::mat4 transform); | ||||||
|        |        | ||||||
|       /** |       /** | ||||||
|        * Sets the transform of this item within world space (relative to scene |        * Sets the transform of this item within world space (relative to scene | ||||||
|   | |||||||
| @@ -27,11 +27,11 @@ void Dawn::helloWorldScene(Scene &s) { | |||||||
|   auto cubeMeshRenderer = cubeItem->addComponent<MeshRenderer>(); |   auto cubeMeshRenderer = cubeItem->addComponent<MeshRenderer>(); | ||||||
|   cubeMeshRenderer->mesh = cubeMesh; |   cubeMeshRenderer->mesh = cubeMesh; | ||||||
|   auto cubeMaterial = cubeItem->addComponent<SimpleTexturedMaterial>(); |   auto cubeMaterial = cubeItem->addComponent<SimpleTexturedMaterial>(); | ||||||
|   addSimpleComponent(cubeItem, [](auto &cmp, auto &events) { |   // addSimpleComponent(cubeItem, [](auto &cmp, auto &events) { | ||||||
|     events.push_back(cmp.getScene()->onUnpausedUpdate.listen([&](float_t delta) { |   //   events.push_back(cmp.getScene()->onUnpausedUpdate.listen([&](float_t delta) { | ||||||
|       auto item = cmp.getItem(); |   //     auto item = cmp.getItem(); | ||||||
|       item->setLocalRotation(item->getLocalRotation() * glm::quat(glm::vec3(1, 1, 0) * delta)); |   //     item->setLocalRotation(item->getLocalRotation() * glm::quat(glm::vec3(1, 1, 0) * delta)); | ||||||
|       // item->setLocalScale(item->getLocalScale() + glm::vec3(1, 1, 1) * delta); |   //     // item->setLocalScale(item->getLocalScale() + glm::vec3(1, 1, 1) * delta); | ||||||
|     })); |   //   })); | ||||||
|   }); |   // }); | ||||||
| } | } | ||||||
| @@ -45,13 +45,14 @@ void BackBufferRenderTarget::setClearColor(const struct Color color) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void BackBufferRenderTarget::clear(const int32_t clearFlags) { | void BackBufferRenderTarget::clear(const int32_t clearFlags) { | ||||||
|   glClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a); |   glClearColor(clearColor.r, clearColor.g, clearColor.b, 1.0f); | ||||||
|   assertNoGLError(); |   assertNoGLError(); | ||||||
|  |  | ||||||
|   GLbitfield mask = 0; |   GLbitfield mask = 0; | ||||||
|   if(Flag::isOn(clearFlags, RENDER_TARGET_CLEAR_COLOR)) { |   if(Flag::isOn(clearFlags, RENDER_TARGET_CLEAR_COLOR)) { | ||||||
|     mask |= GL_COLOR_BUFFER_BIT; |     mask |= GL_COLOR_BUFFER_BIT; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if(Flag::isOn(clearFlags, RENDER_TARGET_CLEAR_DEPTH)) { |   if(Flag::isOn(clearFlags, RENDER_TARGET_CLEAR_DEPTH)) { | ||||||
|     mask |= GL_DEPTH_BUFFER_BIT; |     mask |= GL_DEPTH_BUFFER_BIT; | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ | |||||||
| target_sources(${DAWN_TARGET_NAME} | target_sources(${DAWN_TARGET_NAME} | ||||||
|   PRIVATE |   PRIVATE | ||||||
|     BackBufferRenderTarget.cpp |     BackBufferRenderTarget.cpp | ||||||
|  |     Texture.cpp | ||||||
| ) | ) | ||||||
|  |  | ||||||
| # Subdirs | # Subdirs | ||||||
|   | |||||||
							
								
								
									
										208
									
								
								src/dawnopengl/display/Texture.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										208
									
								
								src/dawnopengl/display/Texture.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,208 @@ | |||||||
|  | // Copyright (c) 2022 Dominic Masters | ||||||
|  | //  | ||||||
|  | // This software is released under the MIT License. | ||||||
|  | // https://opensource.org/licenses/MIT | ||||||
|  |  | ||||||
|  | #include "assert/assert.hpp" | ||||||
|  | #include "assert/assertgl.hpp" | ||||||
|  | #include "Texture.hpp" | ||||||
|  |  | ||||||
|  | using namespace Dawn; | ||||||
|  |  | ||||||
|  | void Texture::bind(const uint8_t slot) { | ||||||
|  |   assertTrue(this->id != -1, "Texture is not ready!"); | ||||||
|  |   glActiveTexture(GL_TEXTURE0 + slot); | ||||||
|  |   assertNoGLError(); | ||||||
|  |   glBindTexture(GL_TEXTURE_2D, this->id); | ||||||
|  |   assertNoGLError(); | ||||||
|  |   this->updateTextureProperties(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int32_t Texture::getWidth() { | ||||||
|  |   return this->width; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int32_t Texture::getHeight() { | ||||||
|  |   return this->height; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Texture::setSize( | ||||||
|  |   const int32_t width, | ||||||
|  |   const int32_t height, | ||||||
|  |   const enum TextureFormat format, | ||||||
|  |   const enum TextureDataFormat dataFormat | ||||||
|  | ) { | ||||||
|  |   if(this->id != -1) { | ||||||
|  |     glDeleteTextures(1, &this->id); | ||||||
|  |     assertNoGLError(); | ||||||
|  |     this->id = -1; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   int32_t maxSize; | ||||||
|  |   glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize); | ||||||
|  |   assertTrue(width > 0 && width <= maxSize, "Width is out of bounds!"); | ||||||
|  |   assertTrue(height > 0 && height <= maxSize, "Height is out of bounds!"); | ||||||
|  |  | ||||||
|  |   this->width = width; | ||||||
|  |   this->height = height; | ||||||
|  |   this->format = format; | ||||||
|  |   this->dataFormat = dataFormat; | ||||||
|  |  | ||||||
|  |   glGenTextures(1, &this->id); | ||||||
|  |   assertNoGLError(); | ||||||
|  |   if(this->id <= 0) assertUnreachable("Texture generation failed!"); | ||||||
|  |  | ||||||
|  |   // Initialize the texture to blank | ||||||
|  |   glActiveTexture(GL_TEXTURE0); | ||||||
|  |   assertNoGLError(); | ||||||
|  |   this->bufferRaw(NULL); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // bool_t Texture::isReady() { | ||||||
|  | //   return this->id != -1; | ||||||
|  | // } | ||||||
|  |  | ||||||
|  | void Texture::updateTextureProperties() { | ||||||
|  |   auto setWrapMode = [&](GLenum axis, enum TextureWrapMode wm) { | ||||||
|  |     switch(wm) { | ||||||
|  |       case TEXTURE_WRAP_MODE_REPEAT: | ||||||
|  |         glTexParameteri(GL_TEXTURE_2D, axis, GL_REPEAT); | ||||||
|  |         break; | ||||||
|  |        | ||||||
|  |       case TEXTURE_WRAP_MODE_MIRRORED_REPEAT: | ||||||
|  |         glTexParameteri(GL_TEXTURE_2D, axis, GL_MIRRORED_REPEAT); | ||||||
|  |         break; | ||||||
|  |  | ||||||
|  |       case TEXTURE_WRAP_MODE_CLAMP_TO_EDGE: | ||||||
|  |         glTexParameteri(GL_TEXTURE_2D, axis, GL_CLAMP_TO_EDGE); | ||||||
|  |         break; | ||||||
|  |  | ||||||
|  |       case TEXTURE_WRAP_MODE_CLAMP_TO_BORDER: | ||||||
|  |         glTexParameteri(GL_TEXTURE_2D, axis, GL_CLAMP_TO_BORDER); | ||||||
|  |         break; | ||||||
|  |  | ||||||
|  |       default: | ||||||
|  |         assertUnreachable("Unknown wrap mode!"); | ||||||
|  |     } | ||||||
|  |     assertNoGLError(); | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   setWrapMode(GL_TEXTURE_WRAP_S, this->wrapModeX); | ||||||
|  |   setWrapMode(GL_TEXTURE_WRAP_T, this->wrapModeY); | ||||||
|  |  | ||||||
|  |   auto setFilterMode = [&]( | ||||||
|  |     GLenum minMag, | ||||||
|  |     enum TextureFilterMode filter, | ||||||
|  |     enum TextureFilterMode mapFilterMode | ||||||
|  |   ) { | ||||||
|  |     switch(filter) { | ||||||
|  |       case TEXTURE_FILTER_MODE_NEAREST: { | ||||||
|  |         glTexParameteri(GL_TEXTURE_2D, minMag, GL_NEAREST); | ||||||
|  |         break; | ||||||
|  |       } | ||||||
|  |        | ||||||
|  |       case TEXTURE_FILTER_MODE_LINEAR: { | ||||||
|  |         glTexParameteri(GL_TEXTURE_2D, minMag, GL_LINEAR); | ||||||
|  |         break; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       default: { | ||||||
|  |         assertUnreachable("Unknown filter mode!"); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     assertNoGLError(); | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   setFilterMode( | ||||||
|  |     GL_TEXTURE_MIN_FILTER, this->filterModeMin, this->mipMapFilterModeMin | ||||||
|  |   ); | ||||||
|  |   setFilterMode( | ||||||
|  |     GL_TEXTURE_MAG_FILTER, this->filterModeMag, this->mipMapFilterModeMag | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Texture::bufferRaw(const void *data) { | ||||||
|  |   assertTrue(this->id != -1, "Texture is not ready!"); | ||||||
|  |  | ||||||
|  |   GLenum format; | ||||||
|  |   switch(this->format) { | ||||||
|  |     case TEXTURE_FORMAT_R: | ||||||
|  |       format = GL_RED; | ||||||
|  |       break; | ||||||
|  |  | ||||||
|  |     case TEXTURE_FORMAT_RG: | ||||||
|  |       format = GL_RG; | ||||||
|  |       break; | ||||||
|  |  | ||||||
|  |     case TEXTURE_FORMAT_RGB: | ||||||
|  |       format = GL_RGB; | ||||||
|  |       break; | ||||||
|  |  | ||||||
|  |     case TEXTURE_FORMAT_RGBA: | ||||||
|  |       format = GL_RGBA; | ||||||
|  |       break; | ||||||
|  |      | ||||||
|  |     default: | ||||||
|  |       assertUnreachable("Unknown texture format!"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   GLenum dataFormat; | ||||||
|  |   switch(this->dataFormat) { | ||||||
|  |     case TEXTURE_DATA_FORMAT_UNSIGNED_BYTE: | ||||||
|  |       dataFormat = GL_UNSIGNED_BYTE; | ||||||
|  |       break; | ||||||
|  |  | ||||||
|  |     case TEXTURE_DATA_FORMAT_FLOAT: | ||||||
|  |       dataFormat = GL_FLOAT; | ||||||
|  |       break; | ||||||
|  |  | ||||||
|  |     default: | ||||||
|  |       assertUnreachable("Unknown texture data format!"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   glBindTexture(GL_TEXTURE_2D, this->id); | ||||||
|  |   assertNoGLError(); | ||||||
|  |   glTexImage2D( | ||||||
|  |     GL_TEXTURE_2D, 0, format, | ||||||
|  |     this->width, this->height, | ||||||
|  |     0, format, dataFormat, data | ||||||
|  |   ); | ||||||
|  |   assertNoGLError(); | ||||||
|  |   glGenerateMipmap(GL_TEXTURE_2D); | ||||||
|  |   assertNoGLError(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Texture::buffer(const struct ColorU8 pixels[]) { | ||||||
|  |   assertTrue( | ||||||
|  |     this->dataFormat == TEXTURE_DATA_FORMAT_UNSIGNED_BYTE, | ||||||
|  |     "Texture data format must be unsigned byte!" | ||||||
|  |   ); | ||||||
|  |   this->bufferRaw((void*)pixels); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Texture::buffer(const struct Color pixels[]) { | ||||||
|  |   assertTrue( | ||||||
|  |     this->dataFormat == TEXTURE_DATA_FORMAT_FLOAT, | ||||||
|  |     "Texture data format must be float!" | ||||||
|  |   ); | ||||||
|  |   assertTrue( | ||||||
|  |     this->format == TEXTURE_FORMAT_RGBA, | ||||||
|  |     "Texture format must be RGBA!" | ||||||
|  |   ); | ||||||
|  |   this->bufferRaw((void*)pixels); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Texture::buffer(const uint8_t pixels[]) { | ||||||
|  |   assertTrue( | ||||||
|  |     this->dataFormat == TEXTURE_DATA_FORMAT_UNSIGNED_BYTE, | ||||||
|  |     "Texture data format must be unsigned byte!" | ||||||
|  |   ); | ||||||
|  |   this->bufferRaw((void*)pixels); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Texture::~Texture() { | ||||||
|  |   if(this->id != -1) { | ||||||
|  |     glDeleteTextures(1, &this->id); | ||||||
|  |     assertNoGLError(); | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										43
									
								
								src/dawnopengl/display/Texture.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/dawnopengl/display/Texture.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | |||||||
|  | // Copyright (c) 2022 Dominic Masters | ||||||
|  | //  | ||||||
|  | // This software is released under the MIT License. | ||||||
|  | // https://opensource.org/licenses/MIT | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  | #include "dawnopengl.hpp" | ||||||
|  | #include "display/ITexture.hpp" | ||||||
|  |  | ||||||
|  | namespace Dawn { | ||||||
|  |   class TextureRenderTarget; | ||||||
|  |    | ||||||
|  |   typedef GLuint textureslot_t; | ||||||
|  |  | ||||||
|  |   class Texture : public ITexture { | ||||||
|  |     private: | ||||||
|  |       int32_t width = -1; | ||||||
|  |       int32_t height = -1; | ||||||
|  |       GLuint id = -1; | ||||||
|  |       enum TextureFormat format; | ||||||
|  |       enum TextureDataFormat dataFormat; | ||||||
|  |  | ||||||
|  |       void updateTextureProperties(); | ||||||
|  |       void bufferRaw(const void *data); | ||||||
|  |  | ||||||
|  |     public: | ||||||
|  |       int32_t getWidth() override; | ||||||
|  |       int32_t getHeight() override; | ||||||
|  |       void setSize( | ||||||
|  |         const int32_t width, | ||||||
|  |         const int32_t height, | ||||||
|  |         const enum TextureFormat format, | ||||||
|  |         const enum TextureDataFormat dataForat | ||||||
|  |       ) override; | ||||||
|  |       // bool_t isReady() override; | ||||||
|  |       void buffer(const struct ColorU8 pixels[]) override; | ||||||
|  |       void buffer(const struct Color pixels[]); | ||||||
|  |       void buffer(const uint8_t pixels[]) override; | ||||||
|  |       void bind(const uint8_t slot) override; | ||||||
|  |  | ||||||
|  |       ~Texture(); | ||||||
|  |   }; | ||||||
|  | } | ||||||
| @@ -9,8 +9,11 @@ | |||||||
| #include "assert/assert.hpp" | #include "assert/assert.hpp" | ||||||
| #include "assert/assertgl.hpp" | #include "assert/assertgl.hpp" | ||||||
| #include "display/Color.hpp" | #include "display/Color.hpp" | ||||||
|  | #include "display/Texture.hpp" | ||||||
|  |  | ||||||
| namespace Dawn { | namespace Dawn { | ||||||
|  |   typedef GLuint shadertexturebinding_t; | ||||||
|  |  | ||||||
|   enum ShaderOpenGLVariant { |   enum ShaderOpenGLVariant { | ||||||
|     GLSL_330_CORE |     GLSL_330_CORE | ||||||
|   }; |   }; | ||||||
| @@ -151,6 +154,18 @@ namespace Dawn { | |||||||
|                   break; |                   break; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|  |                 case ShaderParameterType::BOOLEAN: { | ||||||
|  |                   auto boolean = (bool_t *)value; | ||||||
|  |                   glUniform1i(param.location, *boolean ? 1 : 0); | ||||||
|  |                   break; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 case ShaderParameterType::TEXTURE: { | ||||||
|  |                   textureslot_t texture = *((textureslot_t*)value); | ||||||
|  |                   glUniform1i(param.location, texture); | ||||||
|  |                   break; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|                 default: { |                 default: { | ||||||
|                   assertUnreachable("Unsupported ShaderParameterType"); |                   assertUnreachable("Unsupported ShaderParameterType"); | ||||||
|                 } |                 } | ||||||
|   | |||||||
| @@ -23,11 +23,14 @@ void SimpleTexturedShader::getStages( | |||||||
|         ShaderStageType::VERTEX, |         ShaderStageType::VERTEX, | ||||||
|         "#version 330 core\n" |         "#version 330 core\n" | ||||||
|         "layout (location = 0) in vec3 aPos;\n" |         "layout (location = 0) in vec3 aPos;\n" | ||||||
|  |         "layout (location = 1) in vec2 aTexCoord;\n" | ||||||
|         "uniform mat4 u_Projection;\n" |         "uniform mat4 u_Projection;\n" | ||||||
|         "uniform mat4 u_View;\n" |         "uniform mat4 u_View;\n" | ||||||
|         "uniform mat4 u_Model;\n" |         "uniform mat4 u_Model;\n" | ||||||
|  |         "out vec2 o_TextCoord;\n" | ||||||
|         "void main() {\n" |         "void main() {\n" | ||||||
|           "gl_Position = u_Projection * u_View * u_Model * vec4(aPos, 1.0);\n" |           "gl_Position = u_Projection * u_View * u_Model * vec4(aPos, 1.0);\n" | ||||||
|  |           "o_TextCoord = vec2(aTexCoord.x, aTexCoord.y);\n" | ||||||
|         "}" |         "}" | ||||||
|       ); |       ); | ||||||
|        |        | ||||||
| @@ -37,8 +40,14 @@ void SimpleTexturedShader::getStages( | |||||||
|         "in vec2 o_TextCoord;\n" |         "in vec2 o_TextCoord;\n" | ||||||
|         "out vec4 o_Color;\n" |         "out vec4 o_Color;\n" | ||||||
|         "uniform vec4 u_Color;\n" |         "uniform vec4 u_Color;\n" | ||||||
|  |         "uniform bool u_HasTexture;\n" | ||||||
|  |         "uniform sampler2D u_Texture;\n" | ||||||
|         "void main() {\n" |         "void main() {\n" | ||||||
|           "o_Color = u_Color;" |           "if(u_HasTexture) {\n" | ||||||
|  |             "o_Color = texture(u_Texture, o_TextCoord) * u_Color;\n" | ||||||
|  |           "} else {\n" | ||||||
|  |             "o_Color = u_Color;" | ||||||
|  |           "}\n" | ||||||
|         "}\n" |         "}\n" | ||||||
|       ); |       ); | ||||||
|       break; |       break; | ||||||
| @@ -75,4 +84,16 @@ void SimpleTexturedShader::getStages( | |||||||
|     &rel->color, |     &rel->color, | ||||||
|     ShaderParameterType::COLOR |     ShaderParameterType::COLOR | ||||||
|   )); |   )); | ||||||
|  |  | ||||||
|  |   parameters.push_back(ShaderOpenGLParameter( | ||||||
|  |     "u_HasTexture", | ||||||
|  |     &rel->hasTexture, | ||||||
|  |     ShaderParameterType::BOOLEAN | ||||||
|  |   )); | ||||||
|  |  | ||||||
|  |   parameters.push_back(ShaderOpenGLParameter( | ||||||
|  |     "u_Texture", | ||||||
|  |     &rel->texture, | ||||||
|  |     ShaderParameterType::TEXTURE | ||||||
|  |   )); | ||||||
| } | } | ||||||
| @@ -12,6 +12,8 @@ namespace Dawn { | |||||||
|     glm::mat4 view; |     glm::mat4 view; | ||||||
|     glm::mat4 model; |     glm::mat4 model; | ||||||
|     struct Color color = COLOR_WHITE; |     struct Color color = COLOR_WHITE; | ||||||
|  |     bool hasTexture = false; | ||||||
|  |     shadertexturebinding_t texture = 0; | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|   class SimpleTexturedShader : public Shader<SimpleTexturedShaderData> { |   class SimpleTexturedShader : public Shader<SimpleTexturedShaderData> { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user