forked from bwrrp/glblaat
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGLTexture3D.cpp
126 lines (110 loc) · 3.61 KB
/
GLTexture3D.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
#include "GLTexture3D.h"
#include "GLTextureRectangle.h"
#include <iostream>
#include "GLUtility.h"
using namespace std;
// ----------------------------------------------------------------------------
GLTexture3D *GLTexture3D::New(int width, int height, int depth,
int internalformat, int format, int type,
void *data)
{
// Check if width and height are powers of two
unsigned short xs = (unsigned short)width;
unsigned short ys = (unsigned short)height;
unsigned short zs = (unsigned short)depth;
while (!(xs & 0x01))
{
xs = xs >> 1;
}
while (!(ys & 0x01))
{
ys = ys >> 1;
}
while (!(zs & 0x01))
{
zs = zs >> 1;
}
if ((xs > 1)||(ys > 1)||(zs > 1))
{
// Non-power-of-two sizes, check available extensions
if (GLEW_ARB_texture_non_power_of_two)
{
cout << "GLTexture: sizes are not powers of two, creating NPOTS texture" << endl;
GLTexture3D *tex = new GLTexture3D(width, height, depth, internalformat);
if (!tex->Allocate(format, type, data))
{
delete tex;
return 0;
}
return tex;
}
cerr << "GLTexture: non-power-of-two sized textures not supported" << endl;
return 0;
}
else
{
// Create a normal texture
GLTexture3D *tex = new GLTexture3D(width, height, depth, internalformat);
if (!tex->Allocate(format, type, data))
{
delete tex;
return 0;
}
return tex;
}
}
// ----------------------------------------------------------------------------
GLTexture3D::GLTexture3D(int width, int height, int depth, int internalformat)
: GLTexture(width, height, internalformat), depth(depth)
{
//cout << "GLTexture3D: Constructor" << endl;
}
// ----------------------------------------------------------------------------
GLTexture3D::~GLTexture3D()
{
//cout << "GLTexture3D: Destructor" << endl;
}
// ----------------------------------------------------------------------------
bool GLTexture3D::Allocate(int format, int type, void *data)
{
//cout << "GLTexture3D: Allocate" << endl;
// Store old binding to avoid messing up the state
glPushAttrib(GL_TEXTURE_BIT);
// Store new params
this->dataformat = format;
this->datatype = type;
BindToCurrent();
// Set texture object parameters
glTexParameterf(GetTextureTarget(), GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameterf(GetTextureTarget(), GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameterf(GetTextureTarget(), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameterf(GetTextureTarget(), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameterf(GetTextureTarget(), GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE );
// Try a proxy allocation to check available memory and parameters
glTexImage3D(GL_PROXY_TEXTURE_3D, 0, internalformat,
width, height, depth, 0, format, type, data);
GLint w;
glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &w);
GLUtility::CheckOpenGLError("GLTexture3D: Allocate() - proxy allocation");
bool eflag = GLUtility::GetErrorFlag();
if (w == 0 || eflag)
{
cerr << "GLTexture3D: Proxy allocation failed, may be out of video memory" << endl;
UnbindCurrent();
glPopAttrib();
return false;
}
// Allocate the texture
glTexImage3D(GetTextureTarget(), 0, internalformat,
width, height, depth, 0, format, type, data);
GLUtility::CheckOpenGLError("GLTexture3D: Allocate - glTexImage3D");
UnbindCurrent();
glPopAttrib();
if (GLUtility::GetErrorFlag())
{
cerr << "GLTexture3D: An OpenGL error occurred while allocating the texture" << endl;
GLUtility::ClearOpenGLError();
return false;
}
return true;
}