From e9438ee0f6bcb41485bd4ab3cdb33b42d29d62f1 Mon Sep 17 00:00:00 2001 From: Kai Blaschke Date: Sat, 29 Apr 2023 15:32:01 +0200 Subject: [PATCH] Deleted lots of unused files and code. --- src/libprojectM/Audio/BeatDetect.cpp | 9 +- src/libprojectM/CMakeLists.txt | 8 - src/libprojectM/Common.hpp | 87 -- src/libprojectM/HungarianMethod.hpp | 191 --- .../MilkdropPreset/MilkdropPreset.cpp | 2 + src/libprojectM/PresetFactoryManager.cpp | 18 +- src/libprojectM/PresetFactoryManager.hpp | 2 + src/libprojectM/ProjectM.cpp | 25 +- src/libprojectM/ProjectM.hpp | 19 +- src/libprojectM/Renderer/CMakeLists.txt | 1 + src/libprojectM/Renderer/FileScanner.cpp | 9 +- .../{ => Renderer}/IdleTextures.hpp | 0 src/libprojectM/Renderer/RenderContext.hpp | 1 - src/libprojectM/Renderer/Renderer.cpp | 395 +---- src/libprojectM/Renderer/Renderer.hpp | 67 +- src/libprojectM/Renderer/TextureManager.cpp | 8 +- src/libprojectM/TestRunner.cpp | 0 src/libprojectM/carbontoprojectM.h | 85 -- src/libprojectM/cocoatoprojectM.h | 63 - src/libprojectM/fatal.h | 43 - src/libprojectM/glError.h | 31 - src/libprojectM/gltext.h | 1356 ----------------- src/libprojectM/resource.h | 14 - 23 files changed, 41 insertions(+), 2393 deletions(-) delete mode 100755 src/libprojectM/Common.hpp delete mode 100644 src/libprojectM/HungarianMethod.hpp rename src/libprojectM/{ => Renderer}/IdleTextures.hpp (100%) delete mode 100644 src/libprojectM/TestRunner.cpp delete mode 100755 src/libprojectM/carbontoprojectM.h delete mode 100644 src/libprojectM/cocoatoprojectM.h delete mode 100755 src/libprojectM/fatal.h delete mode 100644 src/libprojectM/glError.h delete mode 100644 src/libprojectM/gltext.h delete mode 100644 src/libprojectM/resource.h diff --git a/src/libprojectM/Audio/BeatDetect.cpp b/src/libprojectM/Audio/BeatDetect.cpp index 1dd02bb5b..96eca68dc 100755 --- a/src/libprojectM/Audio/BeatDetect.cpp +++ b/src/libprojectM/Audio/BeatDetect.cpp @@ -26,18 +26,11 @@ * you'll find it online */ -#include -#include -#include - -#include "wipemalloc.h" - #include "BeatDetect.hpp" #include "PCM.hpp" #include -#include - +#include namespace libprojectM { namespace Audio { diff --git a/src/libprojectM/CMakeLists.txt b/src/libprojectM/CMakeLists.txt index 50c80a8d6..ef9ec5d3b 100644 --- a/src/libprojectM/CMakeLists.txt +++ b/src/libprojectM/CMakeLists.txt @@ -26,9 +26,6 @@ add_library(projectM_main OBJECT Audio/PCM.hpp Audio/fftsg.cpp Audio/fftsg.h - Common.hpp - HungarianMethod.hpp - IdleTextures.hpp Preset.hpp PresetFactory.cpp PresetFactory.hpp @@ -41,11 +38,7 @@ add_library(projectM_main OBJECT RandomNumberGenerators.hpp TimeKeeper.cpp TimeKeeper.hpp - fatal.h - glError.h - gltext.h projectM-opengl.h - resource.h wipemalloc.cpp wipemalloc.h ) @@ -168,7 +161,6 @@ if(ENABLE_CXX_INTERFACE) endif() install(FILES - Common.hpp Audio/PCM.hpp ProjectM.hpp DESTINATION "${PROJECTM_INCLUDE_DIR}/projectM-4" diff --git a/src/libprojectM/Common.hpp b/src/libprojectM/Common.hpp deleted file mode 100755 index 92d631fda..000000000 --- a/src/libprojectM/Common.hpp +++ /dev/null @@ -1,87 +0,0 @@ -/** - * projectM -- Milkdrop-esque visualisation SDK - * Copyright (C)2003-2007 projectM Team - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * See 'LICENSE.txt' included within this release - * - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -//CPP17: std::filesystem::path::preferred_separator -/** Per-platform path separators */ -#ifdef _WIN32 -char constexpr pathSeparator{'\\'}; -#else -char constexpr pathSeparator{'/'}; -#endif /** _WIN32 */ - -size_t constexpr maxTokenSize{512}; -size_t constexpr maxPathSize{4096}; - -//CPP23: uz suffix (https://en.cppreference.com/w/cpp/language/integer_literal) -size_t constexpr stringBufferSize{static_cast(1024 * 150)}; -size_t constexpr stringLineSize{1024}; - -double constexpr maxDoubleSize{10000000.0}; -double constexpr minDoubleSize{-maxDoubleSize}; - -int constexpr maxIntSize{10000000}; -int constexpr minIntSize{-maxIntSize}; - -/* default float initial value */ -double constexpr defaultDoubleIv{0.0}; - -/* default float lower bound */ -double constexpr defaultDoubleLb{minDoubleSize}; - -/* default float upper bound */ -double constexpr defaultDoubleUb{maxDoubleSize}; - -unsigned int const numQVariables(32); - -//CPP17: std::filesystem::path::extension -inline auto ParseExtension(const std::string& filename) -> std::string -{ - const auto start = filename.find_last_of('.'); - - if (start == std::string::npos || start >= (filename.length() - 1)) { - return ""; - } - std::string ext = filename.substr(start + 1, filename.length()); - std::transform(ext.begin(), ext.end(), ext.begin(), tolower); - return ext; -} - -//CPP17: std::filesystem::path::filename -inline auto ParseFilename(const std::string& filename) -> std::string -{ - const auto start = filename.find_last_of('/'); - - if (start == std::string::npos || start >= (filename.length() - 1)) { - return ""; - } - - return filename.substr(start + 1, filename.length()); -} diff --git a/src/libprojectM/HungarianMethod.hpp b/src/libprojectM/HungarianMethod.hpp deleted file mode 100644 index 2598ae4fc..000000000 --- a/src/libprojectM/HungarianMethod.hpp +++ /dev/null @@ -1,191 +0,0 @@ -#ifndef HUNGARIAN_METHOD_HPP -#define HUNGARIAN_METHOD_HPP -#include -#include -#include -#include - -/// A function object which calculates the maximum-weighted bipartite matching between -/// two sets via the hungarian method. -template -class HungarianMethod { -public : -static const size_t MAX_SIZE = N; - -private: -size_t n, max_match; //n workers and n jobs -double lx[N], ly[N]; //labels of X and Y parts -int xy[N]; //xy[x] - vertex that is matched with x, -int yx[N]; //yx[y] - vertex that is matched with y -bool S[N], T[N]; //sets S and T in algorithm -double slack[N]; //as in the algorithm description -double slackx[N]; //slackx[y] such a vertex, that - // l(slackx[y]) + l(y) - w(slackx[y],y) = slack[y] -int prev[N]; //array for memorizing alternating paths - -void init_labels(const double cost[N][N]) -{ - memset(lx, 0, sizeof(lx)); - memset(ly, 0, sizeof(ly)); - for (unsigned int x = 0; x < n; x++) - for (unsigned int y = 0; y < n; y++) - lx[x] = std::max(lx[x], cost[x][y]); -} - -void augment(const double cost[N][N]) //main function of the algorithm -{ - if (max_match == n) return; //check wether matching is already perfect - unsigned int x, y, root = 0; //just counters and root vertex - int q[N], wr = 0, rd = 0; //q - queue for bfs, wr,rd - write and read - //pos in queue - memset(S, false, sizeof(S)); //init set S - memset(T, false, sizeof(T)); //init set T - memset(prev, -1, sizeof(prev)); //init set prev - for the alternating tree - for (x = 0; x < n; x++) //finding root of the tree - if (xy[x] == -1) - { - q[wr++] = root = x; - prev[x] = -2; - S[x] = true; - break; - } - - for (y = 0; y < n; y++) //initializing slack array - { - slack[y] = lx[root] + ly[y] - cost[root][y]; - slackx[y] = root; - } - while (true) //main cycle - { - while (rd < wr) //building tree with bfs cycle - { - x = q[rd++]; //current vertex from X part - for (y = 0; y < n; y++) //iterate through all edges in equality graph - if (cost[x][y] == lx[x] + ly[y] && !T[y]) - { - if (yx[y] == -1) break; //an exposed vertex in Y found, so - //augmenting path exists! - T[y] = true; //else just add y to T, - q[wr++] = yx[y]; //add vertex yx[y], which is matched - //with y, to the queue - add_to_tree(yx[y], x, cost); //add edges (x,y) and (y,yx[y]) to the tree - } - if (y < n) break; //augmenting path found! - } - if (y < n) break; //augmenting path found! - - update_labels(); //augmenting path not found, so improve labeling - wr = rd = 0; - for (y = 0; y < n; y++) - //in this cycle we add edges that were added to the equality graph as a - //result of improving the labeling, we add edge (slackx[y], y) to the tree if - //and only if !T[y] && slack[y] == 0, also with this edge we add another one - //(y, yx[y]) or augment the matching, if y was exposed - if (!T[y] && slack[y] == 0) - { - if (yx[y] == -1) //exposed vertex in Y found - augmenting path exists! - { - x = slackx[y]; - break; - } - else - { - T[y] = true; //else just add y to T, - if (!S[yx[y]]) - { - q[wr++] = yx[y]; //add vertex yx[y], which is matched with - //y, to the queue - add_to_tree(yx[y], slackx[y],cost); //and add edges (x,y) and (y, - //yx[y]) to the tree - } - } - } - if (y < n) break; //augmenting path found! - } - - if (y < n) //we found augmenting path! - { - max_match++; //increment matching - //in this cycle we inverse edges along augmenting path - for (int cx = x, cy = y, ty; cx != -2; cx = prev[cx], cy = ty) - { - ty = xy[cx]; - yx[cy] = cx; - xy[cx] = cy; - } - augment(cost); //recall function, go to step 1 of the algorithm - } -}//end of augment() function - -void update_labels() -{ - unsigned int x, y; - double delta = std::numeric_limits::max(); - for (y = 0; y < n; y++) //calculate delta using slack - if (!T[y]) - delta = std::min(delta, slack[y]); - for (x = 0; x < n; x++) //update X labels - if (S[x]) lx[x] -= delta; - for (y = 0; y < n; y++) //update Y labels - if (T[y]) ly[y] += delta; - for (y = 0; y < n; y++) //update slack array - if (!T[y]) - slack[y] -= delta; -} - -void add_to_tree(int x, int prevx, const double cost[N][N]) -//x - current vertex,prevx - vertex from X before x in the alternating path, -//so we add edges (prevx, xy[x]), (xy[x], x) -{ - S[x] = true; //add x to S - prev[x] = prevx; //we need this when augmenting - for (unsigned int y = 0; y < n; y++) //update slacks, because we add new vertex to S - if (lx[x] + ly[y] - cost[x][y] < slack[y]) - { - slack[y] = lx[x] + ly[y] - cost[x][y]; - slackx[y] = x; - } -} - -public: -/// Computes the best matching of two sets given its cost matrix. -/// See the matching() method to get the computed match result. -/// \param cost a matrix of two sets I,J where cost[i][j] is the weight of edge i->j -/// \param logicalSize the number of elements in both I and J -/// \returns the total cost of the best matching -inline double operator()(const double cost[N][N], size_t logicalSize) -{ - - n = logicalSize; - assert(n <= N); - double ret = 0; //weight of the optimal matching - max_match = 0; //number of vertices in current matching - memset(xy, -1, sizeof(xy)); - memset(yx, -1, sizeof(yx)); - init_labels(cost); //step 0 - augment(cost); //steps 1-3 - for (unsigned int x = 0; x < n; x++) //forming answer there - ret += cost[x][xy[x]]; - return ret; -} - -/// Gets the matching element in 2nd set of the ith element in the first set -/// \param i the index of the ith element in the first set (passed in operator()) -/// \returns an index j, denoting the matched jth element of the 2nd set -inline int matching(int i) const { - return xy[i]; -} - - -/// Gets the matching element in 1st set of the jth element in the 2nd set -/// \param j the index of the jth element in the 2nd set (passed in operator()) -/// \returns an index i, denoting the matched ith element of the 1st set -/// \note inverseMatching(matching(i)) == i -inline int inverseMatching(int j) const { - return yx[j]; -} - -}; - - -#endif diff --git a/src/libprojectM/MilkdropPreset/MilkdropPreset.cpp b/src/libprojectM/MilkdropPreset/MilkdropPreset.cpp index 7b86acd95..af56323b6 100755 --- a/src/libprojectM/MilkdropPreset/MilkdropPreset.cpp +++ b/src/libprojectM/MilkdropPreset/MilkdropPreset.cpp @@ -88,6 +88,8 @@ void MilkdropPreset::RenderFrame(const libprojectM::Audio::FrameAudioData& audio // First evaluate per-frame code PerFrameUpdate(); + glViewport(0, 0, renderContext.viewportSizeX, renderContext.viewportSizeY); + m_framebuffer.Bind(m_previousFrameBuffer); // Motion vector field. Drawn to the previous frame texture before warping it. // Only do it after drawing one frame after init or resize. diff --git a/src/libprojectM/PresetFactoryManager.cpp b/src/libprojectM/PresetFactoryManager.cpp index da16d9534..6db294abd 100644 --- a/src/libprojectM/PresetFactoryManager.cpp +++ b/src/libprojectM/PresetFactoryManager.cpp @@ -11,10 +11,9 @@ // #include "PresetFactoryManager.hpp" -#include "Common.hpp" - #include +#include #include #include #include @@ -135,4 +134,17 @@ std::vector PresetFactoryManager::extensionsHandled() const retval.push_back(element.first); } return retval; -} \ No newline at end of file +} + +//CPP17: std::filesystem::path::extension +auto PresetFactoryManager::ParseExtension(const std::string& filename) -> std::string +{ + const auto start = filename.find_last_of('.'); + + if (start == std::string::npos || start >= (filename.length() - 1)) { + return ""; + } + std::string ext = filename.substr(start + 1, filename.length()); + std::transform(ext.begin(), ext.end(), ext.begin(), tolower); + return ext; +} diff --git a/src/libprojectM/PresetFactoryManager.hpp b/src/libprojectM/PresetFactoryManager.hpp index c5d39ae50..49154d497 100644 --- a/src/libprojectM/PresetFactoryManager.hpp +++ b/src/libprojectM/PresetFactoryManager.hpp @@ -80,6 +80,8 @@ public: private: void registerFactory(const std::string& extension, PresetFactory* factory); + auto ParseExtension(const std::string& filename) -> std::string; + mutable std::map m_factoryMap; mutable std::vector m_factoryList; void ClearFactories(); diff --git a/src/libprojectM/ProjectM.cpp b/src/libprojectM/ProjectM.cpp index 88a1aca88..1454bc575 100644 --- a/src/libprojectM/ProjectM.cpp +++ b/src/libprojectM/ProjectM.cpp @@ -112,7 +112,6 @@ void ProjectM::ResetTextures() void ProjectM::DumpDebugImageOnNextFrame(const std::string& outputFile) { - m_renderer->frameDumpOutputFile = outputFile; } #if PROJECTM_USE_THREADS @@ -200,15 +199,6 @@ void ProjectM::RenderFrame() m_frameCount++; } -void ProjectM::Reset() -{ - this->m_frameCount = 0; - - m_presetFactoryManager->initialize(); - - ResetEngine(); -} - void ProjectM::Initialize() { /** Initialise start time */ @@ -225,11 +215,7 @@ void ProjectM::Initialize() m_beatDetect = std::make_unique(m_pcm); - m_renderer = std::make_unique(m_windowWidth, - m_windowHeight, - m_meshX, - m_meshY, - *m_beatDetect); + m_renderer = std::make_unique(m_windowWidth, m_windowHeight); m_textureManager = std::make_unique(m_textureSearchPaths); @@ -272,6 +258,7 @@ void ProjectM::ResetOpenGL(size_t width, size_t height) /** Stash the new dimensions */ m_windowWidth = width; m_windowHeight = height; + try { m_renderer->reset(width, height); @@ -408,7 +395,6 @@ auto ProjectM::TargetFramesPerSecond() const -> int32_t void ProjectM::SetTargetFramesPerSecond(int32_t fps) { m_targetFps = fps; - m_renderer->setFPS(fps); // ToDo: Renderer should ideally calculate this. } auto ProjectM::AspectCorrection() const -> bool @@ -490,13 +476,6 @@ void ProjectM::TouchDestroyAll() } } -void ProjectM::RecreateRenderer() -{ - m_renderer = std::make_unique(m_windowWidth, m_windowHeight, - m_meshX, m_meshY, - *m_beatDetect.get()); -} - auto ProjectM::GetRenderContext() -> RenderContext { RenderContext ctx{}; diff --git a/src/libprojectM/ProjectM.hpp b/src/libprojectM/ProjectM.hpp index 44fae9aff..2acf837eb 100644 --- a/src/libprojectM/ProjectM.hpp +++ b/src/libprojectM/ProjectM.hpp @@ -25,7 +25,6 @@ #include "projectM-4/projectM_export.h" #include "libprojectM/Audio/PCM.hpp" -#include "libprojectM/Common.hpp" #ifdef _WIN32 @@ -56,10 +55,6 @@ class BeatDetect; } } // namespace libprojectM -class Pcm; - -class Func; - class Renderer; class TextureManager; @@ -209,22 +204,12 @@ public: void DumpDebugImageOnNextFrame(const std::string& outputFile); private: - void EvaluateSecondPreset(); - - auto PipelineContext() -> class PipelineContext&; - - auto PipelineContext2() -> class PipelineContext&; - void Initialize(); - void Reset(); - void ResetEngine(); void StartPresetTransition(std::unique_ptr&& preset, bool hardCut); - void RecreateRenderer(); - void LoadIdlePreset(); auto GetRenderContext() -> RenderContext; @@ -240,8 +225,8 @@ private: size_t m_meshX{32}; //!< Per-point mesh horizontal resolution. size_t m_meshY{24}; //!< Per-point mesh vertical resolution. size_t m_targetFps{35}; //!< Target frames per second. - size_t m_windowWidth{0}; //!< EvaluateFrameData window width. If 0, nothing is rendered. - size_t m_windowHeight{0}; //!< EvaluateFrameData window height. If 0, nothing is rendered. + int m_windowWidth{0}; //!< EvaluateFrameData window width. If 0, nothing is rendered. + int m_windowHeight{0}; //!< EvaluateFrameData window height. If 0, nothing is rendered. double m_presetDuration{30.0}; //!< Preset duration in seconds. double m_softCutDuration{3.0}; //!< Soft cut transition time. double m_hardCutDuration{20.0}; //!< Time after which a hard cut can happen at the earliest. diff --git a/src/libprojectM/Renderer/CMakeLists.txt b/src/libprojectM/Renderer/CMakeLists.txt index ce46d1bbe..a0ddca4e6 100644 --- a/src/libprojectM/Renderer/CMakeLists.txt +++ b/src/libprojectM/Renderer/CMakeLists.txt @@ -3,6 +3,7 @@ add_library(Renderer OBJECT FileScanner.hpp Framebuffer.cpp Framebuffer.hpp + IdleTextures.hpp RenderContext.hpp RenderItem.cpp RenderItem.hpp diff --git a/src/libprojectM/Renderer/FileScanner.cpp b/src/libprojectM/Renderer/FileScanner.cpp index 997c281f1..63243f212 100644 --- a/src/libprojectM/Renderer/FileScanner.cpp +++ b/src/libprojectM/Renderer/FileScanner.cpp @@ -5,13 +5,18 @@ // #include "FileScanner.hpp" -#include "Common.hpp" -#ifndef _WIN32 +/** Per-platform path separators and includes */ +#ifdef _WIN32 +char constexpr pathSeparator{'\\'}; +#else +char constexpr pathSeparator{'/'}; #include #include #endif +#include + FileScanner::FileScanner() { } diff --git a/src/libprojectM/IdleTextures.hpp b/src/libprojectM/Renderer/IdleTextures.hpp similarity index 100% rename from src/libprojectM/IdleTextures.hpp rename to src/libprojectM/Renderer/IdleTextures.hpp diff --git a/src/libprojectM/Renderer/RenderContext.hpp b/src/libprojectM/Renderer/RenderContext.hpp index cae562a66..81b7741cd 100644 --- a/src/libprojectM/Renderer/RenderContext.hpp +++ b/src/libprojectM/Renderer/RenderContext.hpp @@ -18,7 +18,6 @@ public: int frame{0}; //!< Frames rendered so far. float fps{0.0f}; //!< Frames per second. float progress{0.0f}; //!< Preset progress. - int texsize{512}; //!< Size of the internal render texture. int viewportSizeX{0}; //!< Horizontal viewport size in pixels int viewportSizeY{0}; //!< Vertical viewport size in pixels float aspectX{1.0}; //!< X aspect ratio. diff --git a/src/libprojectM/Renderer/Renderer.cpp b/src/libprojectM/Renderer/Renderer.cpp index e2401bd7d..5094fa4d1 100644 --- a/src/libprojectM/Renderer/Renderer.cpp +++ b/src/libprojectM/Renderer/Renderer.cpp @@ -1,436 +1,45 @@ #include "Renderer.hpp" -#include "TextureManager.hpp" -#include "math.h" -#include "omptl/omptl_algorithm" - -#include "MilkdropPreset/Waveform.hpp" -#include "stb_image_write.h" -#include "wipemalloc.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include using namespace std::chrono; class Preset; -Renderer::Renderer(int viewportWidth, int viewportHeight, int meshX, int meshY, - libprojectM::Audio::BeatDetect& beatDetect) - : m_beatDetect(beatDetect) - , m_viewportWidth(viewportWidth) - , m_viewportHeight(viewportHeight) +Renderer::Renderer(int viewportWidth, int viewportHeight) { - // Interpolation VAO/VBO's - glGenBuffers(1, &m_vboInterpolation); - glGenVertexArrays(1, &m_vaoInterpolation); - - glBindVertexArray(m_vaoInterpolation); - glBindBuffer(GL_ARRAY_BUFFER, m_vboInterpolation); - - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, static_cast(nullptr)); // Positions - - glDisableVertexAttribArray(1); - - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, (void*)(sizeof(float) * 2)); // Textures - - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - // CompositeOutput VAO/VBO's - glGenBuffers(1, &m_vboCompositeOutput); - glGenVertexArrays(1, &m_vaoCompositeOutput); - - float composite_buffer_data[8][2] = - { - {-0.5, -0.5}, - {0, 1}, - {-0.5, 0.5}, - {0, 0}, - {0.5, 0.5}, - {1, 0}, - {0.5, -0.5}, - {1, 1} - }; - - - glBindVertexArray(m_vaoCompositeOutput); - glBindBuffer(GL_ARRAY_BUFFER, m_vboCompositeOutput); - - glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 8 * 2, composite_buffer_data, GL_STATIC_DRAW); - - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, static_cast(nullptr)); // Positions - - glDisableVertexAttribArray(1); - - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, (void*)(sizeof(float) * 2)); // Textures - - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - - // CompositeShaderOutput VAO/VBO's - glGenBuffers(1, &m_vboCompositeShaderOutput); - glGenVertexArrays(1, &m_vaoCompositeShaderOutput); - - glBindVertexArray(m_vaoCompositeShaderOutput); - glBindBuffer(GL_ARRAY_BUFFER, m_vboCompositeShaderOutput); - - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(composite_shader_vertex), static_cast(nullptr)); - // Positions - - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(composite_shader_vertex), (void*)(sizeof(float) * 2)); - // Colors - - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(composite_shader_vertex), (void*)(sizeof(float) * 6)); // UV - - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(composite_shader_vertex), (void*)(sizeof(float) * 8)); - // RAD ANG - - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - + reset(viewportWidth, viewportHeight); } -/* -void Renderer::RenderTouch(const Pipeline& pipeline, const PipelineContext& pipelineContext) -{ - Pipeline pipelineTouch; - Waveform wave; - for(std::size_t x = 0; x < m_waveformList.size(); x++){ - pipelineTouch.drawables.push_back(&wave); - wave = m_waveformList[x]; - - // Render waveform - for (std::vector::const_iterator pos = pipelineTouch.drawables.begin(); pos != pipelineTouch.drawables.end(); ++pos) - { - if (*pos != nullptr) - (*pos)->Draw(m_renderContext); - } - } -} -*/ - Renderer::~Renderer() { - free(m_perPointMeshBuffer); - - glDeleteBuffers(1, &m_vboInterpolation); - glDeleteVertexArrays(1, &m_vaoInterpolation); - - glDeleteBuffers(1, &m_vboCompositeOutput); - glDeleteVertexArrays(1, &m_vaoCompositeOutput); } void Renderer::reset(int viewportWidth, int viewportHeight) { - m_viewportWidth = viewportWidth; - m_viewportHeight = viewportHeight; - - glCullFace(GL_BACK); - -#ifndef GL_TRANSITION - glEnable(GL_LINE_SMOOTH); -#endif - - glClearColor(0, 0, 0, 0); - - glViewport(0, 0, viewportWidth, viewportHeight); - - glEnable(GL_BLEND); - m_mainTextureSizeX = viewportWidth; m_mainTextureSizeY = viewportHeight; // snap to 16x16 blocks m_mainTextureSizeX = ((m_mainTextureSizeX - 15) / 16) * 16; m_mainTextureSizeY = ((m_mainTextureSizeY - 15) / 16) * 16; - - m_fAspectX = (m_mainTextureSizeY > m_mainTextureSizeX) ? static_cast(m_mainTextureSizeX) / static_cast(m_mainTextureSizeY) : 1.0f; - m_fAspectY = (m_mainTextureSizeX > m_mainTextureSizeY) ? static_cast(m_mainTextureSizeY) / static_cast(m_mainTextureSizeX) : 1.0f; - - m_fInvAspectX = 1.0f / m_fAspectX; - m_fInvAspectY = 1.0f / m_fAspectY; - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glClear(GL_COLOR_BUFFER_BIT); } -bool Renderer::timeCheck(const milliseconds currentTime, const milliseconds lastTime, const double difference) { - milliseconds ms = std::chrono::duration_cast(currentTime - lastTime); - double diff = ms.count(); - if (diff >= difference) - { - return true; - } else { - return false; - } -} - -// If we touched on the renderer where there is an existing waveform. -bool Renderer::touchedWaveform(float x, float y, std::size_t i) -{ - /* - if (m_waveformList[i].x > (x-0.05f) && m_waveformList[i].x < (x+0.05f) // if x +- 0.5f - && ((m_waveformList[i].y > (y-0.05f) && m_waveformList[i].y < (y+0.05f)) // and y +- 0.5f - || m_waveformList[i].m_mode == Line || m_waveformList[i].m_mode == DoubleLine || m_waveformList[i].m_mode == DerivativeLine ) // OR it's a line (and y doesn't matter) - ) - { - return true; - } - */ - return false; -} // Render a waveform when a touch event is triggered. void Renderer::touch(float x, float y, int pressure, int type = 0) { -/* - for (std::size_t i = 0; i < m_waveformList.size(); i++) { - if (touchedWaveform(x, y, i)) - { - // if we touched an existing waveform with left click, drag it and don't continue with adding another. - touchDrag(x, y, pressure); - return; - } - } - - m_touchX = x; - m_touchY = y; - - // Randomly select colours on touch - m_touchR = ((double)rand() / (RAND_MAX)); - m_touchB = ((double)rand() / (RAND_MAX)); - m_touchG = ((double)rand() / (RAND_MAX)); - m_touchA = ((double)rand() / (RAND_MAX)); - - Waveform wave; - if (type == 0) { - // If we touched randomly, then assign type to a random number between 0 and 8 - wave.m_mode = static_cast((rand() % last)); - } - else { - wave.m_mode = static_cast(type); - } - - wave.additive = true; - wave.modOpacityEnd = 1.1; - wave.modOpacityStart = 0.0; - wave.maximizeColors = true; - wave.modulateAlphaByVolume = false; - - wave.r = m_touchR; - wave.g = m_touchG; - wave.b = m_touchB; - wave.a = m_touchA; - wave.x = m_touchX; - wave.y = m_touchY; - - // add new waveform to waveformTouchList - m_waveformList.push_back(wave); - */ } // Move a waveform when dragging X, Y, and Pressure can change. We also extend the counters so it will stay on screen for as long as you click and drag. void Renderer::touchDrag(float x, float y, int pressure) { - /* - // if we left clicked & held in the approximate position of a waveform, snap to it and adjust x / y to simulate dragging. - // For lines we don't worry about the x axis. - for (std::size_t i = 0; i < m_waveformList.size(); i++) { - if (touchedWaveform(x, y, i)) - { - m_waveformList[i].x = x; - m_waveformList[i].y = y; - } - } - */ } // Remove waveform at X Y void Renderer::touchDestroy(float x, float y) { - /* - // if we right clicked approximately on the position of the waveform, then remove it from the waveform list. - // For lines we don't worry about the x axis. - for (std::size_t i = 0; i < m_waveformList.size(); i++) { - if (touchedWaveform(x, y, i)) - { - m_waveformList.erase(m_waveformList.begin() + i); - } - } - */ } // Remove all waveforms void Renderer::touchDestroyAll() { - //m_waveformList.clear(); } - -/* -void Renderer::CompositeOutput(const Pipeline& pipeline, const PipelineContext& pipelineContext) -{ - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, m_textureManager->getMainTexture()->texID); - - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - - m_renderContext.mat_ortho = glm::ortho(-0.5f, 0.5f, -0.5f, 0.5f, -40.0f, 40.0f); - - m_shaderEngine.enableCompositeShader(m_currentPipeline->compositeShader, pipeline, pipelineContext); - - glUniformMatrix4fv(m_shaderEngine.uniform_v2f_c4f_t2f_vertex_transformation, 1, GL_FALSE, - value_ptr(m_renderContext.mat_ortho)); - glUniform1i(m_shaderEngine.uniform_v2f_c4f_t2f_frag_texture_sampler, 0); - - //Overwrite anything on the screen - glBlendFunc(GL_ONE, GL_ZERO); - glVertexAttrib4f(1, 1.0, 1.0, 1.0, 1.0); - - glBindVertexArray(m_vaoCompositeOutput); - - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - glBindVertexArray(0); - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - for (auto drawable : pipeline.compositeDrawables) - drawable->Draw(m_renderContext); - - glBindTexture(GL_TEXTURE_2D, 0); -} -*/ - -/** - * Calculates the nearest power of two to the given number using the - * appropriate rule - */ -int Renderer::nearestPower2(int value) -{ - int x = value; - int power = 0; - - if (x == 0) - { - return 0; - } - - while ((x & 0x01) != 1) - { - x >>= 1; - } - - if (x == 1) - { - return value; - } - x = value; - while (x != 0) - { - x >>= 1; - power++; - } - if (((1 << power) - value) <= (value - (1 << (power - 1)))) - { - return 1 << power; - } - return 1 << (power - 1); - return 0; -} - - -/* -void Renderer::CompositeShaderOutput(const Pipeline& pipeline, const PipelineContext& pipelineContext) -{ - // hue shader - float shade[4][3] = { - {1.0f, 1.0f, 1.0f}, - {1.0f, 1.0f, 1.0f}, - {1.0f, 1.0f, 1.0f}, - {1.0f, 1.0f, 1.0f} - }; // for each vertex, then each comp. - - // pick 4 colors for the 4 corners - for (int i = 0; i < 4; i++) - { - shade[i][0] = 0.6f + 0.3f * sinf(pipelineContext.time * 30.0f * 0.0143f + 3 + i * 21); - shade[i][1] = 0.6f + 0.3f * sinf(pipelineContext.time * 30.0f * 0.0107f + 1 + i * 13); - shade[i][2] = 0.6f + 0.3f * sinf(pipelineContext.time * 30.0f * 0.0129f + 6 + i * 9); - float max = ((shade[i][0] > shade[i][1]) ? shade[i][0] : shade[i][1]); - if (shade[i][2] > max) max = shade[i][2]; - for (int k = 0; k < 3; k++) - { - shade[i][k] /= max; - shade[i][k] = 0.5f + 0.5f * shade[i][k]; - } - } - - // interpolate the 4 colors & apply to all the verts - for (int j = 0; j < FCGSY; j++) - { - for (int i = 0; i < FCGSX; i++) - { - composite_shader_vertex* pComp = &m_compositeVertices[i + j * FCGSX]; - float x = pComp->x * 0.5f + 0.5f; - float y = pComp->y * 0.5f + 0.5f; - - float col[3] = {1, 1, 1}; - for (int c = 0; c < 3; c++) - col[c] = shade[0][c] * (x) * (y) + - shade[1][c] * (1 - x) * (y) + - shade[2][c] * (x) * (1 - y) + - shade[3][c] * (1 - x) * (1 - y); - - pComp->Diffuse[0] = col[0]; - pComp->Diffuse[1] = col[1]; - pComp->Diffuse[2] = col[2]; - pComp->Diffuse[3] = 1.0; - } - } - - - const int primCount = (FCGSX - 2) * (FCGSY - 2) * 6; - composite_shader_vertex tempv[primCount]; - memset(tempv, 0, sizeof(composite_shader_vertex) * primCount); - int src_idx = 0; - for (int i = 0; i < primCount; i++) - { - tempv[i] = m_compositeVertices[m_compositeIndices[src_idx++]]; - } - - glBindBuffer(GL_ARRAY_BUFFER, m_vboCompositeShaderOutput); - - glBufferData(GL_ARRAY_BUFFER, sizeof(composite_shader_vertex) * primCount, nullptr, GL_DYNAMIC_DRAW); - glBufferData(GL_ARRAY_BUFFER, sizeof(composite_shader_vertex) * primCount, tempv, GL_DYNAMIC_DRAW); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - - glBlendFunc(GL_ONE, GL_ZERO); - - glBindVertexArray(m_vaoCompositeShaderOutput); - - // Now do the final composite blit, fullscreen; - glDrawArrays(GL_TRIANGLES, 0, primCount); - - glBindVertexArray(0); - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -} -*/ \ No newline at end of file diff --git a/src/libprojectM/Renderer/Renderer.hpp b/src/libprojectM/Renderer/Renderer.hpp index 86bb44cec..1bcffd517 100644 --- a/src/libprojectM/Renderer/Renderer.hpp +++ b/src/libprojectM/Renderer/Renderer.hpp @@ -63,83 +63,18 @@ class Renderer public: Renderer() = delete; - Renderer(int viewportWidth, int viewportHeight, - int meshX, int meshY, - libprojectM::Audio::BeatDetect& beatDetect); + Renderer(int viewportWidth, int viewportHeight); ~Renderer(); void reset(int viewportWidth, int viewportHeight); - bool timeCheck(const milliseconds currentTime, const milliseconds lastTime, const double difference); - - void setFPS(const int& theValue) - { - m_fps = std::to_string(theValue); - } - - std::string fps() const - { - return m_fps; - } - - milliseconds nowMilliseconds() - { - return duration_cast(system_clock::now().time_since_epoch()); - } - void touch(float x, float y, int pressure, int type); void touchDrag(float x, float y, int pressure); void touchDestroy(float x, float y); void touchDestroyAll(); - bool touchedWaveform(float x, float y, std::size_t i); - - std::string frameDumpOutputFile; - - milliseconds lastTimeFPS{nowMilliseconds()}; - milliseconds currentTimeFPS{nowMilliseconds()}; - - int totalframes{1}; - float realfps{0.0}; - - std::string title; private: - int nearestPower2(int value); - - libprojectM::Audio::BeatDetect& m_beatDetect; - - std::string m_fps; - - float* m_perPointMeshBuffer{nullptr}; - - int m_viewportWidth{0}; - int m_viewportHeight{0}; - - GLuint m_vboInterpolation{0}; - GLuint m_vaoInterpolation{0}; - - GLuint m_vboCompositeOutput{0}; - GLuint m_vaoCompositeOutput{0}; - - GLuint m_vboCompositeShaderOutput{0}; - GLuint m_vaoCompositeShaderOutput{0}; - - composite_shader_vertex m_compositeVertices[FCGSX * FCGSY]; - int m_compositeIndices[(FCGSX - 2) * (FCGSY - 2) * 6]; - - float m_touchX{0.0}; ///!< X position for touch waveform to start displaying(scale of 0 - 1 and not the exact coordinates) - float m_touchY{0.0}; ///!< y position for touch waveform to start displaying(scale of 0 - 1 and not the exact coordinates) - double m_touchR{0.0}; ///!< Red - double m_touchG{0.0}; ///!< Green - double m_touchB{0.0}; ///!< Blue - double m_touchA{0.0}; ///!< Alpha - int m_mainTextureSizeX{0}; int m_mainTextureSizeY{0}; - - float m_fAspectX{1.0}; - float m_fAspectY{1.0}; - float m_fInvAspectX{1.0}; - float m_fInvAspectY{1.0}; }; diff --git a/src/libprojectM/Renderer/TextureManager.cpp b/src/libprojectM/Renderer/TextureManager.cpp index 3100b4ad9..f126febaf 100644 --- a/src/libprojectM/Renderer/TextureManager.cpp +++ b/src/libprojectM/Renderer/TextureManager.cpp @@ -1,14 +1,18 @@ #include "TextureManager.hpp" + #include "IdleTextures.hpp" + +#include "MilkdropPreset/MilkdropNoise.hpp" + #include "SOIL2/SOIL2.h" + #include "Texture.hpp" #include "projectM-opengl.h" + #include #include #include -#include "MilkdropPreset/MilkdropNoise.hpp" - // Missing in macOS SDK. Query will most certainly fail, but then use the default format. #ifndef GL_TEXTURE_IMAGE_FORMAT #define GL_TEXTURE_IMAGE_FORMAT 0x828F diff --git a/src/libprojectM/TestRunner.cpp b/src/libprojectM/TestRunner.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/libprojectM/carbontoprojectM.h b/src/libprojectM/carbontoprojectM.h deleted file mode 100755 index cd0750084..000000000 --- a/src/libprojectM/carbontoprojectM.h +++ /dev/null @@ -1,85 +0,0 @@ -r/** - * projectM -- Milkdrop-esque visualisation SDK - * Copyright (C)2003-2007 projectM Team - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * See 'LICENSE.txt' included within this release - * - */ -/** - * $Id: carbontoprojectM.hpp,v 1.2 2004/11/12 15:12:58 cvs Exp $ - * - * Translates CARBON -> projectM variables - * - * $Log$ - */ - -#ifndef _CARBONTOPROJECTM_H -#define _CARBONTOPROJECTM_H - -projectMKeycode carbon2pmKeycode( NSEvent *event ) { - projectMKeycode char_code = (projectMKeycode)(event->message & charCodeMask); - switch ( char_code ) { - case kFunctionKeyCharCode: { - switch ( ( event->message << 16 ) >> 24 ) { - case 111: { - return PROJECTM_K_F12; - } - case 103: { - return PROJECTM_K_F11; - } - case 109: { - return PROJECTM_K_F10; - } - case 101: { - return PROJECTM_K_F9; - } - case 100: { - return PROJECTM_K_F8; - } - case 98: { - return PROJECTM_K_F7; - } - case 97: { - return PROJECTM_K_F6; - } - case 96: { - return PROJECTM_K_F5; - } - case 118: { - return PROJECTM_K_F4; - } - case 99: { - return PROJECTM_K_F3; - } - case 120: { - return PROJECTM_K_F2; - } - case 122: { - return PROJECTM_K_F1; - } - } - } - default: { - return char_code; - } - } - } - -projectMModifier carbon2pmModifier( NSEvent *event ) { - return (projectMModifier)PROJECTM_K_LSHIFT; - } - -#endif /** _CARBONTOPROJECTM_H */ diff --git a/src/libprojectM/cocoatoprojectM.h b/src/libprojectM/cocoatoprojectM.h deleted file mode 100644 index eca5460fe..000000000 --- a/src/libprojectM/cocoatoprojectM.h +++ /dev/null @@ -1,63 +0,0 @@ -/** - * projectM -- Milkdrop-esque visualisation SDK - * Copyright (C)2003-2007 projectM Team - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * See 'LICENSE.txt' included within this release - * - */ -/** - * - * Translates cocoa -> projectM variables - * - * $Log$ - */ - -#ifndef _CARBONTOPROJECTM_H -#define _CARBONTOPROJECTM_H - -projectMKeycode cocoa2pmKeycode( NSEvent *event ) { - projectMKeycode char_code = (projectMKeycode)[event keyCode]; - switch ( char_code ) { - case kVK_F1: - case kVK_ANSI_H: - return PROJECTM_K_F1; - case kVK_F2: - return PROJECTM_K_F2; - case kVK_F3: - return PROJECTM_K_F3; - case kVK_F4: - return PROJECTM_K_F4; - default: - // try and get ascii code - NSString *chars = [event charactersIgnoringModifiers]; - if ([chars length]) { - return (projectMKeycode)[chars characterAtIndex:0]; - } - return char_code; - } -} - -projectMModifier cocoa2pmModifier( NSEvent *event ) { - NSUInteger mod = [event modifierFlags]; - if (mod & NSShiftKeyMask) - return (projectMModifier)PROJECTM_K_LSHIFT; - if (mod & NSControlKeyMask) - return (projectMModifier)PROJECTM_K_LCTRL; - - return (projectMModifier)0; -} - -#endif /** _CARBONTOPROJECTM_H */ diff --git a/src/libprojectM/fatal.h b/src/libprojectM/fatal.h deleted file mode 100755 index 57a62850e..000000000 --- a/src/libprojectM/fatal.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - * projectM -- Milkdrop-esque visualisation SDK - * Copyright (C)2003-2007 projectM Team - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * See 'LICENSE.txt' included within this release - * - */ -/** - * $Id: fatal.h,v 1.1.1.1 2005/12/23 18:05:05 psperl Exp $ - * - * Error codes - * - * $Log$ - */ - -#ifndef _FATAL_H -#define _FATAL_H - -/* Fatal Error Definitions */ - -#define PROJECTM_OUTOFMEM_ERROR -7; /* out of memory */ -#define PROJECTM_ERROR -1 /* non specific error */ -#define PROJECTM_SUCCESS 1 -#define PROJECTM_FAILURE -1 -#define PROJECTM_PARSE_ERROR -11 -#define PROJECTM_DIV_BY_ZERO -3 -#define PROJECTM_OK 2 - -#endif /** !_FATAL_H */ - diff --git a/src/libprojectM/glError.h b/src/libprojectM/glError.h deleted file mode 100644 index a6d0940ea..000000000 --- a/src/libprojectM/glError.h +++ /dev/null @@ -1,31 +0,0 @@ -// -// File: glError.h -// Author: fatray -// -// Created on 02 December 2007, 16:08 -// - -#ifndef _GLERROR_H -#define _GLERROR_H - -// no need to include GL in here, -// if someone wants GL errors they probably already included it. - - -/* - * if we are debugging, print all glErrors to stderr. - * Remeber that glErrors are buffered, this just prints any in the buffer. - */ -#ifdef NDEBUG -#define glError() -#else -#define glError() { \ - GLenum err; \ - while ((err = glGetError()) != GL_NO_ERROR) \ - fprintf(stderr, "glError: %s at %s:%u\n", \ - (char *)gluErrorString(err), __FILE__, __LINE__); \ -} -#endif /* glError */ - -#endif /* _GLERROR_H */ - diff --git a/src/libprojectM/gltext.h b/src/libprojectM/gltext.h deleted file mode 100644 index 5450fb114..000000000 --- a/src/libprojectM/gltext.h +++ /dev/null @@ -1,1356 +0,0 @@ - -// Repository: https://github.com/MrVallentin/glText -// License: https://github.com/MrVallentin/glText/blob/master/LICENSE.md -// -// Date Created: September 24, 2013 -// Last Modified: November 03, 2019 - -// In one C or C++ file, define GLT_IMPLEMENTATION prior to inclusion to create the implementation. -// #define GLT_IMPLEMENTATION -// #include "gltext.h" - -// Copyright (c) 2018-2019 Robert Pancoast -// Support OpenGLES -// -// Copyright (c) 2013-2018 Christian Vallentin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. - -// Refrain from using any exposed macros, functions -// or structs prefixed with an underscore. As these -// are only intended for internal purposes. Which -// additionally means they can be removed, renamed -// or changed between minor updates without notice. - -#ifndef GL_TEXT_H -#define GL_TEXT_H - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(__gl_h_) && !defined(__glcorearb_h_) && !defined(USE_GLES) -# error OpenGL header must be included prior to including glText header -#endif - -#include /* malloc(), calloc(), free() */ -#include /* memset(), memcpy(), strlen() */ -#include /* uint8_t, uint16_t, uint32_t, uint64_t */ - -#if (defined(_DEBUG) || defined(DEBUG)) && !defined(GLT_DEBUG) -# define GLT_DEBUG 1 -#endif - -#ifdef GLT_DEBUG -# include /* assert() */ -# define _GLT_ASSERT(expression) assert(expression) -#else -# define _GLT_ASSERT(expression) -#endif - -#ifdef GLT_DEBUG_PRINT -# include /* printf */ -#endif - -#define _GLT_STRINGIFY(str) #str -#define _GLT_STRINGIFY_TOKEN(str) _GLT_STRINGIFY(str) - -#define GLT_STRINGIFY_VERSION(major, minor, patch) _GLT_STRINGIFY(major) "." _GLT_STRINGIFY(minor) "." _GLT_STRINGIFY(patch) - -#define GLT_NAME "glText" - -#define GLT_VERSION_MAJOR 1 -#define GLT_VERSION_MINOR 1 -#define GLT_VERSION_PATCH 6 - -#define GLT_VERSION GLT_STRINGIFY_VERSION(GLT_VERSION_MAJOR, GLT_VERSION_MINOR, GLT_VERSION_PATCH) -#define GLT_NAME_VERSION GLT_NAME " " GLT_VERSION - -#define GLT_NULL 0 -#define GLT_NULL_HANDLE 0 - -#ifdef GLT_IMPORTS -# define GLT_API extern -#else -# ifndef GLT_STATIC -# define GLT_STATIC -# endif -# define GLT_API static -#endif - -#define GLT_LEFT 0 -#define GLT_TOP 0 - -#define GLT_CENTER 1 - -#define GLT_RIGHT 2 -#define GLT_BOTTOM 2 - -static GLboolean gltInitialized = GL_FALSE; - -typedef struct GLTtext GLTtext; - -GLT_API GLboolean gltInit(void); -GLT_API void gltTerminate(void); - -GLT_API GLTtext* gltCreateText(void); -GLT_API void gltDeleteText(GLTtext *text); -#define gltDestroyText gltDeleteText - -GLT_API GLboolean gltSetText(GLTtext *text, const char *string); -GLT_API const char* gltGetText(GLTtext *text); - -GLT_API void gltViewport(GLsizei width, GLsizei height); - -GLT_API void gltBeginDraw(); -GLT_API void gltEndDraw(); - -GLT_API void gltDrawText(GLTtext *text, const GLfloat mvp[16]); - -GLT_API void gltDrawText2D(GLTtext *text, GLfloat x, GLfloat y, GLfloat scale); -GLT_API void gltDrawText2DAligned(GLTtext *text, GLfloat x, GLfloat y, GLfloat scale, int horizontalAlignment, int verticalAlignment); - -GLT_API void gltDrawText3D(GLTtext *text, GLfloat x, GLfloat y, GLfloat z, GLfloat scale, GLfloat view[16], GLfloat projection[16]); - -GLT_API void gltColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a); -GLT_API void gltGetColor(GLfloat *r, GLfloat *g, GLfloat *b, GLfloat *a); - -GLT_API GLfloat gltGetLineHeight(GLfloat scale); - -GLT_API GLfloat gltGetTextWidth(const GLTtext *text, GLfloat scale); -GLT_API GLfloat gltGetTextHeight(const GLTtext *text, GLfloat scale); - -GLT_API GLboolean gltIsCharacterSupported(const char c); -GLT_API GLint gltCountSupportedCharacters(const char *str); - -GLT_API GLboolean gltIsCharacterDrawable(const char c); -GLT_API GLint gltCountDrawableCharacters(const char *str); - -GLT_API GLint gltCountNewLines(const char *str); - -// After this point everything you'll see is the -// implementation and all the internal stuff. -// Use it at your own discretion, but be warned -// that everything can have changed in the next -// commit, so be careful relying on any of it. - -#ifdef GLT_IMPLEMENTATION - -#define _GLT_TEXT2D_POSITION_LOCATION 0 -#define _GLT_TEXT2D_TEXCOORD_LOCATION 1 - -#define _GLT_TEXT2D_POSITION_SIZE 2 -#define _GLT_TEXT2D_TEXCOORD_SIZE 2 -#define _GLT_TEXT2D_VERTEX_SIZE (_GLT_TEXT2D_POSITION_SIZE + _GLT_TEXT2D_TEXCOORD_SIZE) - -#define _GLT_TEXT2D_POSITION_OFFSET 0 -#define _GLT_TEXT2D_TEXCOORD_OFFSET _GLT_TEXT2D_POSITION_SIZE - -#define _GLT_MAT4_INDEX(row, column) ((row) + (column) * 4) - -static const char *_gltFontGlyphCharacters = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?-+/():;%&`*#=[]\""; -#define _gltFontGlyphCount 83 - -#define _gltFontGlyphMinChar ' ' -#define _gltFontGlyphMaxChar 'z' - -static const int _gltFontGlyphHeight = 17; // Line height - -typedef struct _GLTglyph { - char c; - - GLint x, y; - GLint w, h; - - GLfloat u1, v1; - GLfloat u2, v2; - - GLboolean drawable; -} _GLTglyph; - -typedef struct _GLTglyphdata { - uint32_t x, y; - uint32_t w, h; - - uint32_t marginLeft, marginTop; - uint32_t marginRight, marginBottom; - - uint16_t dataWidth, dataHeight; -} _GLTglyphdata; - -static _GLTglyph _gltFontGlyphs[_gltFontGlyphCount]; - -#define _gltFontGlyphLength (_gltFontGlyphMaxChar - _gltFontGlyphMinChar + 1) -static _GLTglyph _gltFontGlyphs2[_gltFontGlyphLength]; - -static GLuint _gltText2DShader = GLT_NULL_HANDLE; -static GLuint _gltText2DFontTexture = GLT_NULL_HANDLE; - -static GLint _gltText2DShaderMVPUniformLocation = -1; -static GLint _gltText2DShaderColorUniformLocation = -1; - -static GLfloat _gltText2DProjectionMatrix[16]; - -struct GLTtext { - char *_text; - GLsizei _textLength; - - GLboolean _dirty; - - GLsizei vertexCount; - GLfloat *_vertices; - - GLuint _vao; - GLuint _vbo; -}; - -GLT_API void _gltGetViewportSize(GLint *width, GLint *height); - -GLT_API void _gltMat4Mult(const GLfloat lhs[16], const GLfloat rhs[16], GLfloat result[16]); - -GLT_API void _gltUpdateBuffers(GLTtext *text); - -GLT_API GLboolean _gltCreateText2DShader(void); -GLT_API GLboolean _gltCreateText2DFontTexture(void); - -GLT_API GLTtext* gltCreateText(void) -{ - GLTtext *text = (GLTtext*)calloc(1, sizeof(GLTtext)); - - _GLT_ASSERT(text); - - if (!text) - return GLT_NULL; - - glGenVertexArrays(1, &text->_vao); - glGenBuffers(1, &text->_vbo); - - _GLT_ASSERT(text->_vao); - _GLT_ASSERT(text->_vbo); - - if (!text->_vao || !text->_vbo) - { - gltDeleteText(text); - return GLT_NULL; - } - - glBindVertexArray(text->_vao); - - glBindBuffer(GL_ARRAY_BUFFER, text->_vbo); - - glEnableVertexAttribArray(_GLT_TEXT2D_POSITION_LOCATION); - glVertexAttribPointer(_GLT_TEXT2D_POSITION_LOCATION, _GLT_TEXT2D_POSITION_SIZE, GL_FLOAT, GL_FALSE, (_GLT_TEXT2D_VERTEX_SIZE * sizeof(GLfloat)), (const void*)(_GLT_TEXT2D_POSITION_OFFSET * sizeof(GLfloat))); - - glEnableVertexAttribArray(_GLT_TEXT2D_TEXCOORD_LOCATION); - glVertexAttribPointer(_GLT_TEXT2D_TEXCOORD_LOCATION, _GLT_TEXT2D_TEXCOORD_SIZE, GL_FLOAT, GL_FALSE, (_GLT_TEXT2D_VERTEX_SIZE * sizeof(GLfloat)), (const void*)(_GLT_TEXT2D_TEXCOORD_OFFSET * sizeof(GLfloat))); - - glBindVertexArray(0); - - return text; -} - -GLT_API void gltDeleteText(GLTtext *text) -{ - if (!text) - return; - - if (text->_vao) - { - glDeleteVertexArrays(1, &text->_vao); - text->_vao = GLT_NULL_HANDLE; - } - - if (text->_vbo) - { - glDeleteBuffers(1, &text->_vbo); - text->_vbo = GLT_NULL_HANDLE; - } - - if (text->_text) - free(text->_text); - - if (text->_vertices) - free(text->_vertices); - - free(text); -} - -GLT_API GLboolean gltSetText(GLTtext *text, const char *string) -{ - if (!text) - return GL_FALSE; - - int strLength = 0; - - if (string) - strLength = strlen(string); - - if (strLength) - { - if (text->_text) - { - if (strcmp(string, text->_text) == 0) - return GL_TRUE; - - free(text->_text); - text->_text = GLT_NULL; - } - - text->_text = (char*)malloc((strLength + 1) * sizeof(char)); - - if (text->_text) - { - memcpy(text->_text, string, (strLength + 1) * sizeof(char)); - - text->_textLength = strLength; - text->_dirty = GL_TRUE; - - return GL_TRUE; - } - } - else - { - if (text->_text) - { - free(text->_text); - text->_text = GLT_NULL; - } - else - { - return GL_TRUE; - } - - text->_textLength = 0; - text->_dirty = GL_TRUE; - - return GL_TRUE; - } - - return GL_FALSE; -} - -GLT_API const char* gltGetText(GLTtext *text) -{ - if (text && text->_text) - return text->_text; - - return "\0"; -} - -GLT_API void gltViewport(GLsizei width, GLsizei height) -{ - _GLT_ASSERT(width > 0); - _GLT_ASSERT(height > 0); - - const GLfloat left = 0.0f; - const GLfloat right = (GLfloat)width; - const GLfloat bottom = (GLfloat)height; - const GLfloat top = 0.0f; - const GLfloat zNear = -1.0f; - const GLfloat zFar = 1.0f; - - const GLfloat projection[16] = { - (2.0f / (right - left)), 0.0f, 0.0f, 0.0f, - 0.0f, (2.0f / (top - bottom)), 0.0f, 0.0f, - 0.0f, 0.0f, (-2.0f / (zFar - zNear)), 0.0f, - - -((right + left) / (right - left)), - -((top + bottom) / (top - bottom)), - -((zFar + zNear) / (zFar - zNear)), - 1.0f, - }; - - memcpy(_gltText2DProjectionMatrix, projection, 16 * sizeof(GLfloat)); -} - -GLT_API void gltBeginDraw() -{ - glUseProgram(_gltText2DShader); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, _gltText2DFontTexture); -} - -GLT_API void gltEndDraw() -{ - -} - -#define _gltDrawText() \ - glUniformMatrix4fv(_gltText2DShaderMVPUniformLocation, 1, GL_FALSE, mvp); \ - \ - glBindVertexArray(text->_vao); \ - glDrawArrays(GL_TRIANGLES, 0, text->vertexCount); - -GLT_API void gltDrawText(GLTtext *text, const GLfloat mvp[16]) -{ - if (!text) - return; - - if (text->_dirty) - _gltUpdateBuffers(text); - - if (!text->vertexCount) - return; - - _gltDrawText(); -} - -GLT_API void gltDrawText2D(GLTtext *text, GLfloat x, GLfloat y, GLfloat scale) -{ - if (!text) - return; - - if (text->_dirty) - _gltUpdateBuffers(text); - - if (!text->vertexCount) - return; - -#ifndef GLT_MANUAL_VIEWPORT - GLint viewportWidth, viewportHeight; - _gltGetViewportSize(&viewportWidth, &viewportHeight); - gltViewport(viewportWidth, viewportHeight); -#endif - - const GLfloat model[16] = { - scale, 0.0f, 0.0f, 0.0f, - 0.0f, scale, 0.0f, 0.0f, - 0.0f, 0.0f, scale, 0.0f, - x, y, 0.0f, 1.0f, - }; - - GLfloat mvp[16]; - _gltMat4Mult(_gltText2DProjectionMatrix, model, mvp); - - _gltDrawText(); -} - -GLT_API void gltDrawText2DAligned(GLTtext *text, GLfloat x, GLfloat y, GLfloat scale, int horizontalAlignment, int verticalAlignment) -{ - if (!text) - return; - - if (text->_dirty) - _gltUpdateBuffers(text); - - if (!text->vertexCount) - return; - - if (horizontalAlignment == GLT_CENTER) - x -= gltGetTextWidth(text, scale) * 0.5f; - else if (horizontalAlignment == GLT_RIGHT) - x -= gltGetTextWidth(text, scale); - - if (verticalAlignment == GLT_CENTER) - y -= gltGetTextHeight(text, scale) * 0.5f; - else if (verticalAlignment == GLT_RIGHT) - y -= gltGetTextHeight(text, scale); - - gltDrawText2D(text, x, y, scale); -} - -GLT_API void gltDrawText3D(GLTtext *text, GLfloat x, GLfloat y, GLfloat z, GLfloat scale, GLfloat view[16], GLfloat projection[16]) -{ - if (!text) - return; - - if (text->_dirty) - _gltUpdateBuffers(text); - - if (!text->vertexCount) - return; - - const GLfloat model[16] = { - scale, 0.0f, 0.0f, 0.0f, - 0.0f, -scale, 0.0f, 0.0f, - 0.0f, 0.0f, scale, 0.0f, - x, y + (GLfloat)_gltFontGlyphHeight * scale, z, 1.0f, - }; - - GLfloat mvp[16]; - GLfloat vp[16]; - - _gltMat4Mult(projection, view, vp); - _gltMat4Mult(vp, model, mvp); - - _gltDrawText(); -} - -GLT_API void gltColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) -{ - glUniform4f(_gltText2DShaderColorUniformLocation, r, g, b, a); -} - -GLT_API void gltGetColor(GLfloat *r, GLfloat *g, GLfloat *b, GLfloat *a) -{ - GLfloat color[4]; - glGetUniformfv(_gltText2DShader, _gltText2DShaderColorUniformLocation, color); - - if (r) (*r) = color[0]; - if (g) (*g) = color[1]; - if (b) (*b) = color[2]; - if (a) (*a) = color[3]; -} - -GLT_API GLfloat gltGetLineHeight(GLfloat scale) -{ - return (GLfloat)_gltFontGlyphHeight * scale; -} - -GLT_API GLfloat gltGetTextWidth(const GLTtext *text, GLfloat scale) -{ - if (!text || !text->_text) - return 0.0f; - - GLfloat maxWidth = 0.0f; - GLfloat width = 0.0f; - - _GLTglyph glyph; - - char c; - int i; - for (i = 0; i < text->_textLength; i++) - { - c = text->_text[i]; - - if ((c == '\n') || (c == '\r')) - { - if (width > maxWidth) - maxWidth = width; - - width = 0.0f; - - continue; - } - - if (!gltIsCharacterSupported(c)) - { -#ifdef GLT_UNKNOWN_CHARACTER - c = GLT_UNKNOWN_CHARACTER; - if (!gltIsCharacterSupported(c)) - continue; -#else - continue; -#endif - } - - glyph = _gltFontGlyphs2[c - _gltFontGlyphMinChar]; - - width += (GLfloat)glyph.w; - } - - if (width > maxWidth) - maxWidth = width; - - return maxWidth * scale; -} - -GLT_API GLfloat gltGetTextHeight(const GLTtext *text, GLfloat scale) -{ - if (!text || !text->_text) - return 0.0f; - - return (GLfloat)(gltCountNewLines(text->_text) + 1) * gltGetLineHeight(scale); -} - -GLT_API GLboolean gltIsCharacterSupported(const char c) -{ - if (c == '\t') return GL_TRUE; - if (c == '\n') return GL_TRUE; - if (c == '\r') return GL_TRUE; - - int i; - for (i = 0; i < _gltFontGlyphCount; i++) - { - if (_gltFontGlyphCharacters[i] == c) - return GL_TRUE; - } - - return GL_FALSE; -} - -GLT_API GLint gltCountSupportedCharacters(const char *str) -{ - if (!str) - return 0; - - GLint count = 0; - - while ((*str) != '\0') - { - if (gltIsCharacterSupported(*str)) - count++; - - str++; - } - - return count; -} - -GLT_API GLboolean gltIsCharacterDrawable(const char c) -{ - if (c < _gltFontGlyphMinChar) return GL_FALSE; - if (c > _gltFontGlyphMaxChar) return GL_FALSE; - - if (_gltFontGlyphs2[c - _gltFontGlyphMinChar].drawable) - return GL_TRUE; - - return GL_FALSE; -} - -GLT_API GLint gltCountDrawableCharacters(const char *str) -{ - if (!str) - return 0; - - GLint count = 0; - - while ((*str) != '\0') - { - if (gltIsCharacterDrawable(*str)) - count++; - - str++; - } - - return count; -} - -GLT_API GLint gltCountNewLines(const char *str) -{ - GLint count = 0; - - while ((str = strchr(str, '\n')) != NULL) - { - count++; - str++; - } - - return count; -} - -GLT_API void _gltGetViewportSize(GLint *width, GLint *height) -{ - GLint dimensions[4]; - glGetIntegerv(GL_VIEWPORT, dimensions); - - if (width) (*width) = dimensions[2]; - if (height) (*height) = dimensions[3]; -} - -GLT_API void _gltMat4Mult(const GLfloat lhs[16], const GLfloat rhs[16], GLfloat result[16]) -{ - int c, r, i; - - for (c = 0; c < 4; c++) - { - for (r = 0; r < 4; r++) - { - result[_GLT_MAT4_INDEX(r, c)] = 0.0f; - - for (i = 0; i < 4; i++) - result[_GLT_MAT4_INDEX(r, c)] += lhs[_GLT_MAT4_INDEX(r, i)] * rhs[_GLT_MAT4_INDEX(i, c)]; - } - } -} - -GLT_API void _gltUpdateBuffers(GLTtext *text) -{ - if (!text || !text->_dirty) - return; - - if (text->_vertices) - { - text->vertexCount = 0; - - free(text->_vertices); - text->_vertices = GLT_NULL; - } - - if (!text->_text || !text->_textLength) - { - text->_dirty = GL_FALSE; - return; - } - - const GLsizei countDrawable = gltCountDrawableCharacters(text->_text); - - if (!countDrawable) - { - text->_dirty = GL_FALSE; - return; - } - - const GLsizei vertexCount = countDrawable * 2 * 3; // 3 vertices in a triangle, 2 triangles in a quad - - const GLsizei vertexSize = _GLT_TEXT2D_VERTEX_SIZE; - GLfloat *vertices = (GLfloat*)malloc(vertexCount * vertexSize * sizeof(GLfloat)); - - if (!vertices) - return; - - GLsizei vertexElementIndex = 0; - - GLfloat glyphX = 0.0f; - GLfloat glyphY = 0.0f; - - GLfloat glyphWidth; - const GLfloat glyphHeight = (GLfloat)_gltFontGlyphHeight; - - const GLfloat glyphAdvanceX = 0.0f; - const GLfloat glyphAdvanceY = 0.0f; - - _GLTglyph glyph; - - char c; - int i; - for (i = 0; i < text->_textLength; i++) - { - c = text->_text[i]; - - if (c == '\n') - { - glyphX = 0.0f; - glyphY += glyphHeight + glyphAdvanceY; - - continue; - } - else if (c == '\r') - { - glyphX = 0.0f; - - continue; - } - - if (!gltIsCharacterSupported(c)) - { -#ifdef GLT_UNKNOWN_CHARACTER - c = GLT_UNKNOWN_CHARACTER; - if (!gltIsCharacterSupported(c)) - continue; -#else - continue; -#endif - } - - glyph = _gltFontGlyphs2[c - _gltFontGlyphMinChar]; - - glyphWidth = (GLfloat)glyph.w; - - if (glyph.drawable) - { - vertices[vertexElementIndex++] = glyphX; - vertices[vertexElementIndex++] = glyphY; - vertices[vertexElementIndex++] = glyph.u1; - vertices[vertexElementIndex++] = glyph.v1; - - vertices[vertexElementIndex++] = glyphX + glyphWidth; - vertices[vertexElementIndex++] = glyphY + glyphHeight; - vertices[vertexElementIndex++] = glyph.u2; - vertices[vertexElementIndex++] = glyph.v2; - - vertices[vertexElementIndex++] = glyphX + glyphWidth; - vertices[vertexElementIndex++] = glyphY; - vertices[vertexElementIndex++] = glyph.u2; - vertices[vertexElementIndex++] = glyph.v1; - - vertices[vertexElementIndex++] = glyphX; - vertices[vertexElementIndex++] = glyphY; - vertices[vertexElementIndex++] = glyph.u1; - vertices[vertexElementIndex++] = glyph.v1; - - vertices[vertexElementIndex++] = glyphX; - vertices[vertexElementIndex++] = glyphY + glyphHeight; - vertices[vertexElementIndex++] = glyph.u1; - vertices[vertexElementIndex++] = glyph.v2; - - vertices[vertexElementIndex++] = glyphX + glyphWidth; - vertices[vertexElementIndex++] = glyphY + glyphHeight; - vertices[vertexElementIndex++] = glyph.u2; - vertices[vertexElementIndex++] = glyph.v2; - } - - glyphX += glyphWidth + glyphAdvanceX; - } - - text->vertexCount = vertexCount; - text->_vertices = vertices; - - glBindBuffer(GL_ARRAY_BUFFER, text->_vbo); - glBufferData(GL_ARRAY_BUFFER, vertexCount * _GLT_TEXT2D_VERTEX_SIZE * sizeof(GLfloat), vertices, GL_DYNAMIC_DRAW); - - text->_dirty = GL_FALSE; -} - -GLT_API GLboolean gltInit(void) -{ - if (gltInitialized) - return GL_TRUE; - - if (!_gltCreateText2DShader()) - return GL_FALSE; - - if (!_gltCreateText2DFontTexture()) - return GL_FALSE; - - gltInitialized = GL_TRUE; - return GL_TRUE; -} - -GLT_API void gltTerminate(void) -{ - if (_gltText2DShader != GLT_NULL_HANDLE) - { - glDeleteProgram(_gltText2DShader); - _gltText2DShader = GLT_NULL_HANDLE; - } - - if (_gltText2DFontTexture != GLT_NULL_HANDLE) - { - glDeleteTextures(1, &_gltText2DFontTexture); - _gltText2DFontTexture = GLT_NULL_HANDLE; - } - - gltInitialized = GL_FALSE; -} - -#if USE_GLES -#define GLSL_VERSION "300 es" -#else -#define GLSL_VERSION "330" -#endif - -static const GLchar* _gltText2DVertexShaderSource = -"#version " -GLSL_VERSION -"\n" -"layout(location = 0) in vec2 position;\n" -"layout(location = 1) in vec2 texCoord;\n" -"\n" -"uniform mat4 mvp;\n" -"\n" -"out vec2 fTexCoord;\n" -"\n" -"void main()\n" -"{\n" -" fTexCoord = texCoord;\n" -" \n" -" gl_Position = mvp * vec4(position, 0.0, 1.0);\n" -"}\n"; - -static const GLchar* _gltText2DFragmentShaderSource = -"#version " -GLSL_VERSION -"\n" -#if USE_GLES -"precision mediump float;\n" -"\n" -#endif -"out vec4 fragColor;\n" -"\n" -"in vec2 fTexCoord;\n" -"\n" -"uniform sampler2D diffuse;\n" -"\n" -"uniform vec4 color;\n" -"\n" -"void main()\n" -"{\n" -" fragColor = texture(diffuse, fTexCoord) * color;\n" -"}\n"; - -GLT_API GLboolean _gltCreateText2DShader(void) -{ - GLuint vertexShader, fragmentShader; - GLint compileStatus, linkStatus; - -#ifdef GLT_DEBUG_PRINT - GLint infoLogLength; - GLsizei infoLogSize; - GLchar *infoLog; -#endif - - vertexShader = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vertexShader, 1, &_gltText2DVertexShaderSource, NULL); - glCompileShader(vertexShader); - - glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &compileStatus); - - if (compileStatus != GL_TRUE) - { -#ifdef GLT_DEBUG_PRINT - glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &infoLogLength); - - // If no information log exists 0 is returned or 1 for a - // string only containing the null termination char. - if (infoLogLength > 1) - { - infoLogSize = infoLogLength * sizeof(GLchar); - infoLog = (GLchar*)malloc(infoLogSize); - - glGetShaderInfoLog(vertexShader, infoLogSize, NULL, infoLog); - - printf("Vertex Shader #%u :\n%s\n", vertexShader, infoLog); - - free(infoLog); - } -#endif - - glDeleteShader(vertexShader); - gltTerminate(); - -#ifdef GLT_DEBUG - _GLT_ASSERT(compileStatus == GL_TRUE); - return GL_FALSE; -#else - return GL_FALSE; -#endif - } - - fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fragmentShader, 1, &_gltText2DFragmentShaderSource, NULL); - glCompileShader(fragmentShader); - - glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &compileStatus); - - if (compileStatus != GL_TRUE) - { -#ifdef GLT_DEBUG_PRINT - glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &infoLogLength); - - // If no information log exists 0 is returned or 1 for a - // string only containing the null termination char. - if (infoLogLength > 1) - { - infoLogSize = infoLogLength * sizeof(GLchar); - infoLog = (GLchar*)malloc(infoLogSize); - - glGetShaderInfoLog(fragmentShader, infoLogSize, NULL, infoLog); - - printf("Fragment Shader #%u :\n%s\n", fragmentShader, infoLog); - - free(infoLog); - } -#endif - - glDeleteShader(vertexShader); - glDeleteShader(fragmentShader); - gltTerminate(); - -#ifdef GLT_DEBUG - _GLT_ASSERT(compileStatus == GL_TRUE); - return GL_FALSE; -#else - return GL_FALSE; -#endif - } - - _gltText2DShader = glCreateProgram(); - - glAttachShader(_gltText2DShader, vertexShader); - glAttachShader(_gltText2DShader, fragmentShader); - - glBindAttribLocation(_gltText2DShader, _GLT_TEXT2D_POSITION_LOCATION, "position"); - glBindAttribLocation(_gltText2DShader, _GLT_TEXT2D_TEXCOORD_LOCATION, "texCoord"); - -#if !defined(USE_GLES) - glBindFragDataLocation(_gltText2DShader, 0, "fragColor"); -#endif - - glLinkProgram(_gltText2DShader); - - glDetachShader(_gltText2DShader, vertexShader); - glDeleteShader(vertexShader); - - glDetachShader(_gltText2DShader, fragmentShader); - glDeleteShader(fragmentShader); - - glGetProgramiv(_gltText2DShader, GL_LINK_STATUS, &linkStatus); - - if (linkStatus != GL_TRUE) - { -#ifdef GLT_DEBUG_PRINT - glGetProgramiv(_gltText2DShader, GL_INFO_LOG_LENGTH, &infoLogLength); - - // If no information log exists 0 is returned or 1 for a - // string only containing the null termination char. - if (infoLogLength > 1) - { - infoLogSize = infoLogLength * sizeof(GLchar); - infoLog = (GLchar*)malloc(infoLogSize); - - glGetProgramInfoLog(_gltText2DShader, infoLogSize, NULL, infoLog); - - printf("Program #%u :\n%s\n", _gltText2DShader, infoLog); - - free(infoLog); - } -#endif - - gltTerminate(); - -#ifdef GLT_DEBUG - _GLT_ASSERT(linkStatus == GL_TRUE); - return GL_FALSE; -#else - return GL_FALSE; -#endif - } - - glUseProgram(_gltText2DShader); - - _gltText2DShaderMVPUniformLocation = glGetUniformLocation(_gltText2DShader, "mvp"); - _gltText2DShaderColorUniformLocation = glGetUniformLocation(_gltText2DShader, "color"); - - glUniform1i(glGetUniformLocation(_gltText2DShader, "diffuse"), 0); - - glUseProgram(0); - - return GL_TRUE; -} - -static const uint64_t _gltFontGlyphRects[_gltFontGlyphCount] = { - 0x1100040000, 0x304090004, 0x30209000D, 0x304090016, 0x30209001F, 0x304090028, 0x302090031, 0x409003A, - 0x302090043, 0x30109004C, 0x1080055, 0x30209005D, 0x302090066, 0x3040A006F, 0x304090079, 0x304090082, - 0x409008B, 0x4090094, 0x30409009D, 0x3040900A6, 0x3020900AF, 0x3040900B8, 0x3040900C1, 0x3040A00CA, - 0x3040900D4, 0x40A00DD, 0x3040900E7, 0x3020900F0, 0x3020900F9, 0x302090102, 0x30209010B, 0x302090114, - 0x30209011D, 0x302090126, 0x30209012F, 0x302070138, 0x30209013F, 0x302090148, 0x302090151, 0x3020A015A, - 0x3020A0164, 0x30209016E, 0x302090177, 0x102090180, 0x302090189, 0x302090192, 0x30209019B, 0x3020901A4, - 0x3020901AD, 0x3020A01B6, 0x3020901C0, 0x3020901C9, 0x3020901D2, 0x3020901DB, 0x3020901E4, 0x3020901ED, - 0x3020901F6, 0x3020A01FF, 0x302090209, 0x302090212, 0x30209021B, 0x302090224, 0x30209022D, 0x309060236, - 0x10906023C, 0x302070242, 0x302090249, 0x706090252, 0x50409025B, 0x202090264, 0x10207026D, 0x102070274, - 0x30406027B, 0x104060281, 0x2010B0287, 0x3020A0292, 0xB0007029C, 0x5040A02AA, 0x3020A02B4, 0x6050902BE, - 0x20702C7, 0x20702CE, 0xB010902D5, -}; - -#define _GLT_FONT_GLYPH_DATA_TYPE uint64_t -#define _GLT_FONT_PIXEL_SIZE_BITS 2 - -#define _gltFontGlyphDataCount 387 - -static const _GLT_FONT_GLYPH_DATA_TYPE _gltFontGlyphData[_gltFontGlyphDataCount] = { - 0x551695416A901554, 0x569695A5A56AA55A, 0x555554155545AA9, 0x916AA41569005A40, 0xA5A569695A5A5696, 0x51555556AA569695, 0x696916A941554155, 0x69155A55569555A5, - 0x15541555456A9569, 0xA9569545A4005500, 0x569695A5A569695A, 0x5545AA9569695A5A, 0x916A941554555415, 0x55A56AA95A5A5696, 0x40555416A9555695, 0x55A45AA505550155, - 0xA55AAA455A555691, 0x169005A45569155, 0xA945554015400554, 0x569695A5A569695A, 0x9545AA9569695A5A, 0x4555555AA95A5556, 0x55A4016900154555, 0xA569695A5A45AA90, - 0x69695A5A569695A5, 0x9001541555455555, 0x5AA4155505A4016, 0xA40169005A501695, 0x155555AAA4569505, 0x5A405A4015405555, 0x5A505A545AA45554, 0x5A405A405A405A40, - 0x555556A95A555A40, 0x569005A400551554, 0x9569A569695A5A45, 0xA5A56969169A556A, 0xA405555555155555, 0x169005A50169505A, 0x9505A40169005A40, 0x5555155555AAA456, - 0x95A66916AA905555, 0x695A6695A6695A66, 0x154555555A5695A6, 0x5696916AA4155555, 0x9695A5A569695A5A, 0x45555155555A5A56, 0xA5A5696916A94155, 0x9569695A5A569695, - 0x155515541555456A, 0x695A5A5696916AA4, 0x56AA569695A5A569, 0x5540169155A55569, 0x56AA515550015400, 0x9695A5A569695A5A, 0x5A5516AA55A5A56, 0x500155005A401695, - 0xA56A695A5A455555, 0x169015A55569556, 0x54005500155005A4, 0x555A555695AA9455, 0xAA569555A5505AA5, 0x15415551555556, 0x5A55AAA455A50169, 0x40169005A4556915, - 0x550155505AA5055A, 0xA569695A5A455555, 0x69695A5A569695A5, 0x555554155545AA95, 0x5A5A569695A5A455, 0xA515AA55A5A56969, 0x1545505500555055, 0x95A6695A6695A569, - 0xA4569A55A6695A66, 0x5551555015554569, 0x456A9569695A5A45, 0xA5A5696916A95569, 0x4155545555155555, 0xA45A5A45A5A45A5A, 0xA945A5A45A5A45A5, 0x56A915A555695056, - 0x4555501554055551, 0x6945695169555AAA, 0x55AAA45569156955, 0x5A50055055551555, 0xA569695A5A45AA50, 0x69695A5A56AA95A5, 0x555555155555A5A5, 0x5A5A5696916AA415, - 0x5A5696956AA56969, 0x1555556AA569695A, 0x96916A9415541555, 0x9555A555695A5A56, 0x6A9569695A5A4556, 0xA405551554155545, 0x69695A5A45A6905A, 0x695A5A569695A5A5, - 0x5550555555AA55A, 0x5A555695AAA45555, 0x4556916AA4156955, 0x5555AAA45569155A, 0x95AAA45555555515, 0x6AA41569555A5556, 0xA40169155A455691, 0x1554005500155005, - 0x695A5A5696916A94, 0x5A5A56A69555A555, 0x54155545AA956969, 0x569695A5A4555555, 0x9695AAA569695A5A, 0x55A5A569695A5A56, 0x55AA455555551555, 0x5A416905A456915A, - 0x515555AA45A51690, 0x169005A400550055, 0x9555A40169005A40, 0x456A9569695A5A56, 0xA5A4555515541555, 0xA55A69569A569695, 0x6969169A45A6915A, 0x555555155555A5A5, - 0x5A40169005A400, 0x5A40169005A40169, 0x155555AAA4556900, 0x695A569154555555, 0x6695A6695A9A95A5, 0xA5695A5695A6695A, 0x55154555555A5695, 0x95A5695A56915455, - 0x695AA695A6A95A5A, 0x5695A5695A5695A9, 0x155455154555555A, 0x695A5A5696916A94, 0x5A5A569695A5A569, 0x541555456A956969, 0x5696916AA4155515, 0x56956AA569695A5A, - 0x5005A40169155A55, 0x6A94155400550015, 0xA569695A5A569691, 0x69695A5A569695A5, 0x5A5415A5456A95, 0x16AA415555500155, 0xAA569695A5A56969, 0x569695A5A55A6956, - 0x5545555155555A5A, 0x5555A5696916A941, 0xA5545A5005A5155A, 0x41555456A9569695, 0x56955AAA45555155, 0x9005A40169055A51, 0x5A40169005A4016, 0x5A45555055001550, - 0x569695A5A569695A, 0x9695A5A569695A5A, 0x515541555456A956, 0xA5A569695A5A4555, 0xA569695A5A569695, 0x555055A515AA55A5, 0x95A5691545505500, 0x695A6695A5695A56, - 0x9A4569A55A6695A6, 0x555015554169A456, 0x9569695A5A455551, 0x5A6515A515694566, 0x555A5A569695A5A4, 0x5A5A455555555155, 0xA9569695A5A56969, 0x169015A41569456, - 0x55505500155005A4, 0x5A55169555AAA45, 0x55A455A555A515A5, 0x5155555AAA455690, 0x696916A941554555, 0xA95A5A56A695A9A5, 0x56A9569695A6A569, 0x9401540155415554, - 0x5A5516AA45A9516, 0xA40169005A401695, 0x4154005540169005, 0xA5A5696916A94155, 0x9556945695169555, 0x55555AAA45569156, 0x6916A94155455551, 0x56A5169555A5A569, - 0xA9569695A5A56955, 0x15415541555456, 0x4169A4055A4005A4, 0xA916969169A5169A, 0x50056954569555AA, 0x5AAA455551540015, 0xAA41569555A55569, 0x55A555A551695516, - 0x55005550555555AA, 0x915694569416A401, 0xA5A569695A5A45AA, 0x41555456A9569695, 0x69555AAA45555155, 0x9415A415A5056951, 0x169015A40569056, 0xA941554015400554, - 0x569A95A5A5696916, 0x9695A5A56A6956A9, 0x415541555456A956, 0xA5A5696916A94155, 0x516AA55A5A569695, 0x155415A915694569, 0x555A95A915505540, 0x5A55A95A91555545, - 0x1694154154555569, 0xA456956A95AA56A9, 0x55416905A415515, 0x696916A941554154, 0x9055A515A555A5A5, 0x5A4016900554056, 0xAA45555055001550, 0x5505555155555A, - 0x6955AAA4569505A4, 0x5500155055A515, 0x690169405A400550, 0x90569415A415A505, 0x569015A415A5056, 0x6941540015400554, 0xA456915A55A55691, 0x16905A505A416905, - 0x6901555405541694, 0x16905A505A416941, 0x6955A45A516905A4, 0xA455415415545695, 0x6A45555515556A56, 0x56A45555515556A5, 0xA56A45555515556A, 0x5505515555A56956, - 0x690569A4016A5001, 0x4056954169A9459A, 0x416A690156941569, 0x15A9505A695169A6, 0x4015505540055540, 0x94169A4169A405A9, 0x5A56A9A4555A415A, 0x555169A955A5A55A, - 0x6945A90555555415, 0x1555154055416941, 0x56AAA456A545A690, 0x40555515A69156A5, 0x6945A69015550555, 0xA6915A6956AAA45A, 0x5A6956AAA45A6955, 0x455540555515A691, - 0xAA9555556AA91555, 0xA915555554555556, 0x416905A556955A56, 0x5A416905A416905A, 0x555515555AA45690, 0x6905A516955AA455, 0x416905A416905A41, 0x55556A95A556905A, - 0xA5A5696915555554, 0x5555155555, -}; - -GLT_API GLboolean _gltCreateText2DFontTexture(void) -{ - if (gltInitialized) - return GL_TRUE; - - memset(_gltFontGlyphs, 0, _gltFontGlyphCount * sizeof(_GLTglyph)); - memset(_gltFontGlyphs2, 0, _gltFontGlyphLength * sizeof(_GLTglyph)); - - GLsizei texWidth = 0; - GLsizei texHeight = 0; - - GLsizei drawableGlyphCount = 0; - - _GLTglyphdata *glyphsData = (_GLTglyphdata*)calloc(_gltFontGlyphCount, sizeof(_GLTglyphdata)); - - uint64_t glyphPacked; - uint32_t glyphMarginPacked; - - uint16_t glyphX, glyphY, glyphWidth, glyphHeight; - uint16_t glyphMarginLeft, glyphMarginTop, glyphMarginRight, glyphMarginBottom; - - uint16_t glyphDataWidth, glyphDataHeight; - - glyphMarginLeft = 0; - glyphMarginRight = 0; - - _GLTglyph *glyph; - _GLTglyphdata *glyphData; - - char c; - int i; - int x, y; - - for (i = 0; i < _gltFontGlyphCount; i++) - { - c = _gltFontGlyphCharacters[i]; - - glyphPacked = _gltFontGlyphRects[i]; - - glyphX = (glyphPacked >> (uint64_t)(8 * 0)) & 0xFFFF; - glyphWidth = (glyphPacked >> (uint64_t)(8 * 2)) & 0xFF; - - glyphY = 0; - glyphHeight = _gltFontGlyphHeight; - - glyphMarginPacked = (glyphPacked >> (uint64_t)(8 * 3)) & 0xFFFF; - - glyphMarginTop = (glyphMarginPacked >> (uint16_t)(0)) & 0xFF; - glyphMarginBottom = (glyphMarginPacked >> (uint16_t)(8)) & 0xFF; - - glyphDataWidth = glyphWidth; - glyphDataHeight = glyphHeight - (glyphMarginTop + glyphMarginBottom); - - glyph = &_gltFontGlyphs[i]; - - glyph->c = c; - - glyph->x = glyphX; - glyph->y = glyphY; - glyph->w = glyphWidth; - glyph->h = glyphHeight; - - glyphData = &glyphsData[i]; - - glyphData->x = glyphX; - glyphData->y = glyphY; - glyphData->w = glyphWidth; - glyphData->h = glyphHeight; - - glyphData->marginLeft = glyphMarginLeft; - glyphData->marginTop = glyphMarginTop; - glyphData->marginRight = glyphMarginRight; - glyphData->marginBottom = glyphMarginBottom; - - glyphData->dataWidth = glyphDataWidth; - glyphData->dataHeight = glyphDataHeight; - - glyph->drawable = GL_FALSE; - - if ((glyphDataWidth > 0) && (glyphDataHeight > 0)) - glyph->drawable = GL_TRUE; - - if (glyph->drawable) - { - drawableGlyphCount++; - - texWidth += (GLsizei)glyphWidth; - - if (texHeight < glyphHeight) - texHeight = glyphHeight; - } - } - - const GLsizei textureGlyphPadding = 1; // amount of pixels added around the whole bitmap texture - const GLsizei textureGlyphSpacing = 1; // amount of pixels added between each glyph on the final bitmap texture - - texWidth += textureGlyphSpacing * (drawableGlyphCount - 1); - - texWidth += textureGlyphPadding * 2; - texHeight += textureGlyphPadding * 2; - - const GLsizei texAreaSize = texWidth * texHeight; - - const GLsizei texPixelComponents = 4; // R, G, B, A - GLubyte *texData = (GLubyte*)malloc(texAreaSize * texPixelComponents * sizeof(GLubyte)); - - GLsizei texPixelIndex; - - for (texPixelIndex = 0; texPixelIndex < (texAreaSize * texPixelComponents); texPixelIndex++) - texData[texPixelIndex] = 0; - -#define _GLT_TEX_PIXEL_INDEX(x, y) ((y) * texWidth * texPixelComponents + (x) * texPixelComponents) - -#define _GLT_TEX_SET_PIXEL(x, y, r, g, b, a) { \ - texPixelIndex = _GLT_TEX_PIXEL_INDEX(x, y); \ - texData[texPixelIndex + 0] = r; \ - texData[texPixelIndex + 1] = g; \ - texData[texPixelIndex + 2] = b; \ - texData[texPixelIndex + 3] = a; \ - } - - const int glyphDataTypeSizeBits = sizeof(_GLT_FONT_GLYPH_DATA_TYPE) * 8; // 8 bits in a byte - - int data0Index = 0; - int data1Index = 0; - - int bit0Index = 0; - int bit1Index = 1; - - char c0 = '0'; - char c1 = '0'; - - GLuint r, g, b, a; - - GLfloat u1, v1; - GLfloat u2, v2; - - GLsizei texX = 0; - GLsizei texY = 0; - - texX += textureGlyphPadding; - - for (i = 0; i < _gltFontGlyphCount; i++) - { - glyph = &_gltFontGlyphs[i]; - glyphData = &glyphsData[i]; - - if (!glyph->drawable) - continue; - - c = glyph->c; - - glyphX = glyph->x; - glyphY = glyph->y; - glyphWidth = glyph->w; - glyphHeight = glyph->h; - - glyphMarginLeft = glyphData->marginLeft; - glyphMarginTop = glyphData->marginTop; - glyphMarginRight = glyphData->marginRight; - glyphMarginBottom = glyphData->marginBottom; - - glyphDataWidth = glyphData->dataWidth; - glyphDataHeight = glyphData->dataHeight; - - texY = textureGlyphPadding; - - u1 = (GLfloat)texX / (GLfloat)texWidth; - v1 = (GLfloat)texY / (GLfloat)texHeight; - - u2 = (GLfloat)glyphWidth / (GLfloat)texWidth; - v2 = (GLfloat)glyphHeight / (GLfloat)texHeight; - - glyph->u1 = u1; - glyph->v1 = v1; - - glyph->u2 = u1 + u2; - glyph->v2 = v1 + v2; - - texX += glyphMarginLeft; - texY += glyphMarginTop; - - for (y = 0; y < glyphDataHeight; y++) - { - for (x = 0; x < glyphDataWidth; x++) - { - c0 = (_gltFontGlyphData[data0Index] >> bit0Index) & 1; - c1 = (_gltFontGlyphData[data1Index] >> bit1Index) & 1; - - if ((c0 == 0) && (c1 == 0)) - { - r = 0; - g = 0; - b = 0; - a = 0; - } - else if ((c0 == 0) && (c1 == 1)) - { - r = 255; - g = 255; - b = 255; - a = 255; - } - else if ((c0 == 1) && (c1 == 0)) - { - r = 0; - g = 0; - b = 0; - a = 255; - } - - _GLT_TEX_SET_PIXEL(texX + x, texY + y, r, g, b, a); - - bit0Index += _GLT_FONT_PIXEL_SIZE_BITS; - bit1Index += _GLT_FONT_PIXEL_SIZE_BITS; - - if (bit0Index >= glyphDataTypeSizeBits) - { - bit0Index = bit0Index % glyphDataTypeSizeBits; - data0Index++; - } - - if (bit1Index >= glyphDataTypeSizeBits) - { - bit1Index = bit1Index % glyphDataTypeSizeBits; - data1Index++; - } - } - } - - texX += glyphDataWidth; - texY += glyphDataHeight; - - texX += glyphMarginRight; - texX += textureGlyphSpacing; - } - - for (i = 0; i < _gltFontGlyphCount; i++) - { - glyph = &_gltFontGlyphs[i]; - - _gltFontGlyphs2[glyph->c - _gltFontGlyphMinChar] = *glyph; - } - -#undef _GLT_TEX_PIXEL_INDEX -#undef _GLT_TEX_SET_PIXEL - - glGenTextures(1, &_gltText2DFontTexture); - glBindTexture(GL_TEXTURE_2D, _gltText2DFontTexture); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - free(texData); - - free(glyphsData); - - return GL_TRUE; -} - -#endif - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/src/libprojectM/resource.h b/src/libprojectM/resource.h deleted file mode 100644 index a0b6e9601..000000000 --- a/src/libprojectM/resource.h +++ /dev/null @@ -1,14 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by libprojectM.rc - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif