From d8a7bc7a98e1ae0b77a99064cb287f198cf1234a Mon Sep 17 00:00:00 2001 From: themancalledjakob Date: Sat, 1 Apr 2023 17:36:00 +0200 Subject: [PATCH] get curves data in shader --- data/ofxGPUFont/shaders/GL3/font.frag | 10 +- example/clean.sh | 2 +- example/src/gpufont/font.hpp | 212 +++++++++++++++++++++----- example/src/main.cpp | 3 +- example/src/ofApp.cpp | 94 ++++++++++-- example/src/ofApp.h | 8 +- 6 files changed, 274 insertions(+), 55 deletions(-) diff --git a/data/ofxGPUFont/shaders/GL3/font.frag b/data/ofxGPUFont/shaders/GL3/font.frag index 71c33f0..8c5f638 100644 --- a/data/ofxGPUFont/shaders/GL3/font.frag +++ b/data/ofxGPUFont/shaders/GL3/font.frag @@ -20,7 +20,7 @@ uniform vec4 color; // Size of the window (in pixels) used for 1-dimensional anti-aliasing along each rays. // 0 - no anti-aliasing // 1 - normal anti-aliasing -// >=2 - exaggerated effect +// >=2 - exaggerated effect uniform float antiAliasingWindowSize = 1.0; // Enable a second ray along the y-axis to achieve 2-dimensional anti-aliasing. @@ -65,7 +65,7 @@ float computeCoverage(float inverseDiameter, vec2 p0, vec2 p1, vec2 p2) { // Quadratic segment, solve abc formula to find roots. float radicand = b.y*b.y - a.y*c.y; if (radicand <= 0) return 0.0; - + float s = sqrt(radicand); t0 = (b.y - s) / a.y; t1 = (b.y + s) / a.y; @@ -86,7 +86,7 @@ float computeCoverage(float inverseDiameter, vec2 p0, vec2 p1, vec2 p2) { } float alpha = 0; - + if (t0 >= 0 && t0 < 1) { float x = (a.x*t0 - 2.0*b.x)*t0 + c.x; alpha += clamp(x * inverseDiameter + 0.5, 0, 1); @@ -123,6 +123,10 @@ void main() { alpha += computeCoverage(inverseDiameter.y, rotate(p0), rotate(p1), rotate(p2)); } } + vec4 debug = texelFetch(curves, int(uv.x * textureSize(curves))); + result = vec4(debug.rgb, 1.0); + + return; if (enableSuperSamplingAntiAliasing) { alpha *= 0.5; diff --git a/example/clean.sh b/example/clean.sh index f1cfc89..8124f4c 100755 --- a/example/clean.sh +++ b/example/clean.sh @@ -5,7 +5,7 @@ PREVIOUS_DIR=$(pwd) cd $DIR -emmake make clean && make clean && rm -rf obj && rm -rf ../../obj +make clean && rm -rf obj && rm -rf ../../../addons/obj rm -rf ../../../libs/openFrameworksCompiled/lib/linux64/obj rm -rf ../../../libs/openFrameworksCompiled/lib/linux64/libopenFrameworks.a rm -rf ../../../libs/openFrameworksCompiled/lib/emscripten/obj diff --git a/example/src/gpufont/font.hpp b/example/src/gpufont/font.hpp index 0b97aee..8f6f0b6 100644 --- a/example/src/gpufont/font.hpp +++ b/example/src/gpufont/font.hpp @@ -5,6 +5,10 @@ #include "ofMain.h" #include +#ifdef TARGET_OPENGLES + #include + #include +#endif #include FT_FREETYPE_H #include FT_MULTIPLE_MASTERS_H @@ -89,13 +93,11 @@ class Font { static FT_Face loadFace(FT_Library library, const std::string & filename, std::string & error){ FT_Face face = NULL; - string pwd = ofSystem("pwd"); - cout << "pwd: " << pwd << endl; - pwd.erase(std::remove_if(pwd.begin(), pwd.end(), ::isspace), pwd.end()); - cout << "fontPAth: " << pwd << "/" << filename << endl; - string fontPath = pwd + "/" + filename; + //string pwd = ofSystem("pwd"); + //pwd.erase(std::remove_if(pwd.begin(), pwd.end(), ::isspace), pwd.end()); + //string fontPath = pwd + "/" + filename; - FT_Error ftError = FT_New_Face(library, fontPath.c_str(), 0, &face); + FT_Error ftError = FT_New_Face(library, filename.c_str(), 0, &face); if(ftError){ const char * ftErrorStr = FT_Error_String(ftError); if(ftErrorStr){ @@ -144,11 +146,18 @@ class Font { glGenBuffers(1, &vbo); glGenBuffers(1, &ebo); - glGenTextures(1, &glyphTexture); - glGenTextures(1, &curveTexture); + #ifndef TARGET_OPENGLES + glGenTextures(1, &glyphTexture); + glGenTextures(1, &curveTexture); + #endif - glGenBuffers(1, &glyphBuffer); - glGenBuffers(1, &curveBuffer); + #ifndef TARGET_OPENGLES + glGenBuffers(1, &glyphBuffer); + glGenBuffers(1, &curveBuffer); + #else + glGenTextures(1, &glyphBuffer); + glGenTextures(1, &curveBuffer); + #endif glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, vbo); @@ -190,13 +199,40 @@ class Font { uploadBuffers(); - glBindTexture(GL_TEXTURE_BUFFER, glyphTexture); - glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32I, glyphBuffer); - glBindTexture(GL_TEXTURE_BUFFER, 0); + #ifndef TARGET_OPENGLES + glBindTexture(GL_TEXTURE_BUFFER, glyphTexture); + glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32I, glyphBuffer); + glBindTexture(GL_TEXTURE_BUFFER, 0); - glBindTexture(GL_TEXTURE_BUFFER, curveTexture); - glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32F, curveBuffer); - glBindTexture(GL_TEXTURE_BUFFER, 0); + glBindTexture(GL_TEXTURE_BUFFER, curveTexture); + glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32F, curveBuffer); + glBindTexture(GL_TEXTURE_BUFFER, 0); + #else + //glBindTexture(GL_TEXTURE_2D, glyphTexture); + + //glTexImage2D(GL_TEXTURE_2D, + //0, + //GL_RG32I, + //2048, + //1, + //0, + //GL_RG, + //GL_INT, + //&glyphBuffer); + //glBindTexture(GL_TEXTURE_2D, 0); + + //glBindTexture(GL_TEXTURE_2D, curveTexture); + //glTexImage2D(GL_TEXTURE_2D, + //0, + //GL_RG32F, + //2048, + //1, + //0, + //GL_RG, + //GL_INT, + //&glyphBuffer); + //glBindTexture(GL_TEXTURE_2D, 0); + #endif } ~Font(){ @@ -205,11 +241,16 @@ class Font { glDeleteBuffers(1, &vbo); glDeleteBuffers(1, &ebo); - glDeleteTextures(1, &glyphTexture); - glDeleteTextures(1, &curveTexture); + #ifndef TARGET_OPENGLES + glDeleteTextures(1, &glyphTexture); + glDeleteTextures(1, &curveTexture); - glDeleteBuffers(1, &glyphBuffer); - glDeleteBuffers(1, &curveBuffer); + glDeleteBuffers(1, &glyphBuffer); + glDeleteBuffers(1, &curveBuffer); + #else + glDeleteTextures(1, &glyphBuffer); + glDeleteTextures(1, &curveBuffer); + #endif FT_Done_Face(face); } @@ -296,13 +337,95 @@ class Font { private: void uploadBuffers(){ - glBindBuffer(GL_TEXTURE_BUFFER, glyphBuffer); - glBufferData(GL_TEXTURE_BUFFER, sizeof(BufferGlyph) * bufferGlyphs.size(), bufferGlyphs.data(), GL_STATIC_DRAW); - glBindBuffer(GL_TEXTURE_BUFFER, 0); + cout << "bufferGlyphs.size(): " << bufferGlyphs.size() << endl; + cout << "bufferCurves.size(): " << bufferCurves.size() << endl; + #ifndef TARGET_OPENGLES + glBindBuffer(GL_TEXTURE_BUFFER, glyphBuffer); + glBufferData(GL_TEXTURE_BUFFER, sizeof(BufferGlyph) * bufferGlyphs.size(), bufferGlyphs.data(), GL_STATIC_DRAW); + glBindBuffer(GL_TEXTURE_BUFFER, 0); - glBindBuffer(GL_TEXTURE_BUFFER, curveBuffer); - glBufferData(GL_TEXTURE_BUFFER, sizeof(BufferCurve) * bufferCurves.size(), bufferCurves.data(), GL_STATIC_DRAW); - glBindBuffer(GL_TEXTURE_BUFFER, 0); + glBindBuffer(GL_TEXTURE_BUFFER, curveBuffer); + glBufferData(GL_TEXTURE_BUFFER, sizeof(BufferCurve) * bufferCurves.size(), bufferCurves.data(), GL_STATIC_DRAW); + glBindBuffer(GL_TEXTURE_BUFFER, 0); + #else + //glBindBuffer(GL_TEXTURE_2D, glyphBuffer); + //glBufferData(GL_TEXTURE_2D, sizeof(BufferGlyph) * bufferGlyphs.size(), bufferGlyphs.data(), GL_STATIC_DRAW); + //glBindBuffer(GL_TEXTURE_2D, 0); + + //glBindBuffer(GL_TEXTURE_2D, curveBuffer); + //glBufferData(GL_TEXTURE_2D, sizeof(BufferCurve) * bufferCurves.size(), bufferCurves.data(), GL_STATIC_DRAW); + //glBindBuffer(GL_TEXTURE_2D, 0); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, glyphBuffer); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_NEAREST); + + glTexImage2D(GL_TEXTURE_2D, + 0, + GL_RG32I, + bufferGlyphs.size(), + 1, + 0, + GL_RG_INTEGER, + GL_INT, + bufferGlyphs.data()); + glBindTexture(GL_TEXTURE_2D, 0); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, curveBuffer); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, + 0, + GL_RG32F, + bufferCurves.size(), + 1, + 0, + GL_RG, + GL_FLOAT, + bufferCurves.data()); + + //unsigned char * data = new unsigned char[3 * size * sizeof(unsigned char)]; + //for(unsigned int i = 0; i < size; i++){ + //data[i * 3] = (unsigned char)(155.0f); + //data[i * 3 + 1] = (unsigned char)(155.0f); + //data[i * 3 + 2] = (unsigned char)(255.0f); + //} + //glTexImage2D(GL_TEXTURE_2D, + //0, + //GL_RGB, + //size, + //1, + //0, + //GL_RGB, + //GL_UNSIGNED_BYTE, + //data); + // + //int size = 2048; + //float * data = new float[2 * size * sizeof(float)]; + //for(unsigned int i = 0; i < size; i++){ + //data[i * 2] = (float)(0.0f); + //data[i * 2 + 1] = (float)(0.0f); + //} + //glTexImage2D(GL_TEXTURE_2D, + //0, + //GL_RG32F, + //size, + //1, + //0, + //GL_RG, + //GL_FLOAT, + //data); + #endif } void buildGlyph(uint32_t charcode, FT_UInt glyphIndex){ @@ -566,18 +689,33 @@ class Font { void drawSetup(){ GLint location; - location = glGetUniformLocation(program, "glyphs"); - glUniform1i(location, 0); - location = glGetUniformLocation(program, "curves"); - glUniform1i(location, 1); + #ifndef TARGET_OPENGLES + location = glGetUniformLocation(program, "glyphs"); + glUniform1i(location, 0); + location = glGetUniformLocation(program, "curves"); + glUniform1i(location, 1); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_BUFFER, glyphTexture); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_BUFFER, glyphTexture); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_BUFFER, curveTexture); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_BUFFER, curveTexture); + glActiveTexture(GL_TEXTURE0); + #else + glyphBuffer = glGetUniformLocation(program, "glyphs"); + glUniform1i(glyphBuffer, 0); + curveBuffer = glGetUniformLocation(program, "curves"); + glUniform1i(curveBuffer, 1); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_BUFFER, glyphBuffer); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_BUFFER, curveBuffer); + + glActiveTexture(GL_TEXTURE0); + #endif - glActiveTexture(GL_TEXTURE0); } void draw(float x, float y, float z, const std::string & text){ @@ -750,7 +888,9 @@ class Font { float worldSize; GLuint vao, vbo, ebo; - GLuint glyphTexture, curveTexture; + #ifndef TARGET_OPENGLES + GLuint glyphTexture, curveTexture; + #endif GLuint glyphBuffer, curveBuffer; std::vector bufferGlyphs; diff --git a/example/src/main.cpp b/example/src/main.cpp index 7a3543d..f5cf0cc 100644 --- a/example/src/main.cpp +++ b/example/src/main.cpp @@ -6,7 +6,8 @@ int main(){ #ifdef OF_TARGET_OPENGLES ofGLESWindowSettings settings; //settings.setSize(1920, 1080); - settings.glesVersion = 3; + settings.glesVersionMajor = 3; + settings.glesVersionMinor = 0; #else ofGLWindowSettings settings; settings.setSize(1920, 1080); diff --git a/example/src/ofApp.cpp b/example/src/ofApp.cpp index 3997915..3f6a379 100644 --- a/example/src/ofApp.cpp +++ b/example/src/ofApp.cpp @@ -1,4 +1,33 @@ #include "ofApp.h" +#include "ofAppRunner.h" +#include "ofGraphics.h" +#include "ofTexture.h" + +#ifdef TARGET_EMSCRIPTEN + #include + #include +#endif + +/* validate webgl shaders like this: +const gl = document.getElementDyId('canvas').getContext('webgl2'); +var get_shader=function(shadersource,shadertype) +{ + var shader=gl.createShader(shadertype); + gl.shaderSource(shader,shadersource); + gl.compileShader(shader); + + // Check for any compilation error + if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + alert(gl.getShaderInfoLog(shader)); + return null; + } + + return shader; +} +get_shader(`#version 300 es +bla bla bla +`, gl.FRAGMENT_SHADER); // -> aaaand error +*/ //-------------------------------------------------------------- void ofApp::setup(){ @@ -46,8 +75,13 @@ to cultivate, or a resource to be exploited… This is going to be difficult. I don’t know yet where to start. I hope to capture something essential.)DONE"; - shaderCatalog = std::make_unique ("data/ofxGPUFont/shaders/GL3"); - backgroundShader = shaderCatalog->get("background"); + #ifdef TARGET_EMSCRIPTEN + string shaderDir = "data/ofxGPUFont/shaders/ES3"; + #else + string shaderDir = "data/ofxGPUFont/shaders/GL3"; + #endif + shaderCatalog = std::make_unique (shaderDir); + //backgroundShader = shaderCatalog->get("background"); fontShader = shaderCatalog->get("font"); { @@ -66,6 +100,24 @@ start. I hope to capture something essential.)DONE"; bb); transform = Transform(); + + int maxSamples; + glGetIntegerv(GL_MAX_SAMPLES, &maxSamples); + cout << "MAX_SAMPLES: " << ofToString(maxSamples) << endl; + int maxTexSize; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize); + cout << "MAX_TEXTURE_SIZE: " << ofToString(maxTexSize) << endl; + + const unsigned char * glVersion = glGetString(GL_VERSION); + int glMajor, glMinor; + glGetIntegerv(GL_MAJOR_VERSION, &glMajor); + glGetIntegerv(GL_MINOR_VERSION, &glMinor); + + cout << "GL_VERSION: " << glVersion + << " | Major(" << ofToString(glMajor) << ")" + << " | Minor(" << ofToString(glMajor) << ")" + << endl; + } //-------------------------------------------------------------- @@ -84,20 +136,25 @@ void ofApp::draw(){ glm::mat4 view = transform.getViewMatrix(); glm::mat4 model = glm::mat4(1.0f); - { // Draw background. - GLuint program = backgroundShader->program; - glUseProgram(program); - glBindVertexArray(emptyVAO); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glBindVertexArray(0); - glUseProgram(0); - } + //{ // Draw background. + //GLuint program = backgroundShader->program; + //glUseProgram(program); + //glBindVertexArray(emptyVAO); + //glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + //glBindVertexArray(0); + //glUseProgram(0); + //} + + ofBackground(ofColor::pink); // Uses premultiplied-alpha. glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + int currentProgram; + glGetIntegerv(GL_CURRENT_PROGRAM, ¤tProgram); + if(font){ GLuint program = fontShader->program; glUseProgram(program); @@ -107,6 +164,7 @@ void ofApp::draw(){ location = glGetUniformLocation(program, "projection"); glUniformMatrix4fv(location, 1, false, glm::value_ptr(projection)); + location = glGetUniformLocation(program, "view"); glUniformMatrix4fv(location, 1, false, glm::value_ptr(view)); location = glGetUniformLocation(program, "model"); @@ -116,7 +174,7 @@ void ofApp::draw(){ glUniform1f(location, z); location = glGetUniformLocation(program, "color"); - glUniform4f(location, 1.0f, 1.0f, 1.0f, 1.0f); + glUniform4f(location, 1.0f, 0.0f, 1.0f, 1.0f); location = glGetUniformLocation(program, "antiAliasingWindowSize"); glUniform1f(location, (float)antiAliasingWindowSize); @@ -128,11 +186,12 @@ void ofApp::draw(){ float cx = 0.5f * (bb.minX + bb.maxX); float cy = 0.5f * (bb.minY + bb.maxY); font->draw(-cx, -cy, 0, mainText); - glUseProgram(0); + glUseProgram(currentProgram); } glDisable(GL_BLEND); + ofDrawBitmapStringHighlight("fps: " + ofToString(ofGetFrameRate()), 20, 20); } //-------------------------------------------------------------- @@ -142,7 +201,16 @@ void ofApp::keyPressed(int key){ //-------------------------------------------------------------- void ofApp::keyReleased(int key){ - + if(key == 'l'){ + #ifdef TARGET_EMSCRIPTEN + string shaderDir = "data/ofxGPUFont/shaders/ES3"; + #else + string shaderDir = "data/ofxGPUFont/shaders/GL3"; + #endif + shaderCatalog = std::make_unique (shaderDir); + //backgroundShader = shaderCatalog->get("background"); + fontShader = shaderCatalog->get("font"); + } } //-------------------------------------------------------------- diff --git a/example/src/ofApp.h b/example/src/ofApp.h index 1c9ad98..1f48270 100644 --- a/example/src/ofApp.h +++ b/example/src/ofApp.h @@ -77,7 +77,7 @@ class ofApp : public ofBaseApp { GLuint emptyVAO; std::unique_ptr shaderCatalog; - std::shared_ptr backgroundShader; + //std::shared_ptr backgroundShader; std::shared_ptr fontShader; Font::BoundingBox bb; @@ -89,8 +89,14 @@ class ofApp : public ofBaseApp { float helpFontBaseSize = 20.0f; +// Size of the window (in pixels) used for 1-dimensional anti-aliasing along each rays. +// 0 - no anti-aliasing +// 1 - normal anti-aliasing +// >=2 - exaggerated effect int antiAliasingWindowSize = 1; +// Enable a second ray along the y-axis to achieve 2-dimensional anti-aliasing. bool enableSuperSamplingAntiAliasing = true; +// Draw control points for debugging (green - on curve, magenta - off curve). bool enableControlPointsVisualization = false; bool showHelp = true;