Skip to content
GitLab
Explore
Sign in
Register
Show whitespace changes
Inline
Side-by-side
SDLTest/src/RenderDispatcher.cpp
View file @
b85ec35b
...
...
@@ -54,7 +54,16 @@ bool RenderDispatcher::dispatchNoRecurse(const std::unordered_set<GUIElement*>&
instances
.
clear
();
instancesClear
.
clear
();
for
(
auto
&
element
:
elements
)
{
if
(
!
element
->
dirty
||
!
element
->
updateOverlaps
)
continue
;
Rect
bounds
=
element
->
getBounds
(
false
);
for
(
auto
&
elementClip
:
elements
)
{
if
(
elementClip
->
dirty
)
continue
;
if
(
!
elementClip
->
getBounds
(
false
).
overlaps
(
bounds
))
continue
;
elementClip
->
dirty
=
1
;
//SDL_Log("RenderDispatcher::dispatchNoRecurse collide %i %i", (int)&element, (int)&elementClip);
}
}
for
(
auto
&
element
:
elements
)
{
if
(
!
element
->
dirty
)
continue
;
size_t
appendSize
=
element
->
getInstanceCount
();
...
...
@@ -66,9 +75,12 @@ bool RenderDispatcher::dispatchNoRecurse(const std::unordered_set<GUIElement*>&
size_t
appendSize
=
element
->
getInstanceCount
();
Span
<
Instance
>
newInstances
=
instances
.
appendGetEnd
(
appendSize
);
element
->
populateInstances
(
newInstances
);
if
(
element
->
updateOverlaps
)
for
(
size_t
i
=
0
;
i
<
appendSize
;
i
++
)
newInstances
[
i
].
depth
+=
element
->
depth
;
element
->
dirty
-=
1
;
instancesClear
.
append
(
InstanceDataFlat
{
element
->
getBounds
(
true
),
clearColor
(
RectU
)
element
->
getBounds
(
true
),
clearColor
});
}
if
(
instances
.
size
()
==
0
)
return
false
;
...
...
@@ -99,10 +111,10 @@ void RenderDispatcher::updateUniforms(SDL_Window* window, Vec2 offset) {
0
,
0
,
-
1
,
0
,
-
1
-
offset
.
x
*
wI
*
2.0f
,
1
+
offset
.
y
*
hI
*
2.0f
,
0
,
1
};
commonUniforms
.
projection
->
set
(
ortho
);
projection
.
set
(
ortho
);
timeMS
=
SDL_GetTicks
();
commonUniforms
.
time
->
value
=
(
uint32_t
)
timeMS
;
time
.
value
=
(
uint32_t
)
timeMS
;
}
bool
RenderDispatcher
::
handleMouse
(
const
std
::
unordered_set
<
GUIElement
*>&
elements
,
MouseButton
button
,
MouseInput
input
,
Vec2
pos
,
uint32_t
index
)
{
pos
=
Vec2
(
offset
.
x
+
pos
.
x
,
offset
.
y
+
pos
.
y
);
...
...
@@ -156,23 +168,27 @@ bool RenderDispatcher::handleWheel(const std::unordered_set<GUIElement*>& elemen
void
orderObjects
(
Instance
*
arr
,
size_t
n
)
{
for
(
size_t
i
=
0
;
i
<
n
;
i
++
)
if
(
arr
->
skip
)
arr
->
depth
=
-
1
;
// Step 1: Sort by depth only (stable sort to keep original order in equal depths)
// We do stable sort so relative order inside equal depth remains for grouping later
for
(
size_t
i
=
0
;
i
<
n
;
i
++
)
if
(
arr
->
skip
)
arr
->
depth
=
-
1
;
//Sort by depth
std
::
stable_sort
(
arr
,
arr
+
n
,
[](
const
Instance
&
a
,
const
Instance
&
b
)
{
return
a
.
depth
<
b
.
depth
;
});
// Step 2: Within equal depth groups, group by shader (stable sort again)
// we could optimise by switching the sort order each sort if the last sorts shader doesnt equal the first to ensure blocks of shaders remain connected
size_t
start
=
0
;
for
(
size_t
i
=
1
;
i
<=
n
;
i
++
)
{
if
(
i
==
n
||
arr
[
i
].
depth
!=
arr
[
start
].
depth
)
{
// Sort by shader inside [start, i)
std
::
stable_sort
(
arr
+
start
,
arr
+
i
,
[](
const
Instance
&
a
,
const
Instance
&
b
)
{
//Sort by shaders
for
(
size_t
iDepthStart
=
0
,
iDepthEnd
=
1
;
iDepthEnd
<=
n
;
iDepthEnd
++
)
{
if
(
iDepthEnd
==
n
||
arr
[
iDepthEnd
].
depth
!=
arr
[
iDepthStart
].
depth
)
{
std
::
stable_sort
(
arr
+
iDepthStart
,
arr
+
iDepthEnd
,
[](
const
Instance
&
a
,
const
Instance
&
b
)
{
return
a
.
shader
<
b
.
shader
;
});
start
=
i
;
//Sort by uniforms
for
(
size_t
iUniformStart
=
iDepthStart
,
iUniformEnd
=
iDepthStart
+
1
;
iUniformEnd
<
iDepthEnd
;
iUniformEnd
++
)
{
if
(
iUniformEnd
==
iDepthEnd
||
arr
[
iUniformEnd
].
uniforms
.
data
!=
arr
[
iUniformStart
].
uniforms
.
data
)
{
std
::
stable_sort
(
arr
+
iUniformStart
,
arr
+
iUniformEnd
,
[](
const
Instance
&
a
,
const
Instance
&
b
)
{
return
a
.
uniforms
.
data
<
b
.
uniforms
.
data
;
});
iUniformStart
=
iUniformEnd
;
}
}
iDepthStart
=
iDepthEnd
;
}
}
}
...
...
@@ -180,15 +196,21 @@ void RenderInstances(ObjectBuffer* obj, Span<Instance> data) {
orderObjects
(
data
.
data
,
data
.
size
());
size_t
matchStart
=
0
;
AShader
*
matchShader
=
data
[
0
].
shader
;
Span
<
Uniform
*>
matchUniforms
=
data
[
0
].
uniforms
;
size_t
maxBatch
=
matchShader
->
getInstanceSize
();
for
(
size_t
i
=
1
;
i
<
data
.
size
();
i
++
)
{
size_t
batchSize
=
i
-
matchStart
;
if
(
data
[
i
].
depth
==
-
1
)
return
;
if
(
data
[
i
].
shader
==
matchShader
&&
batchSize
!=
maxBatch
)
continue
;
Instance
&
inst
=
data
[
i
];
if
(
inst
.
depth
==
-
1
)
return
;
if
(
batchSize
!=
maxBatch
&&
inst
.
shader
==
matchShader
&&
inst
.
uniforms
.
data
==
matchUniforms
.
data
)
continue
;
assert
(
matchShader
);
if
(
matchUniforms
.
size
()
!=
0
)
matchShader
->
setUniforms
(
matchUniforms
);
matchShader
->
renderInstances
(
obj
,
Span
<
Instance
>
(
data
.
data
+
matchStart
,
i
-
matchStart
));
matchStart
=
i
;
matchShader
=
data
[
i
].
shader
;
matchShader
=
inst
.
shader
;
matchUniforms
=
inst
.
uniforms
;
maxBatch
=
matchShader
->
getInstanceSize
();
}
if
(
data
.
size
()
-
matchStart
==
0
)
return
;
...
...
SDLTest/src/ShaderHelper.cpp
View file @
b85ec35b
...
...
@@ -78,10 +78,10 @@ GLuint LoadShaderProgramFile(const char* vsFile, const char* fsFile) {
return
LoadShaderProgramMemory
(
vsSrc
.
get
(),
fsSrc
.
get
());
}
#include
<cassert>
void
CheckGLError
(
const
char
*
function
)
{
GLenum
err
;
while
((
err
=
glGetError
())
!=
GL_NO_ERROR
)
{
std
::
cerr
<<
"OpenGL Error in "
<<
function
<<
": ["
<<
err
<<
"] "
<<
(
err
)
<<
std
::
endl
;
//glewGetErrorString
}
}
\ No newline at end of file
SDLTest/src/Shaders.cpp
View file @
b85ec35b
...
...
@@ -6,14 +6,44 @@ void AShader::setProgram(GLuint program) {
onSetProgram
();
}
ObjectBuffer
::
Shader
ObjectBuffer
::
getShaderBuffers
(
AShader
*
shader
)
{
void
ObjectBuffer
::
Shader
::
resizeBuffer
(
AShader
*
shader
,
size_t
newBufferSize
)
{
size_t
instanceSize
=
shader
->
getInstanceSize
();
if
(
newBufferSize
==
bufferSize
)
return
;
glBindBuffer
(
GL_ARRAY_BUFFER
,
instanceVBO
);
glBufferData
(
GL_ARRAY_BUFFER
,
instanceSize
*
newBufferSize
,
NULL
,
GL_STREAM_DRAW
);
bufferSize
=
newBufferSize
;
}
size_t
nextPow2
(
size_t
v
)
{
if
(
v
==
0
)
return
1
;
v
--
;
v
|=
v
>>
1
;
v
|=
v
>>
2
;
v
|=
v
>>
4
;
v
|=
v
>>
8
;
v
|=
v
>>
16
;
#if SIZE_MAX > 0xffffffff
v
|=
v
>>
32
;
#endif
v
++
;
return
v
;
}
void
ObjectBuffer
::
Shader
::
upscaleBuffer
(
AShader
*
shader
,
size_t
minBufferSize
)
{
size_t
instanceSize
=
shader
->
getInstanceSize
();
if
(
minBufferSize
<=
bufferSize
)
return
;
size_t
newBufferSize
=
nextPow2
(
instanceSize
*
minBufferSize
);
glBindBuffer
(
GL_ARRAY_BUFFER
,
instanceVBO
);
glBufferData
(
GL_ARRAY_BUFFER
,
newBufferSize
,
NULL
,
GL_STREAM_DRAW
);
bufferSize
=
newBufferSize
;
}
ObjectBuffer
::
Shader
*
ObjectBuffer
::
getShaderBuffers
(
AShader
*
shader
)
{
if
(
lastFound
.
first
==
shader
->
program
)
return
lastFound
.
second
;
auto
found
=
shaders
.
find
(
shader
->
program
);
if
(
found
!=
shaders
.
end
())
{
lastFound
=
std
::
pair
<
GLuint
,
Shader
>
(
shader
->
program
,
found
->
second
);
return
found
->
second
;
lastFound
=
std
::
pair
<
GLuint
,
Shader
*
>
(
shader
->
program
,
&
found
->
second
);
return
&
found
->
second
;
}
Shader
newShader
;
...
...
@@ -23,11 +53,10 @@ ObjectBuffer::Shader ObjectBuffer::getShaderBuffers(AShader* shader) {
constructVBOAttribs
(
VBO
);
size_t
instanceMaxCount
=
shader
->
getInstanceMaxCount
();
size_t
instanceSize
=
shader
->
getInstanceSize
();
glGenBuffers
(
1
,
&
newShader
.
instanceVBO
);
glBindBuffer
(
GL_ARRAY_BUFFER
,
newShader
.
instanceVBO
);
glBufferData
(
GL_ARRAY_BUFFER
,
instanceSize
*
instanceMaxCount
,
NULL
,
GL_STREAM_DRAW
);
glBufferData
(
GL_ARRAY_BUFFER
,
0
,
NULL
,
GL_STREAM_DRAW
);
for
(
auto
&
field
:
shader
->
fields
)
{
if
(
field
.
varying
)
...
...
@@ -40,9 +69,9 @@ ObjectBuffer::Shader ObjectBuffer::getShaderBuffers(AShader* shader) {
glBindVertexArray
(
0
);
lastFound
=
std
::
pair
<
GLuint
,
Shader
>
(
shader
->
program
,
newShader
);
shaders
.
insert
(
std
::
pair
<
GLuint
,
Shader
>
(
shader
->
program
,
new
Shader
)
);
return
new
Shader
;
auto
newInsert
=
shaders
.
insert
(
std
::
pair
<
GLuint
,
Shader
>
(
shader
->
program
,
newShader
)
)
;
lastFound
=
std
::
pair
<
GLuint
,
Shader
*
>
(
shader
->
program
,
&
new
Insert
.
first
->
second
);
return
&
new
Insert
.
first
->
second
;
}
...
...
SDLTest/src/SliderElement.cpp
View file @
b85ec35b
...
...
@@ -17,9 +17,9 @@ void SliderElement::populateInstances(Span<Instance> buffer) {
Distance
limitInverse
=
(
Distance
)(
position
.
w
*
(
limitValue
/
maxValue
));
Distance
stepPixel
=
(
Distance
)(
position
.
w
/
maxValue
);
background
.
rect
=
position
;
background
.
rect
=
(
RectU
)
position
;
background
.
color
=
theme
.
background
[
2
];
backgroundLimit
.
rect
=
position
;
backgroundLimit
.
rect
=
(
RectU
)
position
;
backgroundLimit
.
color
=
theme
.
background
[
1
];
backgroundLimit
.
rect
.
x
+=
limitInverse
;
backgroundLimit
.
rect
.
w
-=
limitInverse
;
...
...
@@ -27,19 +27,19 @@ void SliderElement::populateInstances(Span<Instance> buffer) {
if
(
fillValue
)
{
instances
[
instanceBackgrouncValue
].
skip
=
false
;
backgroundValue
.
color
=
theme
.
statusArr
[
inputState
];
backgroundValue
.
rect
=
position
;
backgroundValue
.
rect
=
(
RectU
)
position
;
backgroundValue
.
rect
.
w
=
(
Distance
)(
position
.
w
*
(
value
/
maxValue
));
}
else
instances
[
instanceBackgrouncValue
].
skip
=
true
;
lines
.
rect
=
position
;
lines
.
rect
=
(
RectU
)
position
;
lines
.
color
=
theme
.
background
[
0
];
lines
.
color
.
a
=
128
;
lines
.
distance
=
Vec2
(
stepPixel
,
0
);
lines
.
size
=
1
;
lines
.
offset
=
0
;
handle
.
rect
=
calculateHandleBounds
();
handle
.
rect
=
(
RectU
)
calculateHandleBounds
();
handle
.
color
=
theme
.
interactableArr
[
inputState
];
buffer
.
copyFrom
(
instances
);
...
...
SDLTest/src/SliderPrecisionElement.cpp
View file @
b85ec35b
...
...
@@ -20,10 +20,10 @@ void SliderPrecisionElement::populateInstances(Span<Instance> buffer) {
Distance
stepPixel
=
(
Distance
)(
position
.
w
/
linkedSlider
->
maxValue
*
scale
);
float
valueFract
=
linkedSlider
->
value
-
std
::
floorf
(
linkedSlider
->
value
);
background
.
rect
=
position
;
background
.
rect
=
(
RectU
)
position
;
background
.
color
=
theme
.
background
[
2
];
backgroundLimit
.
rect
=
position
;
backgroundLimit
.
rect
=
(
RectU
)
position
;
backgroundLimit
.
color
=
theme
.
background
[
1
];
float
limitRelative
=
linkedSlider
->
limitValue
-
linkedSlider
->
value
;
Position
limitRelativePixel
=
(
position
.
w
/
2
)
-
(
Position
)(
limitRelative
*
position
.
w
*
scale
/
linkedSlider
->
maxValue
);
...
...
@@ -35,19 +35,19 @@ void SliderPrecisionElement::populateInstances(Span<Instance> buffer) {
if
(
linkedSlider
->
fillValue
)
{
instances
[
instanceBackgrouncValue
].
skip
=
false
;
backgroundValue
.
color
=
theme
.
statusArr
[
inputState
];
backgroundValue
.
rect
=
position
;
backgroundValue
.
rect
=
(
RectU
)
position
;
backgroundValue
.
rect
.
w
=
background
.
rect
.
w
/
2
;
}
else
instances
[
instanceBackgrouncValue
].
skip
=
true
;
lines
.
rect
=
position
;
lines
.
rect
=
(
RectU
)
position
;
lines
.
color
=
theme
.
background
[
0
];
lines
.
color
.
a
=
128
;
lines
.
distance
=
Vec2
(
stepPixel
,
0
);
lines
.
size
=
1
;
lines
.
offset
=
(
uint16_t
)(
valueFract
*
stepPixel
);
handle
.
rect
=
calculateHandleBounds
();
handle
.
rect
=
(
RectU
)
calculateHandleBounds
();
handle
.
color
=
theme
.
interactableArr
[
inputState
];
buffer
.
copyFrom
(
instances
);
...
...
SDLTest/src/SliderRangeElement.cpp
View file @
b85ec35b
...
...
@@ -23,30 +23,30 @@ void SliderRangeElement::populateInstances(Span<Instance> buffer) {
Distance
limitInverse
=
(
Distance
)(
position
.
w
*
(
linkedSlider
->
limitValue
/
linkedSlider
->
maxValue
));
Distance
stepPixel
=
(
Distance
)(
position
.
w
/
linkedSlider
->
maxValue
);
background
.
rect
=
position
;
background
.
rect
=
(
RectU
)
position
;
background
.
color
=
theme
.
background
[
2
];
backgroundLimit
.
rect
=
position
;
backgroundLimit
.
rect
=
(
RectU
)
position
;
backgroundLimit
.
color
=
theme
.
background
[
1
];
backgroundLimit
.
rect
.
x
+=
limitInverse
;
backgroundLimit
.
rect
.
w
-=
limitInverse
;
backgroundValue
.
color
=
theme
.
statusArr
[
inputStateMin
>
inputStateMax
?
inputStateMin
:
inputStateMax
];
backgroundValue
.
rect
=
position
;
backgroundValue
.
rect
=
(
RectU
)
position
;
Distance
valueMinPix
=
(
Distance
)(
position
.
w
*
(
valueMin
/
linkedSlider
->
maxValue
));
Distance
valueMaxPix
=
(
Distance
)(
position
.
w
*
(
valueMax
/
linkedSlider
->
maxValue
));
backgroundValue
.
rect
.
x
=
position
.
x
+
valueMinPix
;
backgroundValue
.
rect
.
w
=
valueMaxPix
-
valueMinPix
;
lines
.
rect
=
position
;
lines
.
rect
=
(
RectU
)
position
;
lines
.
color
=
theme
.
background
[
0
];
lines
.
color
.
a
=
128
;
lines
.
distance
=
Vec2
(
stepPixel
,
0
);
lines
.
size
=
1
;
lines
.
offset
=
0
;
handleMin
.
rect
=
calculateHandleBounds
(
false
);
handleMin
.
rect
=
(
RectU
)
calculateHandleBounds
(
false
);
handleMin
.
color
=
theme
.
interactableArr
[
inputStateMin
];
handleMax
.
rect
=
calculateHandleBounds
(
true
);
handleMax
.
rect
=
(
RectU
)
calculateHandleBounds
(
true
);
handleMax
.
color
=
theme
.
interactableArr
[
inputStateMax
];
buffer
.
copyFrom
(
instances
);
...
...
@@ -130,7 +130,7 @@ bool SliderRangeElement::handleMouse(MouseButton button, MouseInput state, Vec2
//SDL_Log("Mouse x %i y %i. State %i, inputState %i", pos.x, pos.y, (int)state, (int)inputState);
if
(
!
linkedSlider
)
return
false
;
dirty
=
DIRTY
;
bool
retMin
=
handleMouseMin
(
button
,
state
,
pos
,
index
);
bool
retMin
=
inputStateMax
==
ACTIVE
?
false
:
handleMouseMin
(
button
,
state
,
pos
,
index
);
bool
retMax
=
handleMouseMax
(
button
,
state
,
pos
,
index
);
return
retMin
||
retMax
;
}
...
...
SDLTest/src/TextElement.cpp
View file @
b85ec35b
...
...
@@ -15,6 +15,7 @@ void TextElement::populateInstances(Span<Instance> buffer) {
assert
(
font
);
size_t
textSize
=
text
.
size
();
if
(
textChange
||
atlas
->
getLastUpdateID
()
!=
atlasUpdateID
)
{
dirty
=
DIRTY
;
if
(
atlas
==
nullptr
||
atlas
->
getFontSize
()
!=
fontSize
)
atlas
=
font
->
getAtlas
(
fontSize
);
...
...
@@ -22,15 +23,6 @@ void TextElement::populateInstances(Span<Instance> buffer) {
instances
.
resize
(
textSize
);
atlas
->
generateInstances
(
position
,
text
,
Span
<
Instance
>
(
instances
));
SDL_Log
(
"TextElement::populateInstances [%i]:"
,
(
int
)
textSize
);
for
(
Instance
&
instance
:
instances
)
{
InstanceDataGlyph
*
data
=
instance
.
data
.
pointerAs
<
InstanceDataGlyph
>
();
std
::
cout
<<
" rect "
;
data
->
rect
.
debugPrint
();
//std::cout << ", \tatlas ";
//data->atlas.debugPrint();
std
::
cout
<<
std
::
endl
;
}
atlasUpdateID
=
atlas
->
getLastUpdateID
();
}
assert
(
instances
.
size
()
==
textSize
);
...
...
SDLTest/src/Types.cpp
View file @
b85ec35b
...
...
@@ -2,74 +2,8 @@
#include
<cstring>
#include
<cstdint>
#include
<cassert>
#include
<iostream>
Rect
Rect
::
flipAxies
()
const
{
return
Rect
{
x
,
y
,
h
,
w
};
}
bool
Rect
::
inside
(
Vec2
point
)
const
{
return
x
<=
point
.
x
&&
x
+
w
>=
point
.
x
&&
y
<=
point
.
y
&&
y
+
h
>=
point
.
y
;
}
Rect
Rect
::
clip
(
const
Rect
&
that
)
const
{
Rect
newRect
=
*
this
;
int32_t
diff
;
diff
=
that
.
x
-
newRect
.
x
;
if
(
diff
>
newRect
.
w
)
return
Rect
();
if
(
diff
>
0
)
{
newRect
.
x
+=
diff
;
newRect
.
w
-=
diff
;
}
diff
=
(
newRect
.
x
+
newRect
.
w
)
-
(
that
.
x
+
that
.
w
);
if
(
diff
>
newRect
.
w
)
return
Rect
();
if
(
diff
>
0
)
{
newRect
.
w
-=
diff
;
}
diff
=
that
.
y
-
newRect
.
y
;
if
(
diff
>
newRect
.
h
)
return
Rect
();
if
(
diff
>
0
)
{
newRect
.
y
+=
diff
;
newRect
.
h
-=
diff
;
}
diff
=
(
newRect
.
y
+
newRect
.
h
)
-
(
that
.
y
+
that
.
h
);
if
(
diff
>
newRect
.
h
)
return
Rect
();
if
(
diff
>
0
)
{
newRect
.
y
-=
diff
;
}
return
newRect
;
}
Rect
Rect
::
combine
(
const
Rect
&
that
)
const
{
Rect
newRect
=
*
this
;
int32_t
diff
;
diff
=
that
.
x
-
newRect
.
x
;
if
(
diff
>
0
)
{
newRect
.
x
-=
diff
;
newRect
.
w
+=
diff
;
}
diff
=
(
newRect
.
x
+
newRect
.
w
)
-
(
that
.
x
+
that
.
w
);
if
(
diff
>
0
)
{
newRect
.
w
+=
diff
;
}
diff
=
that
.
y
-
newRect
.
y
;
if
(
diff
>
0
)
{
newRect
.
y
-=
diff
;
newRect
.
h
+=
diff
;
}
diff
=
(
newRect
.
y
+
newRect
.
h
)
-
(
that
.
y
+
that
.
h
);
if
(
diff
>
0
)
{
newRect
.
y
+=
diff
;
}
return
newRect
;
}
void
Rect
::
debugPrint
()
const
{
std
::
cout
<<
"Rect("
<<
x
<<
", "
<<
y
<<
", "
<<
w
<<
", "
<<
h
<<
")"
;
}
Vec2
Vec2
::
flipAxies
()
{
return
Vec2
{
y
,
x
};
...
...
SDLTest/src/Uniform.cpp
View file @
b85ec35b
...
...
@@ -68,7 +68,7 @@ constexpr const GLenum textureLocs[] = {
GL_TEXTURE4
,
GL_TEXTURE5
,
GL_TEXTURE6
,
GL_TEXTURE7
};
void
UniformTexture8
::
applyLoc
(
GLint
loc
)
{
assert
(
tex
!
=
GL_NONE
);
if
(
tex
=
=
GL_NONE
)
return
;
glActiveTexture
(
textureLocs
[
index
]);
glBindTexture
(
GL_TEXTURE_2D
,
tex
);
glUniform1i
(
loc
,
index
);
...
...
@@ -77,19 +77,21 @@ void UniformTexture8::set(const std::vector<uint8_t>& data, uint32_t width, uint
assert
(
data
.
size
()
==
(
width
*
height
));
if
(
tex
==
GL_NONE
)
{
glGenTextures
(
1
,
&
tex
);
CheckGLError
(
"glBindTexture"
);
CheckGLError
(
"glGenTextures"
);
glBindTexture
(
GL_TEXTURE_2D
,
tex
);
glTexParameteri
(
GL_TEXTURE_2D
,
GL_TEXTURE_WRAP_S
,
GL_CLAMP_TO_EDGE
);
glTexParameteri
(
GL_TEXTURE_2D
,
GL_TEXTURE_WRAP_T
,
GL_CLAMP_TO_EDGE
);
glTexParameteri
(
GL_TEXTURE_2D
,
GL_TEXTURE_MIN_FILTER
,
GL_LINEAR
);
glTexParameteri
(
GL_TEXTURE_2D
,
GL_TEXTURE_MAG_FILTER
,
GL_LINEAR
);
}
glBindTexture
(
GL_TEXTURE_2D
,
tex
);
CheckGLError
(
"glBindTexture"
);
if
(
width
==
this
->
width
&&
height
==
this
->
height
)
if
(
width
==
this
->
width
&&
height
==
this
->
height
)
{
glTexSubImage2D
(
GL_TEXTURE_2D
,
0
,
0
,
0
,
width
,
height
,
GL_RED
,
GL_UNSIGNED_BYTE
,
data
.
data
());
else
{
this
->
width
=
width
;
this
->
height
=
height
;
glTexImage2D
(
GL_TEXTURE_2D
,
0
,
GL_RED
,
width
,
height
,
0
,
GL_RED
,
GL_UNSIGNED_BYTE
,
data
.
data
()
);
CheckGLError
(
"glTexSubImage2D"
);
}
else
{
glTexImage2D
(
GL_TEXTURE_2D
,
0
,
GL_R8
,
width
,
height
,
0
,
GL_RED
,
GL_UNSIGNED_BYTE
,
data
.
data
())
;
CheckGLError
(
"glTexImage2D"
);
}
}
Prev
1
2
Next