diff options
author | chai <chaifix@163.com> | 2021-10-30 22:59:42 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2021-10-30 22:59:42 +0800 |
commit | 26f05c6e3dcac9995345fb5a2b031be7e3ea79e9 (patch) | |
tree | fc32c3e9d235817df0be331a6100b7f8263facab | |
parent | c3e259f4d29e9bdcb73617ad8e4d71f117b4d289 (diff) |
*TextGenerator
-rw-r--r-- | Data/Editor.exe | bin | 0 -> 2385408 bytes | |||
-rw-r--r-- | Data/Resources/Font/Deng.ttf | bin | 0 -> 16093132 bytes | |||
-rw-r--r-- | Data/Scripts/Editor/AssetBrowser.lua | 9 | ||||
-rw-r--r-- | Data/Scripts/EditorApplication.lua | 2 | ||||
-rw-r--r-- | Editor/EditorMain.cpp | 28 | ||||
-rw-r--r-- | Editor/GUI/ContainerWindow.cpp | 19 | ||||
-rw-r--r-- | Editor/GUI/EditorWindows.h | 4 | ||||
-rw-r--r-- | Editor/GUI/GUIWindow.cpp | 18 | ||||
-rw-r--r-- | Editor/Graphics/Graphics.cpp | 2 | ||||
-rw-r--r-- | Editor/Graphics/Graphics.h | 2 | ||||
-rw-r--r-- | Runtime/Common/DataBuffer.h | 2 | ||||
-rw-r--r-- | Runtime/FileSystem/ImageJobs.cpp | 4 | ||||
-rw-r--r-- | Runtime/GUI/TextGenerator.cpp | 205 | ||||
-rw-r--r-- | Runtime/GUI/TextGenerator.h | 89 | ||||
-rw-r--r-- | Runtime/Graphics/GfxDevice.cpp | 6 | ||||
-rw-r--r-- | Runtime/Graphics/ImageData.h | 38 | ||||
-rw-r--r-- | Runtime/Graphics/Texture.cpp | 118 | ||||
-rw-r--r-- | Runtime/Graphics/Texture.h | 3 | ||||
-rw-r--r-- | Runtime/Math/Math.h | 4 | ||||
-rw-r--r-- | Runtime/Math/Rect.h | 2 | ||||
-rw-r--r-- | Runtime/Scripting/Resource/Resource.bind.cpp | 4 |
21 files changed, 481 insertions, 78 deletions
diff --git a/Data/Editor.exe b/Data/Editor.exe Binary files differnew file mode 100644 index 0000000..e59406e --- /dev/null +++ b/Data/Editor.exe diff --git a/Data/Resources/Font/Deng.ttf b/Data/Resources/Font/Deng.ttf Binary files differnew file mode 100644 index 0000000..7438a2a --- /dev/null +++ b/Data/Resources/Font/Deng.ttf diff --git a/Data/Scripts/Editor/AssetBrowser.lua b/Data/Scripts/Editor/AssetBrowser.lua index a36cda2..68f0483 100644 --- a/Data/Scripts/Editor/AssetBrowser.lua +++ b/Data/Scripts/Editor/AssetBrowser.lua @@ -42,7 +42,11 @@ out vec4 FragColor; void main()
{
- FragColor = texture(uiTex, uv);
+ vec4 sampled = vec4(texture(uiTex, uv).r, 0, 0, 1.0);
+ FragColor = sampled;
+// FragColor = texture(uiTex, uv);
+// FragColor.rgb = vec3(1,0,0);
+// FragColor.a = 1;
}
FSH_END
@@ -52,6 +56,7 @@ local tex AssetBrowser.OnGUI = function(self)
+
if tex == nil then
tex = Engine.Resource.LoadTexture("./Resources/Images/brickwall.jpg")
end
@@ -76,7 +81,7 @@ AssetBrowser.OnGUI = function(self) Engine.Rendering.UseShader(shader)
Engine.Rendering.SetMatrix44("mvp", ortho)
- Engine.Rendering.SetTexture("tex", tex)
+ Engine.Rendering.SetTexture("uiTex", tex)
Engine.Rendering.DrawUIQuad({10, 30, 300, 300})
Engine.Rendering.ResetUniformState()
diff --git a/Data/Scripts/EditorApplication.lua b/Data/Scripts/EditorApplication.lua index 75749df..e9dbc32 100644 --- a/Data/Scripts/EditorApplication.lua +++ b/Data/Scripts/EditorApplication.lua @@ -111,6 +111,8 @@ local fsh = [[ } ]] +BeforeMainLoop() + while true do app:OnStep() diff --git a/Editor/EditorMain.cpp b/Editor/EditorMain.cpp index 69c1c1a..e31da28 100644 --- a/Editor/EditorMain.cpp +++ b/Editor/EditorMain.cpp @@ -9,6 +9,8 @@ #include "Editor/Win/Win.h"
#include "Runtime/Threading/Thread.h"
+#include "Runtime/GUI/TextGenerator.h"
+
using namespace LuaBind;
void ErrorHandle(cc8* msg)
@@ -16,6 +18,27 @@ void ErrorHandle(cc8* msg) log_error(std::string("[Lua] ") + msg);
}
+void TestFont()
+{
+ TextGeneratingSettings setting;
+ setting.margin = 5;
+ setting.padding = 3;
+ setting.atlasSize = Internal::Vector2(256, 256);
+ TextGenerator::Instance()->Setup(setting);
+ TextGenerator::Instance()->RenderCharacter(L'好', 14);
+ TextGenerator::Instance()->RenderCharacter(L'大', 14);
+ TextGenerator::Instance()->RenderCharacter(L'家', 14);
+ TextGenerator::Instance()->RenderCharacter(L'晚', 14);
+ TextGenerator::Instance()->RenderCharacter(L'上', 14);
+ TextGenerator::Instance()->RenderCharacter(L'快', 14);
+}
+
+int BeforeMainLoop(lua_State* L)
+{
+ TestFont();
+ return 0;
+}
+
void InitLuaState(LuaBind::VM& vm)
{
vm.Setup();
@@ -35,6 +58,9 @@ void InitLuaState(LuaBind::VM& vm) Win::SetDllSearchDirectory(workingDir);
LuaBind::State state = vm.GetMainState();
+ state.PushGlobalNamespace();
+ state.RegisterMethod("BeforeMainLoop", BeforeMainLoop);
+
state.DoFile("./boot.lua");
}
@@ -50,4 +76,4 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) InitLuaState(vm);
return 0;
-}
\ No newline at end of file +}
diff --git a/Editor/GUI/ContainerWindow.cpp b/Editor/GUI/ContainerWindow.cpp index 62c6cb7..01bb1e9 100644 --- a/Editor/GUI/ContainerWindow.cpp +++ b/Editor/GUI/ContainerWindow.cpp @@ -196,8 +196,8 @@ void ContainerWindow::DoPaint() void ContainerWindow::SetAsRenderContext() { Assert(m_DC != NULL); - Assert(m_RC != NULL); - Assert(wglMakeCurrent(m_DC, m_RC)); + Assert(g_GLRC != NULL); + Assert(wglMakeCurrent(m_DC, g_GLRC)); RECT rect; GetWindowRect(m_Window, &rect); glViewport(0, 0, rect.right - rect.left, rect.bottom - rect.top); @@ -256,16 +256,15 @@ bool ContainerWindow::SetRenderContext() int pf = 0; DescribePixelFormat(m_DC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd); - if (!(m_RC = wglCreateContext(m_DC))) // Are We Able To Get A Rendering Context? - { - MessageBox(NULL, "Can't Create A GL Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); - return FALSE; // Return FALSE - } - - if (m_RC && !g_IsGLInitialized) + if (g_GLRC == NULL || !g_IsGLInitialized) { + if (!(g_GLRC = wglCreateContext(m_DC))) // Are We Able To Get A Rendering Context? + { + MessageBox(NULL, "Can't Create A GL Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } log_info("Initialize OpenGL"); - wglMakeCurrent(m_DC, m_RC); + wglMakeCurrent(m_DC, g_GLRC); if (!gladLoadGL()) { log_error("初始化GL错误"); } diff --git a/Editor/GUI/EditorWindows.h b/Editor/GUI/EditorWindows.h index 79e047c..e1ad89a 100644 --- a/Editor/GUI/EditorWindows.h +++ b/Editor/GUI/EditorWindows.h @@ -67,7 +67,6 @@ public: GET(HWND, WindowHandle, m_Window); GET(HDC, DC, m_DC); - GET(HGLRC, RC, m_RC); void OnRectChanged(); void OnActivateApplication(bool active); @@ -79,7 +78,6 @@ private: HWND m_Window; HDC m_DC; - HGLRC m_RC; POINT m_Size; ShowMode m_ShowMode; // 窗口类型 bool m_IsClosing; @@ -149,7 +147,6 @@ public: GET_SET(std::string, Name, m_Name); GET(HDC, DC, m_DC); - GET(HGLRC, RC, m_RC); private: void ProcessEventMessages(UINT message, WPARAM wParam, LPARAM lParam); @@ -160,7 +157,6 @@ private: ContainerWindow* m_ContainerWindow; HWND m_Handle; HDC m_DC; - HGLRC m_RC; std::vector<LuaBind::MemberRef> m_EditorWindows; diff --git a/Editor/GUI/GUIWindow.cpp b/Editor/GUI/GUIWindow.cpp index fddc68d..eb44647 100644 --- a/Editor/GUI/GUIWindow.cpp +++ b/Editor/GUI/GUIWindow.cpp @@ -293,21 +293,6 @@ bool GUIWindow::SetRenderContext() int pf = 0; DescribePixelFormat(m_DC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd); - if (!(m_RC = wglCreateContext(m_DC))) // Are We Able To Get A Rendering Context? - { - MessageBox(NULL, "Can't Create A GL Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); - return FALSE; // Return FALSE - } - - if (m_RC && !g_IsGLInitialized) - { - log_info("Initialize OpenGL"); - wglMakeCurrent(m_DC, m_RC); - if (!gladLoadGL()) { - log_error("初始化GL错误"); - } - g_IsGLInitialized = true; - } return true; } @@ -345,8 +330,7 @@ void GUIWindow::SetPosition(Internal::Rect position) void GUIWindow::SetAsRenderContext() { Assert(m_DC != NULL); - Assert(m_RC != NULL); - Assert(wglMakeCurrent(m_DC, m_RC)); + Assert(wglMakeCurrent(m_DC, g_GLRC)); RECT rect; GetWindowRect(m_Handle, &rect); glViewport(0, 0, rect.right - rect.left, rect.bottom - rect.top); diff --git a/Editor/Graphics/Graphics.cpp b/Editor/Graphics/Graphics.cpp index af48d75..4c9465f 100644 --- a/Editor/Graphics/Graphics.cpp +++ b/Editor/Graphics/Graphics.cpp @@ -1,3 +1,5 @@ #include "Graphics.h"
bool g_IsGLInitialized = false;
+
+HGLRC g_GLRC = NULL;
\ No newline at end of file diff --git a/Editor/Graphics/Graphics.h b/Editor/Graphics/Graphics.h index ad27ede..f32246a 100644 --- a/Editor/Graphics/Graphics.h +++ b/Editor/Graphics/Graphics.h @@ -1,3 +1,5 @@ #pragma once
+#include <windows.h>
extern bool g_IsGLInitialized;
+extern HGLRC g_GLRC;
\ No newline at end of file diff --git a/Runtime/Common/DataBuffer.h b/Runtime/Common/DataBuffer.h index 74d2b02..7004937 100644 --- a/Runtime/Common/DataBuffer.h +++ b/Runtime/Common/DataBuffer.h @@ -17,7 +17,7 @@ public: delete data; } - char* data; + unsigned char* data; int length; private: diff --git a/Runtime/FileSystem/ImageJobs.cpp b/Runtime/FileSystem/ImageJobs.cpp index 84e4ff3..1d836d2 100644 --- a/Runtime/FileSystem/ImageJobs.cpp +++ b/Runtime/FileSystem/ImageJobs.cpp @@ -41,8 +41,8 @@ void ReadImageFileJob::Dispacth(void* param) bridge.pixels = NULL; imgData->width = bridge.width; imgData->height = bridge.height; - imgData->format = ImageData::EPixelFormat::RGB; - imgData->type = ImageData::EPixelElementType::UNSIGNED_BYTE; + imgData->format = EPixelFormat::PixelFormat_RGB; + imgData->type = EPixelElementType::PixelType_UNSIGNED_BYTE; callback.PushRef(state); imgData->PushUserdata(state); diff --git a/Runtime/GUI/TextGenerator.cpp b/Runtime/GUI/TextGenerator.cpp index 6841c4e..a518772 100644 --- a/Runtime/GUI/TextGenerator.cpp +++ b/Runtime/GUI/TextGenerator.cpp @@ -1,19 +1,206 @@ #include "freetype.h" #include "TextGenerator.h" #include "../Math/Math.h" +#include "Runtime/Debug/Log.h" +#include "Runtime/Utilities/Assert.h" +#include "Runtime/Graphics/ImageData.h" using namespace character; +//https://unicode-table.com/en/#cjk-unified-ideographs-extension-a //https://learnopengl.com/In-Practice/Text-Rendering +//https://www.zhihu.com/question/294660079 +//https://baike.baidu.com/item/%E5%9F%BA%E6%9C%AC%E5%A4%9A%E6%96%87%E7%A7%8D%E5%B9%B3%E9%9D%A2/10788078 +//https://stackoverflow.com/questions/27331819/whats-the-difference-between-a-character-a-code-point-a-glyph-and-a-grapheme -struct Character { - unsigned int textureID; // ID handle of the glyph texture - Internal::Vector2 size; // Size of glyph - Internal::Vector2 bearing; // Offset from baseline to left/top of glyph - unsigned int advance; // Offset to advance to next glyph -}; +void TextGenerator::Setup(TextGeneratingSettings settings) +{ + m_AtlasMargin = settings.margin; + m_GlyphPadding = settings.padding; + m_AtlasSize = settings.atlasSize; + + if (FT_Init_FreeType(&m_FTLibrary)) + { + return; + } + + if (FT_New_Face(m_FTLibrary, "Resources/Font/Deng.ttf", 0, &m_FTFace)) + { + return; + } +} + +character::Hash TextGenerator::GetHash(Codepoint codepoint, int pixelSize) +{ + character::Hash hash; + hash.codepoint = codepoint; + hash.size = pixelSize; + return hash; +} + +Character TextGenerator::GetCharacter(character::Codepoint codepoint, int pixelSize) +{ + character::Hash hash = GetHash(codepoint, pixelSize); + auto iter = m_Characters.find(hash); + if (iter == m_Characters.end()) + { + RenderCharacter(codepoint, pixelSize); + iter = m_Characters.find(hash); + } + Assert(iter != m_Characters.end()); + return iter->second; +} + +void TextGenerator::RenderCharacter(character::Codepoint codepoint, int pixelSize) +{ + character::Hash hash = GetHash(codepoint, pixelSize); +// if (m_Characters.count(hash) != 0) +// return; + FT_Set_Pixel_Sizes(m_FTFace, 0, pixelSize); + if (FT_Load_Char(m_FTFace, codepoint, FT_LOAD_RENDER)) + { + return; + } + + int w = m_FTFace->glyph->bitmap.width; + int h = m_FTFace->glyph->bitmap.rows; + + TextHelper::print_glyph(m_FTFace->glyph->bitmap.buffer, w, h); + + GlyphAtals* atlas = RequestAtlas(pixelSize, Internal::Vector2(w, h)); + Assert(atlas); + + Internal::Rect rect = GetRenderChartAndMove(atlas, Internal::Vector2(w, h)); + + try + { + atlas->altas->UpdateSubImage(rect, EPixelFormat::PixelFormat_R, EPixelElementType::PixelType_UNSIGNED_BYTE, m_FTFace->glyph->bitmap.buffer); + } + catch (TextureException& e) + { + std::string error = e.what(); + error = "Render Character Error: " + error; + log_error(e.what()); + return; + } + + Character character; + character.atlas = atlas->index; + character.position = rect; + character.bearing = Internal::Vector2(m_FTFace->glyph->bitmap_left, m_FTFace->glyph->bitmap_top); + character.advance = m_FTFace->glyph->advance.x; + + m_Characters.insert(std::pair<character::Hash, Character>(hash, character)); +} + +GlyphAtals* TextGenerator::GetGlyphAtlas(int index) +{ + if (index >= m_Atlases.size()) + return NULL; + return &m_Atlases[index]; +} + +Internal::Rect TextGenerator::GetRenderChartAndMove(GlyphAtals* atlas, Internal::Vector2 preferSize) +{ + Internal::Rect rect; + Internal::Vector2 space; + space.x = atlas->width - m_AtlasMargin * 2 - m_GlyphPadding - atlas->cursor.x; + space.y = atlas->height - m_AtlasMargin * 2 - m_GlyphPadding - atlas->cursor.y; + if (space.x > preferSize.x && space.y > preferSize.y) + { + rect.x = atlas->cursor.x; + rect.y = atlas->cursor.y; + rect.width = preferSize.x; + rect.height = preferSize.y; + atlas->cursor.x += rect.width; + atlas->rowHeight = max(atlas->rowHeight, preferSize.y); + } + else if (space.y - atlas->rowHeight > preferSize.y) + { + rect.x = m_AtlasMargin; + rect.y = atlas->cursor.y + m_GlyphPadding + atlas->rowHeight; + rect.width = preferSize.x; + rect.height = preferSize.y; + atlas->cursor.x = m_AtlasMargin; + atlas->cursor.y += atlas->rowHeight; + atlas->rowHeight = rect.height; + } + else + { + Assert(false); + } + return rect; +} + +GlyphAtals* TextGenerator::RequestAtlas(int pixelSize, Internal::Vector2 preferSize) +{ + GlyphAtals* atlas = NULL; + auto iter = m_AtlasCache.find(pixelSize); + if (iter == m_AtlasCache.end() || !HasEnoughSpace(iter->second, preferSize)) + { + Texture* tex = CreateAtlas(); + GlyphAtals newAtlas = GlyphAtals(); + newAtlas.altas = tex; + newAtlas.width = m_AtlasSize.x; + newAtlas.height = m_AtlasSize.y; + newAtlas.index = m_Atlases.size(); + newAtlas.cursor = Internal::Vector2(m_AtlasMargin, m_AtlasMargin); + + m_Atlases.push_back(newAtlas); + atlas = &m_Atlases[m_Atlases.size() - 1]; + + if (iter != m_AtlasCache.end()) + m_AtlasCache.erase(pixelSize); + m_AtlasCache.insert(std::pair<int, GlyphAtals*>(pixelSize, atlas)); + } + else + { + atlas = iter->second; + } + Assert(atlas); + return atlas; +} + +Texture* TextGenerator::CreateAtlas() +{ + TextureSetting setting; + setting.filterMode = ETextureFilterMode::Linear; + setting.wrapMode = ETextureWrapMode::Clamp; + setting.format = ETextureFormat::R8; + setting.type = ETextureType::TEX_2D; + setting.keepImageData = false; + Texture* tex = new Texture(setting, m_AtlasSize.x, m_AtlasSize.y); + return tex; +} + +bool TextGenerator::HasEnoughSpace(GlyphAtals* atlas, Internal::Vector2 preferSize) +{ + if (atlas == NULL) + return false; + Internal::Vector2 space; + space.x = atlas->width - m_AtlasMargin * 2 - m_GlyphPadding - atlas->cursor.x; + space.y = atlas->height - m_AtlasMargin * 2 - m_GlyphPadding - atlas->cursor.y; + if (space.x > preferSize.x && space.y > preferSize.y) + return true; + if (space.y - atlas->rowHeight > preferSize.y) + return true; + return false; +} + +Character GetCharacter(character::Codepoint Codepoint, int pixelSize) +{ + return Character(); +} -hash TextGenerator::GetCharacterHash(unicode unicode, int pixelSize) +void TextHelper::print_glyph(unsigned char* glyph, int width, int height) { - -}
\ No newline at end of file + for (int r = 0; r < height; ++r) + { + for (int c = 0; c < width; ++c) + { + unsigned char ch = glyph[c + r * width]; + printf("%c", ch == 0 ? ' ' : '+'); + } + printf("\n"); + } +} diff --git a/Runtime/GUI/TextGenerator.h b/Runtime/GUI/TextGenerator.h index eacc99c..1065acf 100644 --- a/Runtime/GUI/TextGenerator.h +++ b/Runtime/GUI/TextGenerator.h @@ -1,32 +1,105 @@ #pragma once #include "Runtime/Utilities/Singleton.h" +#include "Runtime/Graphics/Texture.h" +#include "freetype.h" + #include <string> #include <unordered_map> +#include <vector> //https://learnopengl.com/In-Practice/Text-Rendering struct Character { - unsigned int textureID; // ID handle of the glyph texture - Internal::Vector2 size; // Size of glyph - Internal::Vector2 bearing; // Offset from baseline to left/top of glyph - unsigned int advance; // Offset to advance to next glyph + unsigned int atlas; // atlas索引 + Internal::Rect position; // 在altas里的位置 + Internal::Vector2 bearing; // 左上角相对于原点的偏移 + unsigned int advance; // 总宽,算上了间隔 }; namespace character { - typedef wchar_t unicode; - typedef unsigned int hash; + typedef unsigned short Codepoint; // unicode Codepoint(BMP,U+0000至U+FFFF) + + union Hash { + unsigned int hashCode; + struct { + Codepoint codepoint; + unsigned short size;//字体大小 + }; + bool operator==(const Hash &other) const + { + return codepoint == other.codepoint && size == other.size; + } + }; +} + +namespace std +{ + template <> + struct hash<character::Hash> + { + std::size_t operator()(const character::Hash& k) const + { + return k.hashCode; + } + }; } +struct GlyphAtals +{ + int index; + Texture* altas; // 贴图 + int width, height; // 尺寸 + Internal::Vector2 cursor; // 游标,从左上角(0,0)开始 + int rowHeight; // 当前行的高度 +}; + +struct TextGeneratingSettings +{ + Internal::Vector2 atlasSize; // atlas的尺寸 + int margin; // atlas的边界 + int padding; // glyph相互之间的间距,防止采样的时候越界 +}; + class TextGenerator : public Singleton<TextGenerator> { public: + void Setup(TextGeneratingSettings settings); + Character GetCharacter(character::Codepoint codepoint, int pixelSize); + void RenderCharacter(character::Codepoint codepoint, int pixelSize); + GlyphAtals* GetGlyphAtlas(int index); private: - std::unordered_map<character::hash, Character> m_Characters; - character::hash GetCharacterHash(character::unicode unicode, int pixelSize); + Texture* CreateAtlas(); + GlyphAtals* RequestAtlas(int pixelSize, Internal::Vector2 preferSize); + + Internal::Rect GetRenderChartAndMove(GlyphAtals* atlas, Internal::Vector2 preferSize); + bool HasEnoughSpace(GlyphAtals* atlas, Internal::Vector2 preferSize); + + std::unordered_map<character::Hash, Character> m_Characters; // 渲染完的文字 + + std::vector<GlyphAtals> m_Atlases; // 当前所有的atlas + std::unordered_map<int, GlyphAtals*> m_AtlasCache; // 快速找到可用的atlas + + int m_AtlasMargin; + int m_GlyphPadding; + Internal::Vector2 m_AtlasSize; + + FT_Library m_FTLibrary; + FT_Face m_FTFace; + + character::Hash GetHash(character::Codepoint Codepoint, int pixelSize); }; + +#define g_TextGenerator (*TextGenerator::Instance()) + +namespace TextHelper +{ + + void print_glyph(unsigned char* glyph, int width, int height); + +} diff --git a/Runtime/Graphics/GfxDevice.cpp b/Runtime/Graphics/GfxDevice.cpp index d30a60a..f318487 100644 --- a/Runtime/Graphics/GfxDevice.cpp +++ b/Runtime/Graphics/GfxDevice.cpp @@ -80,6 +80,9 @@ void GfxDevice::UseShader(LuaBind::State& state, Shader* shader, int idx) m_Shader.shader = shader; m_Shader.ref.SetRef(state, idx); + + glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } void GfxDevice::UnuseShader() @@ -135,7 +138,8 @@ void GfxDevice::SetUniformTexture(const char* name, Texture* texture) int texUnit = s_TextureUnitBucket.back(); s_TextureUnitBucket.pop_back(); glActiveTexture(GL_TEXTURE0 + texUnit);
- glBindTexture(GL_TEXTURE_2D, texture->GetGpuID());
+ //glBindTexture(GL_TEXTURE_2D, texture->GetGpuID());
+ glBindTexture(GL_TEXTURE_2D, 2);
GLint loc = glGetUniformLocation(m_Shader.GetID(), name); glUniform1i(loc, texUnit); diff --git a/Runtime/Graphics/ImageData.h b/Runtime/Graphics/ImageData.h index 7bf0335..fe26776 100644 --- a/Runtime/Graphics/ImageData.h +++ b/Runtime/Graphics/ImageData.h @@ -5,29 +5,29 @@ #include "Runtime/Threading/Job.h" #include "Runtime/Lua/LuaHelper.h" +enum EPixelFormat +{ + PixelFormat_RGBA, + PixelFormat_RGB, + PixelFormat_R, + PixelFormat_RG, + PixelFormat_BGR, + PixelFormat_BGRA +}; + +enum EPixelElementType +{ + PixelType_UNSIGNED_BYTE, + PixelType_UNSIGNED_INT, + PixelType_BYTE, + PixelType_INT, + PixelType_FLOAT, +}; + // 图片像素数据 class ImageData : public LuaBind::NativeClass<ImageData> { public: - enum EPixelFormat - { - RGBA, - RGB, - R, - RG, - BGR, - BGRA - }; - - enum EPixelElementType - { - UNSIGNED_BYTE, - UNSIGNED_INT, - BYTE, - INT, - FLOAT, - }; - ImageData(LuaBind::VM* vm) : LuaBind::NativeClass<ImageData>(vm) { diff --git a/Runtime/Graphics/Texture.cpp b/Runtime/Graphics/Texture.cpp index 6b682e9..f92c094 100644 --- a/Runtime/Graphics/Texture.cpp +++ b/Runtime/Graphics/Texture.cpp @@ -3,7 +3,6 @@ using namespace LuaBind;
-
Texture::Texture(TextureSetting setting, ImageData* imgData)
: NativeClass<Texture>()
{
@@ -94,7 +93,124 @@ void Texture::Init(TextureSetting setting, ImageData* imgData) );
}
+Texture::Texture(TextureSetting setting, int w, int h)
+ : NativeClass<Texture>()
+{
+ m_KeepPixelData = false;
+
+ m_Width = w;
+ m_Height = h;
+ m_Type = setting.type;
+ m_Format = setting.format;
+ m_WrapMode = setting.wrapMode;
+ m_FilterMode = setting.filterMode;
+ m_KeepPixelData = setting.keepImageData;
+
+ glGenTextures(1, &m_GPUID);
+ glBindTexture(GL_TEXTURE_2D, m_GPUID);
+
+ CheckGLError(
+ glDeleteTextures(1, &m_GPUID);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ throw TextureException(error);
+ );
+
+ switch (m_WrapMode) {
+ case ETextureWrapMode::Clamp:
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ break;
+ case ETextureWrapMode::Repeat:
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ break;
+ case ETextureWrapMode::Mirror:
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
+ break;
+ default:
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ break;
+ }
+
+ CheckGLError(
+ glDeleteTextures(1, &m_GPUID);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ throw TextureException(error);
+ );
+
+ switch (m_FilterMode) {
+ case ETextureFilterMode::Linear:
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ break;
+ case ETextureFilterMode::Nearest:
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ break;
+ default:
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ break;
+ }
+ GLenum internalFormat = GL_RGB;
+ if (m_Format == ETextureFormat::R8)
+ {
+ internalFormat = GL_RED;
+ }
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
+
+ CheckGLError(
+ glDeleteTextures(1, &m_GPUID);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ throw TextureException(error);
+ );
+}
+
Texture::~Texture()
{
glDeleteTextures(1, &m_GPUID);
+}
+
+void Texture::UpdateSubImage(Internal::Rect rect, int format, int type, const void* data)
+{
+ glBindTexture(GL_TEXTURE_2D, m_GPUID);
+
+ CheckGLError(
+ glBindTexture(GL_TEXTURE_2D, 0);
+ throw TextureException(error);
+ );
+
+ GLenum fmt = GL_RED;
+ switch (format)
+ {
+ case EPixelFormat::PixelFormat_BGR: fmt = GL_BGR; break;
+ case EPixelFormat::PixelFormat_BGRA:fmt = GL_BGRA; break;
+ case EPixelFormat::PixelFormat_R: fmt = GL_RED; break;
+ case EPixelFormat::PixelFormat_RG: fmt = GL_RG; break;
+ case EPixelFormat::PixelFormat_RGB: fmt = GL_RGB; break;
+ case EPixelFormat::PixelFormat_RGBA: fmt = GL_RGBA; break;
+ }
+ GLenum t = GL_UNSIGNED_BYTE;
+ switch (type)
+ {
+ case EPixelElementType::PixelType_UNSIGNED_BYTE: t = GL_UNSIGNED_BYTE; break;
+ case EPixelElementType::PixelType_UNSIGNED_INT: t = GL_UNSIGNED_INT; break;
+ case EPixelElementType::PixelType_BYTE: t = GL_BYTE; break;
+ case EPixelElementType::PixelType_INT: t = GL_INT; break;
+ case EPixelElementType::PixelType_FLOAT: t = GL_FLOAT; break;
+ }
+
+ glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x, rect.y, rect.width, rect.height, fmt, t, data);
+
+ CheckGLError(
+ glBindTexture(GL_TEXTURE_2D, 0);
+ throw TextureException(error);
+ );
+
+ glBindTexture(GL_TEXTURE_2D, 0);
}
\ No newline at end of file diff --git a/Runtime/Graphics/Texture.h b/Runtime/Graphics/Texture.h index d02634c..6ead2fb 100644 --- a/Runtime/Graphics/Texture.h +++ b/Runtime/Graphics/Texture.h @@ -61,10 +61,13 @@ public: class Texture : public LuaBind::NativeClass<Texture> { public: + Texture(TextureSetting setting, int width, int height)/*throw TextureException*/; // 空贴图 Texture(TextureSetting setting, ImageData* imgData)/*throw TextureException*/; Texture(LuaBind::VM* vm, TextureSetting setting, ImageData* imgData)/*throw TextureException*/; ~Texture(); + void UpdateSubImage(Internal::Rect rect, int format, int type, const void* data); + GET(int, Width, m_Width); GET(int, Height, m_Height); diff --git a/Runtime/Math/Math.h b/Runtime/Math/Math.h index 370b91c..7f61544 100644 --- a/Runtime/Math/Math.h +++ b/Runtime/Math/Math.h @@ -5,3 +5,7 @@ #include "Vector4.h" #include "Matrix44.h" #include "FloatConversion.h" +#include "Rect.h" + +#define max(a, b)\ +(a)>(b)?(a):(b) diff --git a/Runtime/Math/Rect.h b/Runtime/Math/Rect.h index 80170d6..8e7dae6 100644 --- a/Runtime/Math/Rect.h +++ b/Runtime/Math/Rect.h @@ -4,6 +4,6 @@ namespace Internal { struct Rect { - int x, y, width, height; + float x, y, width, height; }; }
\ No newline at end of file diff --git a/Runtime/Scripting/Resource/Resource.bind.cpp b/Runtime/Scripting/Resource/Resource.bind.cpp index 6f9c0bb..379d88d 100644 --- a/Runtime/Scripting/Resource/Resource.bind.cpp +++ b/Runtime/Scripting/Resource/Resource.bind.cpp @@ -32,8 +32,8 @@ int LoadImageData(lua_State* L) ImageData* data = new ImageData(state.GetVM()); int channels; data->pixels = stbi_load(path, &data->width, &data->height, &channels, 0); - data->format = ImageData::EPixelFormat::RGB; - data->type = ImageData::EPixelElementType::UNSIGNED_BYTE; + data->format = EPixelFormat::PixelFormat_RGB; + data->type = EPixelElementType::PixelType_UNSIGNED_BYTE; data->PushUserdata(state); return 1; |