get curves data in shader

This commit is contained in:
jrkb 2023-04-01 17:36:00 +02:00
parent 6661f7eb0f
commit d8a7bc7a98
6 changed files with 274 additions and 55 deletions

View file

@ -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;

View file

@ -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

View file

@ -5,6 +5,10 @@
#include "ofMain.h"
#include <ft2build.h>
#ifdef TARGET_OPENGLES
#include <GL/gl.h>
#include <GLES/gl.h>
#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 <BufferGlyph> bufferGlyphs;

View file

@ -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);

View file

@ -1,4 +1,33 @@
#include "ofApp.h"
#include "ofAppRunner.h"
#include "ofGraphics.h"
#include "ofTexture.h"
#ifdef TARGET_EMSCRIPTEN
#include <GLES/gl.h>
#include <emscripten/emscripten.h>
#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 dont know yet where to
start. I hope to capture something essential.)DONE";
shaderCatalog = std::make_unique <ShaderCatalog>("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 <ShaderCatalog>(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, &currentProgram);
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 <ShaderCatalog>(shaderDir);
//backgroundShader = shaderCatalog->get("background");
fontShader = shaderCatalog->get("font");
}
}
//--------------------------------------------------------------

View file

@ -77,7 +77,7 @@ class ofApp : public ofBaseApp {
GLuint emptyVAO;
std::unique_ptr <ShaderCatalog> shaderCatalog;
std::shared_ptr <ShaderCatalog::Entry> backgroundShader;
//std::shared_ptr <ShaderCatalog::Entry> backgroundShader;
std::shared_ptr <ShaderCatalog::Entry> 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;