Nicolas Winkler 4 lat temu
rodzic
commit
9146d8a554
2 zmienionych plików z 101 dodań i 8 usunięć
  1. 97 8
      EscapeTimeVisualWidget.cpp
  2. 4 0
      EscapeTimeVisualWidget.h

+ 97 - 8
EscapeTimeVisualWidget.cpp

@@ -5,6 +5,8 @@
 #include <QOpenGLShaderProgram>
 #include <QOpenGLContext>
 #include <QOpenGLFunctions>
+#include <QOpenGLExtraFunctions>
+#include <QOpenGLFunctions_3_0>
 
 #include <vector>
 
@@ -22,7 +24,7 @@ ETVImage::ETVImage(EscapeTimeVisualWidget& owner,
     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     gl.glBindTexture(GL_TEXTURE_2D, 0);
 }
 
@@ -38,6 +40,14 @@ void ETVImage::draw(float x, float y, float w, float h,
                     float tx, float ty, float tw, float th)
 {
     auto& gl = *owner.context()->functions();
+    auto& gle = *owner.context()->extraFunctions();
+
+    GLfloat const fbVertices[] = {
+        0, 0,  0.0f,
+        0, 256, 0.0f,
+        256, 0, 0.0f,
+        256, 256, 0.0f,
+    };
 
     GLfloat const vertices[] = {
         x, y,  0.0f,
@@ -53,6 +63,14 @@ void ETVImage::draw(float x, float y, float w, float h,
         tx + tw, ty + th,
     };
 
+    GLfloat const fullTexCoords[] = {
+        0, 0,
+        0, 1,
+        1, 0,
+        1, 1,
+    };
+
+
     QColor color{ 255, 255, 255 };
     auto& program = owner.program;
     int vertexLoc = program->attributeLocation("vertex");
@@ -60,14 +78,23 @@ void ETVImage::draw(float x, float y, float w, float h,
     int colorLocation = program->uniformLocation("color");
     int texLoc = program->uniformLocation("tex");
     int gradLoc = program->uniformLocation("gradient");
-    program->setAttributeArray(vertexLoc, vertices, 3);
+    program->setAttributeArray(vertexLoc, fbVertices, 3);
     program->setAttributeArray(texCoordsLoc, texCoords, 2);
     program->enableAttributeArray(vertexLoc);
     program->enableAttributeArray(texCoordsLoc);
     program->setUniformValue(colorLocation, color);
 
-
     gl.glEnable(GL_TEXTURE_2D);
+    owner.program->bind();
+
+    //GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0 };
+    //gle.glDrawBuffers(1, drawBuffers);
+    if(gl.glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
+        printf("error intitializing framebuffer\n");
+    }
+    gl.glBindFramebuffer(GL_FRAMEBUFFER, owner.tileFramebuffer);
+    gl.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, owner.tileTexture, 0);
+    //gl.glViewport(0, 0, 256, 256);
 
     gl.glUniform1i(texLoc, 0);
     gl.glUniform1i(gradLoc, 2);
@@ -80,6 +107,24 @@ void ETVImage::draw(float x, float y, float w, float h,
     gl.glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
     program->disableAttributeArray(vertexLoc);
     program->disableAttributeArray(texCoordsLoc);
+
+    owner.renderTextures->bind();
+    gl.glBindFramebuffer(GL_FRAMEBUFFER, 0);
+    //gl.glViewport(0, 0, owner.getResolutionX(), owner.getResolutionY());
+    int rtVertexLoc = owner.renderTextures->attributeLocation("vertex");
+    int rtTexCoordsLoc = owner.renderTextures->attributeLocation("texCoord");
+    int rtTexLoc = owner.renderTextures->attributeLocation("tex");
+
+    gl.glActiveTexture(GL_TEXTURE0);
+    gl.glUniform1i(rtTexLoc, 0);
+    owner.renderTextures->setAttributeArray(rtVertexLoc, vertices, 3);
+    owner.renderTextures->setAttributeArray(rtTexCoordsLoc, fullTexCoords, 2);
+    owner.renderTextures->enableAttributeArray(rtVertexLoc);
+    owner.renderTextures->enableAttributeArray(rtTexCoordsLoc);
+    gl.glBindTexture(GL_TEXTURE_2D, owner.tileTexture);
+    gl.glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+    owner.renderTextures->disableAttributeArray(rtVertexLoc);
+    owner.renderTextures->disableAttributeArray(rtTexCoordsLoc);
     gl.glActiveTexture(GL_TEXTURE0);
 }
 
@@ -117,6 +162,29 @@ void EscapeTimeVisualWidget::initializeGL(void)
 
     //glShadeModel(GL_SMOOTH);
 
+    renderTextures = new QOpenGLShaderProgram{ this->context() };
+    renderTextures->addShaderFromSourceCode(QOpenGLShader::Vertex,
+    "attribute highp vec4 vertex;\n"
+    "attribute highp vec2 texCoord;\n"
+    "uniform highp mat4 matrix;\n"
+    "varying highp vec2 texc;\n"
+    "void main(void)\n"
+    "{\n"
+    "   gl_Position = matrix * vertex;\n"
+    "   texc = texCoord;\n"
+    "}");
+    renderTextures->addShaderFromSourceCode(QOpenGLShader::Fragment,
+    "#version 110\n"
+    "uniform sampler2D tex;\n"
+    "varying highp vec2 texc;\n"
+    "void main(void)\n"
+    "{\n"
+    "    gl_FragColor = texture2D(tex, texc);\n"
+    "}");
+
+    renderTextures->link();
+
+
     program = new QOpenGLShaderProgram{ this->context() };
     bool vert = program->addShaderFromSourceCode(QOpenGLShader::Vertex,
     "attribute highp vec4 vertex;\n"
@@ -131,7 +199,7 @@ void EscapeTimeVisualWidget::initializeGL(void)
 
     // TODO rewrite this monster
     bool frag = program->addShaderFromSourceCode(QOpenGLShader::Fragment,
-    "#version 400\n"
+    "#version 110\n"
     "uniform sampler2D gradient;\n"
     "uniform sampler2D tex;\n"
     "uniform mediump vec4 color;\n"
@@ -140,8 +208,8 @@ void EscapeTimeVisualWidget::initializeGL(void)
     "void main(void)\n"
     "{\n"
     "   float v = texture2D(tex, texc).r;\n"
-    "   vec2 size = textureSize(tex, 0);\n"
-    //"   size = vec2(256.0, 256.0);\n"
+    /*"   vec2 size = textureSize(tex, 0);\n"
+    "   size = vec2(256.0, 256.0);\n"
     "   vec2 accPoint = texc * size;\n"
     "   vec2 ip = floor(accPoint);\n"
     "   vec2 fp = fract(accPoint);\n"
@@ -150,9 +218,9 @@ void EscapeTimeVisualWidget::initializeGL(void)
     "   vec4 col2 = texture2D(gradient, vec2(inter.y*0.005, 0.0));\n"
     "   vec4 col3 = texture2D(gradient, vec2(inter.z*0.005, 0.0));\n"
     "   vec4 col4 = texture2D(gradient, vec2(inter.w*0.005, 0.0));\n"
-    "   vec4 col = mix(mix(col4, col3, fp.x), mix(col1, col2, fp.x), fp.y);\n"
+    "   vec4 col = mix(mix(col4, col3, fp.x), mix(col1, col2, fp.x), fp.y);\n"*/
     "   gl_FragColor = texture2D(gradient, vec2(v*0.005, 0.0));\n"
-    "   gl_FragColor = col;\n"
+    //"   gl_FragColor = col;\n"
 //    "   gl_FragColor = gl_FragColor * texture2D(tex, texc);\n"
 //    "   float v = texture2D(tex, texc).r;\n"
 //    "   gl_FragColor = vec4(v, 1.0 - v, v*v, 1);\n"
@@ -161,6 +229,7 @@ void EscapeTimeVisualWidget::initializeGL(void)
     
     //program.link();
     bool bound = program->bind();
+    bound = renderTextures->bind();
 
     int vertexLoc = program->attributeLocation("vertex");
     int texCoordsLoc = program->attributeLocation("texCoord");
@@ -169,6 +238,22 @@ void EscapeTimeVisualWidget::initializeGL(void)
     int gradLoc = program->uniformLocation("gradient");
     int gradientScaler = program->uniformLocation("gradientScaler");
 
+    auto& gle = *this->context()->extraFunctions();
+
+    gl.glGenTextures(1, &tileTexture);
+    gl.glBindTexture(GL_TEXTURE_2D, tileTexture);
+    gl.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
+    gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+    gl.glGenFramebuffers(1, &tileFramebuffer);
+    gl.glBindFramebuffer(GL_FRAMEBUFFER, tileFramebuffer);
+    gl.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tileTexture, 0);
+    GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0 };
+    gle.glDrawBuffers(1, drawBuffers);
+    if(gl.glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
+        printf("error intitializing framebuffer\n");
+    }
 
     unsigned char pix[] = { 255, 0, 0, 0, 255, 0, 0, 0, 255 };
 
@@ -186,6 +271,7 @@ void EscapeTimeVisualWidget::initializeGL(void)
 
     gradientTextureId = id;
 
+    gl.glDisable(GL_DEPTH_TEST);
     //gl3.glBindSampler(0, id);
 }
 
@@ -207,7 +293,9 @@ void EscapeTimeVisualWidget::resizeGL(int w, int h)
     QMatrix4x4 pmvMatrix;
     pmvMatrix.ortho(QRectF{ 0, 0, newW, newH });
     int matrixLocation = program->uniformLocation("matrix");
+    int rtMatrixLocation = renderTextures->uniformLocation("matrix");
     program->setUniformValue(matrixLocation, pmvMatrix);
+    renderTextures->setUniformValue(rtMatrixLocation, pmvMatrix);
 }
 
 
@@ -215,6 +303,7 @@ void EscapeTimeVisualWidget::paintGL(void)
 {
     if (gradientNeedsUpdate)
         updateGradient();
+
     /*ETVImage etvi{ *this };
 
     auto& gl = *this->context()->functions();

+ 4 - 0
EscapeTimeVisualWidget.h

@@ -32,6 +32,7 @@ class EscapeTimeVisualWidget :
 
     friend class ETVImage;
     QOpenGLShaderProgram* program;
+    QOpenGLShaderProgram* renderTextures;
     GLuint gradientTextureId;
     Gradient gradient;
     bool gradientNeedsUpdate;
@@ -39,6 +40,9 @@ class EscapeTimeVisualWidget :
     float resolutionX;
     float resolutionY;
 
+    GLuint tileFramebuffer;
+    GLuint tileTexture;
+
 public:
     EscapeTimeVisualWidget(QWidget* parent = nullptr);