2013-12-22 14:04:33 +00:00
|
|
|
#include "OpenGLVariable.h"
|
|
|
|
|
|
|
|
#include <QOpenGLShaderProgram>
|
2013-12-23 09:26:29 +00:00
|
|
|
#include <cassert>
|
2015-12-03 22:04:50 +00:00
|
|
|
#include "OpenGLFunctions.h"
|
2013-12-22 17:05:11 +00:00
|
|
|
#include "OpenGLRenderer.h"
|
2013-12-22 14:04:33 +00:00
|
|
|
#include "OpenGLShaderProgram.h"
|
|
|
|
#include "Vector3.h"
|
2013-12-22 16:30:48 +00:00
|
|
|
#include "Matrix4.h"
|
2013-12-22 14:04:33 +00:00
|
|
|
#include "Color.h"
|
2013-12-22 17:05:11 +00:00
|
|
|
#include "Texture2D.h"
|
|
|
|
#include "Texture3D.h"
|
|
|
|
#include "Texture4D.h"
|
2013-12-22 14:04:33 +00:00
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
OpenGLVariable::OpenGLVariable(const std::string &name) : name(name) {
|
2013-12-22 14:04:33 +00:00
|
|
|
type = TYPE_NONE;
|
2013-12-22 17:05:11 +00:00
|
|
|
texture_toupload = false;
|
2015-09-21 19:01:44 +00:00
|
|
|
texture_id = 0;
|
2013-12-22 14:04:33 +00:00
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void OpenGLVariable::apply(OpenGLShaderProgram *program, int &texture_unit) {
|
|
|
|
QOpenGLShaderProgram *pr = program->getProgram();
|
|
|
|
OpenGLFunctions *functions = program->getRenderer()->getOpenGlFunctions();
|
2013-12-22 17:05:11 +00:00
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
if (texture_toupload) {
|
2013-12-22 17:05:11 +00:00
|
|
|
uploadTexture(program->getRenderer());
|
|
|
|
texture_toupload = false;
|
|
|
|
}
|
2013-12-22 14:04:33 +00:00
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
switch (type) {
|
2013-12-22 14:04:33 +00:00
|
|
|
case TYPE_FLOAT:
|
|
|
|
pr->setUniformValue(name.c_str(), value_float);
|
|
|
|
break;
|
|
|
|
case TYPE_COLOR:
|
|
|
|
pr->setUniformValue(name.c_str(), value_color);
|
|
|
|
break;
|
|
|
|
case TYPE_VECTOR3:
|
|
|
|
pr->setUniformValue(name.c_str(), value_vector3);
|
|
|
|
break;
|
2013-12-22 16:30:48 +00:00
|
|
|
case TYPE_MATRIX4:
|
|
|
|
pr->setUniformValue(name.c_str(), value_matrix4);
|
|
|
|
break;
|
2013-12-22 17:05:11 +00:00
|
|
|
case TYPE_TEXTURE_2D:
|
|
|
|
functions->glActiveTexture(GL_TEXTURE0 + texture_unit);
|
|
|
|
functions->glBindTexture(GL_TEXTURE_2D, texture_id);
|
|
|
|
pr->setUniformValue(name.c_str(), texture_unit);
|
|
|
|
texture_unit++;
|
|
|
|
break;
|
|
|
|
case TYPE_TEXTURE_3D:
|
|
|
|
case TYPE_TEXTURE_4D:
|
|
|
|
functions->glActiveTexture(GL_TEXTURE0 + texture_unit);
|
|
|
|
functions->glBindTexture(GL_TEXTURE_3D, texture_id);
|
|
|
|
pr->setUniformValue(name.c_str(), texture_unit);
|
|
|
|
texture_unit++;
|
|
|
|
break;
|
2013-12-22 14:04:33 +00:00
|
|
|
case TYPE_NONE:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void OpenGLVariable::set(const Texture2D *texture, bool repeat, bool color) {
|
2013-12-22 17:05:11 +00:00
|
|
|
assert(type == TYPE_NONE or type == TYPE_TEXTURE_2D);
|
|
|
|
|
|
|
|
type = TYPE_TEXTURE_2D;
|
|
|
|
value_tex2d = texture;
|
|
|
|
texture_toupload = true;
|
2014-01-05 19:37:51 +00:00
|
|
|
texture_repeat = repeat;
|
|
|
|
texture_color = color;
|
2013-12-22 17:05:11 +00:00
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void OpenGLVariable::set(const Texture3D *texture, bool repeat, bool color) {
|
2013-12-22 17:05:11 +00:00
|
|
|
assert(type == TYPE_NONE or type == TYPE_TEXTURE_3D);
|
|
|
|
|
|
|
|
type = TYPE_TEXTURE_3D;
|
|
|
|
value_tex3d = texture;
|
|
|
|
texture_toupload = true;
|
2014-01-05 19:37:51 +00:00
|
|
|
texture_repeat = repeat;
|
|
|
|
texture_color = color;
|
2013-12-22 17:05:11 +00:00
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void OpenGLVariable::set(const Texture4D *texture, bool repeat, bool color) {
|
2013-12-22 17:05:11 +00:00
|
|
|
assert(type == TYPE_NONE or type == TYPE_TEXTURE_4D);
|
|
|
|
|
|
|
|
type = TYPE_TEXTURE_4D;
|
|
|
|
value_tex4d = texture;
|
|
|
|
texture_toupload = true;
|
2014-01-05 19:37:51 +00:00
|
|
|
texture_repeat = repeat;
|
|
|
|
texture_color = color;
|
2013-12-22 17:05:11 +00:00
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void OpenGLVariable::set(float value) {
|
2013-12-22 14:04:33 +00:00
|
|
|
assert(type == TYPE_NONE or type == TYPE_FLOAT);
|
|
|
|
|
|
|
|
type = TYPE_FLOAT;
|
|
|
|
value_float = value;
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void OpenGLVariable::set(const Vector3 &vector) {
|
2013-12-22 16:30:48 +00:00
|
|
|
set(QVector3D(vector.x, vector.y, vector.z));
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void OpenGLVariable::set(const QVector3D &vector) {
|
2013-12-22 16:30:48 +00:00
|
|
|
assert(type == TYPE_NONE or type == TYPE_VECTOR3);
|
2013-12-22 14:04:33 +00:00
|
|
|
|
|
|
|
type = TYPE_VECTOR3;
|
2013-12-22 16:30:48 +00:00
|
|
|
value_vector3 = vector;
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void OpenGLVariable::set(const Matrix4 &matrix) {
|
2013-12-22 16:30:48 +00:00
|
|
|
set(matrix.toQMatrix());
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void OpenGLVariable::set(const QMatrix4x4 &matrix) {
|
2013-12-22 16:30:48 +00:00
|
|
|
assert(type == TYPE_NONE or type == TYPE_MATRIX4);
|
|
|
|
|
|
|
|
type = TYPE_MATRIX4;
|
|
|
|
value_matrix4 = matrix;
|
2013-12-22 14:04:33 +00:00
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void OpenGLVariable::set(const Color &color) {
|
2013-12-22 14:04:33 +00:00
|
|
|
assert(type == TYPE_NONE or type == TYPE_COLOR);
|
|
|
|
|
|
|
|
type = TYPE_COLOR;
|
2014-01-05 20:52:09 +00:00
|
|
|
value_color = QColor::fromRgbF(color.r, color.g, color.b);
|
2013-12-22 14:04:33 +00:00
|
|
|
}
|
2013-12-22 17:05:11 +00:00
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void OpenGLVariable::uploadTexture(OpenGLRenderer *renderer) {
|
|
|
|
OpenGLFunctions *functions = renderer->getOpenGlFunctions();
|
2013-12-22 17:05:11 +00:00
|
|
|
|
|
|
|
assert(type == TYPE_TEXTURE_2D or type == TYPE_TEXTURE_3D or type == TYPE_TEXTURE_4D);
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
if (texture_id == 0) {
|
2013-12-22 17:05:11 +00:00
|
|
|
GLuint texid;
|
|
|
|
functions->glGenTextures(1, &texid);
|
|
|
|
texture_id = texid;
|
|
|
|
}
|
|
|
|
|
|
|
|
GLenum textype = (type == TYPE_TEXTURE_2D) ? GL_TEXTURE_2D : GL_TEXTURE_3D;
|
|
|
|
|
|
|
|
functions->glBindTexture(textype, texture_id);
|
|
|
|
functions->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
|
functions->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
2014-01-05 19:37:51 +00:00
|
|
|
functions->glTexParameteri(textype, GL_TEXTURE_WRAP_S, texture_repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE);
|
|
|
|
functions->glTexParameteri(textype, GL_TEXTURE_WRAP_T, texture_repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE);
|
2015-11-09 21:30:46 +00:00
|
|
|
if (textype == GL_TEXTURE_3D) {
|
2014-01-05 19:37:51 +00:00
|
|
|
functions->glTexParameteri(textype, GL_TEXTURE_WRAP_R, texture_repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE);
|
2013-12-22 17:05:11 +00:00
|
|
|
}
|
|
|
|
|
2014-01-05 19:37:51 +00:00
|
|
|
int dest_format = texture_color ? GL_RGBA : GL_RED;
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
if (type == TYPE_TEXTURE_2D) {
|
2013-12-22 17:05:11 +00:00
|
|
|
int sx, sy;
|
|
|
|
value_tex2d->getSize(&sx, &sy);
|
2015-11-09 21:30:46 +00:00
|
|
|
float *pixels = new float[sx * sy * 4];
|
|
|
|
for (int x = 0; x < sx; x++) {
|
|
|
|
for (int y = 0; y < sy; y++) {
|
|
|
|
float *pixel = pixels + (y * sx + x) * 4;
|
2013-12-22 17:05:11 +00:00
|
|
|
Color col = value_tex2d->getPixel(x, y);
|
|
|
|
pixel[0] = (float)col.r;
|
|
|
|
pixel[1] = (float)col.g;
|
|
|
|
pixel[2] = (float)col.b;
|
|
|
|
pixel[3] = (float)col.a;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-05 19:37:51 +00:00
|
|
|
functions->glTexImage2D(GL_TEXTURE_2D, 0, dest_format, sx, sy, 0, GL_RGBA, GL_FLOAT, pixels);
|
2013-12-22 17:05:11 +00:00
|
|
|
delete[] pixels;
|
2015-11-09 21:30:46 +00:00
|
|
|
} else if (type == TYPE_TEXTURE_3D) {
|
2013-12-22 17:05:11 +00:00
|
|
|
int sx, sy, sz;
|
|
|
|
value_tex3d->getSize(&sx, &sy, &sz);
|
2015-11-09 21:30:46 +00:00
|
|
|
float *pixels = new float[sx * sy * sz * 4];
|
|
|
|
for (int x = 0; x < sx; x++) {
|
|
|
|
for (int y = 0; y < sy; y++) {
|
|
|
|
for (int z = 0; z < sz; z++) {
|
|
|
|
float *pixel = pixels + (z * (sx * sy) + y * sx + x) * 4;
|
2013-12-22 17:05:11 +00:00
|
|
|
Color col = value_tex3d->getPixel(x, y, z);
|
|
|
|
pixel[0] = (float)col.r;
|
|
|
|
pixel[1] = (float)col.g;
|
|
|
|
pixel[2] = (float)col.b;
|
|
|
|
pixel[3] = (float)col.a;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-05 19:37:51 +00:00
|
|
|
functions->glTexImage3D(GL_TEXTURE_3D, 0, dest_format, sx, sy, sz, 0, GL_RGBA, GL_FLOAT, pixels);
|
2013-12-22 17:05:11 +00:00
|
|
|
delete[] pixels;
|
2015-11-09 21:30:46 +00:00
|
|
|
} else {
|
2013-12-22 17:05:11 +00:00
|
|
|
int sx, sy, sz, sw;
|
|
|
|
value_tex4d->getSize(&sx, &sy, &sz, &sw);
|
2015-11-09 21:30:46 +00:00
|
|
|
float *pixels = new float[sx * sy * sz * sw * 4];
|
|
|
|
for (int x = 0; x < sx; x++) {
|
|
|
|
for (int y = 0; y < sy; y++) {
|
|
|
|
for (int z = 0; z < sz; z++) {
|
|
|
|
for (int w = 0; w < sw; w++) {
|
|
|
|
float *pixel = pixels + (w * (sx * sy * sz) + z * (sx * sy) + y * sx + x) * 4;
|
2013-12-22 17:05:11 +00:00
|
|
|
Color col = value_tex4d->getPixel(x, y, z, w);
|
|
|
|
pixel[0] = (float)col.r;
|
|
|
|
pixel[1] = (float)col.g;
|
|
|
|
pixel[2] = (float)col.b;
|
|
|
|
pixel[3] = (float)col.a;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-05 19:37:51 +00:00
|
|
|
functions->glTexImage3D(GL_TEXTURE_3D, 0, dest_format, sx, sy, sz * sw, 0, GL_RGBA, GL_FLOAT, pixels);
|
2013-12-22 17:05:11 +00:00
|
|
|
delete[] pixels;
|
|
|
|
}
|
|
|
|
}
|