-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdata.cpp
130 lines (113 loc) · 4.98 KB
/
data.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include "data.h"
#include <QDebug>
#include <QColor>
#include <QFileInfo>
#include "application.h"
#include "util.h"
const TextureData::Format TextureData::FORMATS[] = {
{Format::Indexed, "Indexed", GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, sizeof(GLubyte), {GL_COLOR_ATTACHMENT0, GL_NONE}, 0},
{Format::RGBA, "RGBA", GL_RGBA8UI, GL_BGRA_INTEGER, GL_UNSIGNED_BYTE, sizeof(GLubyte) * 4, {GL_NONE, GL_COLOR_ATTACHMENT0}, 1},
};
TextureData::TextureData(const QSize &size, const Format::Id format, const GLubyte *const data) :
OpenGLData(), size(size), format(format),
texture([this, data](){
const TextureData::Format *const format = &FORMATS[(int)this->format];
GLuint texture;
glGenTextures((GLsizei)1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
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_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D, 0, format->internalFormat, this->size.width(), this->size.height(), 0, format->format, format->glEnum, data);
return texture; }()),
framebuffer([this](){
const TextureData::Format *const format = &FORMATS[(int)this->format];
GLuint framebuffer;
glGenFramebuffers((GLsizei)1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
glDrawBuffers(2, format->buffers);
// glBindFramebuffer(GL_FRAMEBUFFER, 0);
return framebuffer; }())
{
}
TextureData::~TextureData()
{
GLContextGrabber grab(context, surface);
glDeleteTextures(1, &texture);
glDeleteFramebuffers(1, &framebuffer);
}
GLubyte *TextureData::readPixel(const QPoint &position, GLubyte *const buffer)
{
GLubyte *data = (buffer != nullptr) ? buffer : new GLubyte[size.width() * size.height() * FORMATS[(int)format].size];
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glReadPixels(position.x(), position.y(), 1, 1, FORMATS[(int)format].format, FORMATS[(int)format].glEnum, data);
return data;
}
void TextureData::writePixel(const QPoint &position, const GLubyte *const data)
{
glBindTexture(GL_TEXTURE_2D, texture);
glTexSubImage2D(GL_TEXTURE_2D, 0, position.x(), position.y(), 1, 1, FORMATS[(int)format].format, FORMATS[(int)format].glEnum, data);
}
GLubyte *TextureData::readData(GLubyte *const buffer)
{
GLubyte *data = (buffer != nullptr) ? buffer : new GLubyte[size.width() * size.height() * FORMATS[(int)format].size];
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glReadPixels(0, 0, size.width(), size.height(), FORMATS[(int)format].format, FORMATS[(int)format].glEnum, data);
return data;
}
void TextureData::writeData(const GLubyte *const data)
{
glBindTexture(GL_TEXTURE_2D, texture);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size.width(), size.height(), FORMATS[(int)format].format, FORMATS[(int)format].glEnum, data);
}
void TextureData::clear(const GLubyte *const data)
{
const TextureData::Format *const format = &FORMATS[(int)this->format];
GLuint buffer[format->size];
for (int i = 0; i < format->size; i++) {
buffer[i] = data[i];
}
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
glClearBufferuiv(GL_COLOR, format->outputBuffer, buffer);
}
PaletteData::PaletteData(const GLuint length, const GLubyte *const data) :
TextureData(QSize(length, 1), Format::RGBA, data)
{
}
ImageData::ImageData(const QSize &size, const Format::Id format, const GLubyte *const data) :
TextureData(size, format, data), rect(QPoint(0, 0), size),
projectionMatrix([this]() {
const float halfWidth = (float)this->size.width() / 2.f;
const float halfHeight = (float)this->size.height() / 2.f;
QMatrix4x4 temp;
temp.scale(1.f / (float)halfWidth, 1.f / (float)halfHeight);
temp.translate(-halfWidth, -halfHeight);
return temp; }()),
vertexArray([this](){
GLuint vertexArray;
glGenVertexArrays(1, &vertexArray);
return vertexArray; }()),
vertexBuffer([this](){
GLuint vertexBuffer;
glGenBuffers((GLsizei)1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
const GLfloat vertices[][2] = {
{0.f, 0.f},
{(GLfloat)this->size.width(), 0.f},
{(GLfloat)this->size.width(), (GLfloat)this->size.height()},
{0.f, (GLfloat)this->size.height()},
};
glBufferData(GL_ARRAY_BUFFER, 4 * 2 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
return vertexBuffer; }())
{
}
ImageData::~ImageData()
{
GLContextGrabber grab(context, surface);
glDeleteVertexArrays(1, &vertexArray);
glDeleteBuffers(1, &vertexBuffer);
}