2013-12-22 14:04:33 +00:00
|
|
|
#include "OpenGLVariable.h"
|
|
|
|
|
|
|
|
#include <cassert>
|
|
|
|
#include <QOpenGLShaderProgram>
|
2013-12-22 17:05:11 +00:00
|
|
|
#include <QOpenGLFunctions_3_2_Core>
|
|
|
|
#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
|
|
|
|
|
|
|
OpenGLVariable::OpenGLVariable(const std::string &name):
|
|
|
|
name(name)
|
|
|
|
{
|
|
|
|
type = TYPE_NONE;
|
2013-12-22 17:05:11 +00:00
|
|
|
texture_toupload = false;
|
2013-12-22 14:04:33 +00:00
|
|
|
}
|
|
|
|
|
2013-12-22 17:05:11 +00:00
|
|
|
void OpenGLVariable::apply(OpenGLShaderProgram *program, int &texture_unit)
|
2013-12-22 14:04:33 +00:00
|
|
|
{
|
|
|
|
QOpenGLShaderProgram* pr = program->getProgram();
|
2013-12-22 17:05:11 +00:00
|
|
|
QOpenGLFunctions_3_2_Core* functions = program->getRenderer()->getOpenGlFunctions();
|
|
|
|
|
|
|
|
if (texture_toupload)
|
|
|
|
{
|
|
|
|
uploadTexture(program->getRenderer());
|
|
|
|
texture_toupload = false;
|
|
|
|
}
|
2013-12-22 14:04:33 +00:00
|
|
|
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-22 17:05:11 +00:00
|
|
|
void OpenGLVariable::set(const Texture2D *texture)
|
|
|
|
{
|
|
|
|
assert(type == TYPE_NONE or type == TYPE_TEXTURE_2D);
|
|
|
|
|
|
|
|
type = TYPE_TEXTURE_2D;
|
|
|
|
value_tex2d = texture;
|
|
|
|
texture_toupload = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenGLVariable::set(const Texture3D *texture)
|
|
|
|
{
|
|
|
|
assert(type == TYPE_NONE or type == TYPE_TEXTURE_3D);
|
|
|
|
|
|
|
|
type = TYPE_TEXTURE_3D;
|
|
|
|
value_tex3d = texture;
|
|
|
|
texture_toupload = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenGLVariable::set(const Texture4D *texture)
|
|
|
|
{
|
|
|
|
assert(type == TYPE_NONE or type == TYPE_TEXTURE_4D);
|
|
|
|
|
|
|
|
type = TYPE_TEXTURE_4D;
|
|
|
|
value_tex4d = texture;
|
|
|
|
texture_toupload = true;
|
|
|
|
}
|
|
|
|
|
2013-12-22 14:04:33 +00:00
|
|
|
void OpenGLVariable::set(float value)
|
|
|
|
{
|
|
|
|
assert(type == TYPE_NONE or type == TYPE_FLOAT);
|
|
|
|
|
|
|
|
type = TYPE_FLOAT;
|
|
|
|
value_float = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenGLVariable::set(const Vector3 &vector)
|
|
|
|
{
|
2013-12-22 16:30:48 +00:00
|
|
|
set(QVector3D(vector.x, vector.y, vector.z));
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenGLVariable::set(const QVector3D &vector)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenGLVariable::set(const Matrix4 &matrix)
|
|
|
|
{
|
|
|
|
set(matrix.toQMatrix());
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenGLVariable::set(const QMatrix4x4 &matrix)
|
|
|
|
{
|
|
|
|
assert(type == TYPE_NONE or type == TYPE_MATRIX4);
|
|
|
|
|
|
|
|
type = TYPE_MATRIX4;
|
|
|
|
value_matrix4 = matrix;
|
2013-12-22 14:04:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void OpenGLVariable::set(const Color &color)
|
|
|
|
{
|
|
|
|
assert(type == TYPE_NONE or type == TYPE_COLOR);
|
|
|
|
|
|
|
|
type = TYPE_COLOR;
|
|
|
|
value_color = QColor(color.r, color.g, color.b);
|
|
|
|
}
|
2013-12-22 17:05:11 +00:00
|
|
|
|
|
|
|
void OpenGLVariable::uploadTexture(OpenGLRenderer* renderer)
|
|
|
|
{
|
|
|
|
QOpenGLFunctions_3_2_Core* functions = renderer->getOpenGlFunctions();
|
|
|
|
|
|
|
|
assert(type == TYPE_TEXTURE_2D or type == TYPE_TEXTURE_3D or type == TYPE_TEXTURE_4D);
|
|
|
|
|
|
|
|
if (texture_id == 0)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
functions->glTexParameteri(textype, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
|
|
functions->glTexParameteri(textype, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
|
|
if (textype == GL_TEXTURE_3D)
|
|
|
|
{
|
|
|
|
functions->glTexParameteri(textype, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (type == TYPE_TEXTURE_2D)
|
|
|
|
{
|
|
|
|
int sx, sy;
|
|
|
|
value_tex2d->getSize(&sx, &sy);
|
|
|
|
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;
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
functions->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sx, sy, 0, GL_RGBA, GL_FLOAT, pixels);
|
|
|
|
delete[] pixels;
|
|
|
|
}
|
|
|
|
else if (type == TYPE_TEXTURE_3D)
|
|
|
|
{
|
|
|
|
int sx, sy, sz;
|
|
|
|
value_tex3d->getSize(&sx, &sy, &sz);
|
|
|
|
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;
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
functions->glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, sx, sy, sz, 0, GL_RGBA, GL_FLOAT, pixels);
|
|
|
|
delete[] pixels;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int sx, sy, sz, sw;
|
|
|
|
value_tex4d->getSize(&sx, &sy, &sz, &sw);
|
|
|
|
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;
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
functions->glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, sx, sy, sz * sw, 0, GL_RGBA, GL_FLOAT, pixels);
|
|
|
|
delete[] pixels;
|
|
|
|
}
|
|
|
|
}
|