|
@@ -0,0 +1,179 @@
|
|
|
+#include "EscapeTimeVisualWidget.h"
|
|
|
+
|
|
|
+#include "Bitmap.h"
|
|
|
+
|
|
|
+#include <QOpenGLShaderProgram>
|
|
|
+#include <QOpenGLContext>
|
|
|
+#include <QOpenGLFunctions>
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ETVImage::ETVImage(EscapeTimeVisualWidget& owner) :
|
|
|
+ owner{ owner }
|
|
|
+{
|
|
|
+ auto& gl = *owner.context()->functions();
|
|
|
+ gl.glGenTextures(1, &textureId);
|
|
|
+ gl.glActiveTexture(GL_TEXTURE0);
|
|
|
+ gl.glBindTexture(GL_TEXTURE_2D, textureId);
|
|
|
+
|
|
|
+ Bitmap<float> img{512, 512};
|
|
|
+ for (int i = 0; i < img.width; i++) {
|
|
|
+ for (int j = 0; j < img.height; j++) {
|
|
|
+ img.get(i, j) = (i ^ j);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ gl.glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, int(img.width), int(img.height), 0, GL_RED, GL_FLOAT, img.pixels.get());
|
|
|
+ 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_LINEAR);
|
|
|
+ gl.glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ETVImage::~ETVImage(void)
|
|
|
+{
|
|
|
+ auto& gl = *owner.context()->functions();
|
|
|
+ gl.glDeleteTextures(1, &textureId);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void ETVImage::draw(float x, float y, float w, float h,
|
|
|
+ float tx, float ty, float tw, float th)
|
|
|
+{
|
|
|
+ auto& gl = *owner.context()->functions();
|
|
|
+
|
|
|
+ GLfloat const vertices[] = {
|
|
|
+ x, y, 0.0f,
|
|
|
+ x, y + h, 0.0f,
|
|
|
+ x + w, y, 0.0f,
|
|
|
+ x + w, y + h, 0.0f,
|
|
|
+ };
|
|
|
+
|
|
|
+ GLfloat const texCoords[] = {
|
|
|
+ tx, ty,
|
|
|
+ tx, ty + th,
|
|
|
+ tx + tw, ty,
|
|
|
+ tx + tw, ty + th,
|
|
|
+ };
|
|
|
+
|
|
|
+ QColor color{ 255, 255, 255 };
|
|
|
+ auto& program = owner.program;
|
|
|
+ int vertexLoc = program->attributeLocation("vertex");
|
|
|
+ int texCoordsLoc = program->attributeLocation("texCoord");
|
|
|
+ int colorLocation = program->uniformLocation("color");
|
|
|
+ int texLoc = program->uniformLocation("tex");
|
|
|
+ int gradLoc = program->uniformLocation("gradient");
|
|
|
+ program->setAttributeArray(vertexLoc, vertices, 3);
|
|
|
+ program->setAttributeArray(texCoordsLoc, texCoords, 2);
|
|
|
+ program->enableAttributeArray(vertexLoc);
|
|
|
+ program->enableAttributeArray(texCoordsLoc);
|
|
|
+ program->setUniformValue(colorLocation, color);
|
|
|
+
|
|
|
+
|
|
|
+ gl.glEnable(GL_TEXTURE_2D);
|
|
|
+
|
|
|
+ gl.glUniform1i(texLoc, 0);
|
|
|
+ gl.glUniform1i(gradLoc, 2);
|
|
|
+
|
|
|
+ gl.glActiveTexture(GL_TEXTURE0);
|
|
|
+ gl.glBindTexture(GL_TEXTURE_2D, textureId);
|
|
|
+ gl.glActiveTexture(GL_TEXTURE2);
|
|
|
+ gl.glBindTexture(GL_TEXTURE_2D, owner.gradientTextureId);
|
|
|
+
|
|
|
+ gl.glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
|
|
+ program->disableAttributeArray(vertexLoc);
|
|
|
+ program->disableAttributeArray(texCoordsLoc);
|
|
|
+ gl.glActiveTexture(GL_TEXTURE0);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+EscapeTimeVisualWidget::EscapeTimeVisualWidget(QWidget* parent) :
|
|
|
+ QOpenGLWidget{ parent }
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void EscapeTimeVisualWidget::initializeGL(void)
|
|
|
+{
|
|
|
+ auto& gl = *this->context()->functions();
|
|
|
+ gl.glClearColor(0, 0, 0, 0);
|
|
|
+
|
|
|
+ gl.glDisable(GL_DEPTH_TEST);
|
|
|
+
|
|
|
+ // looks not even better
|
|
|
+ //gl.glEnable(GL_FRAMEBUFFER_SRGB);
|
|
|
+
|
|
|
+ //glShadeModel(GL_SMOOTH);
|
|
|
+
|
|
|
+ program = new QOpenGLShaderProgram{ this->context() };
|
|
|
+ bool vert = program->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"
|
|
|
+ "}");
|
|
|
+ bool frag = program->addShaderFromSourceCode(QOpenGLShader::Fragment,
|
|
|
+ "uniform sampler2D gradient;\n"
|
|
|
+ "uniform sampler2D tex;\n"
|
|
|
+ "uniform mediump vec4 color;\n"
|
|
|
+ "varying highp vec2 texc;\n"
|
|
|
+ "void main(void)\n"
|
|
|
+ "{\n"
|
|
|
+ " float v = texture2D(tex, texc).r;\n"
|
|
|
+ " gl_FragColor = texture2D(gradient, vec2(v*0.005, 0.0));\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"
|
|
|
+// " gl_FragColor.g = 0.3;\n"
|
|
|
+ "}");
|
|
|
+ //program.link();
|
|
|
+ bool bound = program->bind();
|
|
|
+
|
|
|
+ unsigned char pix[] = { 255, 0, 0, 0, 255, 0, 0, 0, 255 };
|
|
|
+
|
|
|
+ GLuint id;
|
|
|
+ gl.glEnable(GL_TEXTURE_2D);
|
|
|
+ gl.glGenTextures(1, &id);
|
|
|
+ gl.glBindTexture(GL_TEXTURE_2D, id);
|
|
|
+
|
|
|
+ gl.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 3, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, reinterpret_cast<char*> (pix));
|
|
|
+ gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
|
|
+ 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_LINEAR);
|
|
|
+ gl.glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
+
|
|
|
+ gradientTextureId = id;
|
|
|
+
|
|
|
+ //gl3.glBindSampler(0, id);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void EscapeTimeVisualWidget::resizeGL(int w, int h)
|
|
|
+{
|
|
|
+ auto& gl = *this->context()->functions();
|
|
|
+ float pixelRatio = this->devicePixelRatioF();
|
|
|
+ gl.glViewport(0, 0, w * pixelRatio, h * pixelRatio);
|
|
|
+
|
|
|
+ QMatrix4x4 pmvMatrix;
|
|
|
+ pmvMatrix.ortho(QRectF{ 0, 0, w * pixelRatio, h * pixelRatio });
|
|
|
+ int matrixLocation = program->uniformLocation("matrix");
|
|
|
+ program->setUniformValue(matrixLocation, pmvMatrix);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void EscapeTimeVisualWidget::paintGL(void)
|
|
|
+{
|
|
|
+ ETVImage etvi{ *this };
|
|
|
+
|
|
|
+ auto& gl = *this->context()->functions();
|
|
|
+ gl.glClearColor(0.0, 0.2, 0.0, 1.0);
|
|
|
+ gl.glClear(GL_COLOR_BUFFER_BIT);
|
|
|
+
|
|
|
+ etvi.draw(100, 100, 700, 700);
|
|
|
+}
|