Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Johannes Braun
glare
Commits
969f57dd
Commit
969f57dd
authored
Sep 15, 2017
by
Johannes Braun
Browse files
Several fixes
parent
3c5c9e1a
Changes
24
Hide whitespace changes
Inline
Side-by-side
assets/imgui/config.ini
View file @
969f57dd
...
...
@@ -4,12 +4,12 @@ Size=353,64
Collapsed
=
0
[Scene]
Pos
=
0,72
Pos
=
-2,66
Size
=
352,837
Collapsed
=
0
[Settings]
Pos
=
112
8,-2
Pos
=
112
5,0
Size
=
311,899
Collapsed
=
0
assets/preferences/linespace_default.xml
View file @
969f57dd
<linespace
version=
"1.0"
>
<item
name=
"subdivisions"
value=
"
1
0"
/>
<item
name=
"grid-subdivisions"
value=
"
10
"
/>
<item
name=
"subdivisions"
value=
"
2
0"
/>
<item
name=
"grid-subdivisions"
value=
"
2
"
/>
<item
name=
"radial-subdivision"
value=
"50"
/>
<item
name=
"generator"
value=
"gpu"
/>
</linespace>
assets/shaders/pathtracer/data/mesh_datastructure.glsl
View file @
969f57dd
...
...
@@ -73,6 +73,7 @@ Mesh getMesh(const in Scene scene, int index)
bool
traverseObjects
(
const
in
Scene
scene
,
const
in
Ray
ray
,
const
in
bool
use_first
,
const
in
float
max_distance
,
inout
Hit
hit
,
inout
float
t_min
,
bool
force_bvh
=
false
)
{
hit
.
invalidate
();
if
(
!
use_global_bvh
)
{
float
current_t
=
t_min
;
...
...
@@ -119,7 +120,7 @@ bool traverseObjects(const in Scene scene, const in Ray ray, const in bool use_f
for
(;;)
{
int
ls_index
=
index
.
x
+
index
.
y
*
mesh
.
grid_linespace
.
grid_resolution
.
x
+
index
.
z
*
mesh
.
grid_linespace
.
grid_resolution
.
y
*
mesh
.
grid_linespace
.
grid_resolution
.
z
;
int
ls_index
=
index
.
x
+
index
.
y
*
mesh
.
grid_linespace
.
grid_resolution
.
x
+
index
.
z
*
mesh
.
grid_linespace
.
grid_resolution
.
x
*
mesh
.
grid_linespace
.
grid_resolution
.
y
;
int
axis
=
smallestAxis
(
tnext
);
...
...
assets/shaders/pathtracer/data/mesh_linespace.glsl
View file @
969f57dd
...
...
@@ -138,7 +138,7 @@ bool traverseLineSpace(const in Mesh mesh, int index, const in Ray local_ray, co
if
(
mesh
.
grid_linespace
.
linespaces
[
index
].
line_count
==
0
)
return
false
;
Ray
loc
=
local_ray
;
loc
.
origin
+=
0
.
05
f
*
loc
.
direction
;
loc
.
origin
+=
1e-4
f
*
loc
.
direction
;
if
(
!
loc
.
intersectsBounds
(
mesh
.
grid_linespace
.
linespaces
[
index
].
bounds
,
tmin
,
tmax
,
face_tmin
,
face_tmax
)
||
t_min
<=
tmin
||
tmin
>
max_distance
)
{
...
...
assets/shaders/pathtracer/generators/bvh/bvh_raygenerator.comp
View file @
969f57dd
...
...
@@ -10,9 +10,10 @@
layout(local_size_variable) in;
layout(rgba32f) uniform image2D
u_
render_target;
layout(rgba32f) uniform image2D render_target;
uniform int random_seed;
uniform bool use_linespace = false;
uniform bool random_subpixel = false;
uniform Scene scene;
layout(std430) buffer trace_buffer
...
...
@@ -20,20 +21,15 @@ layout(std430) buffer trace_buffer
Trace traces_data[];
};
uniform struct
{
bool u_random_subpixel; //defaults to false.
} settings;
void main()
{
ivec2 target_size =
u_
render_target.imageSize();
ivec2 target_size = render_target.imageSize();
if (!(int(gl_GlobalInvocationID.x) < target_size.x && int(gl_GlobalInvocationID.y) < target_size.y))
return;
int id = target_size.x * int(gl_GlobalInvocationID.y) + int(gl_GlobalInvocationID.x);
vec2 random =
settings.u_
random_subpixel ?
vec2(0, 0) :
rand2D(random_seed + id, target_size.x*target_size.y);
vec2 random = random_subpixel ? rand2D(random_seed + id, target_size.x*target_size.y)
: vec2(0, 0)
;
traces_data[id].ray = scene.camera.getRayFromPixel(vec2(gl_GlobalInvocationID.xy), random, vec2(target_size));
traces_data[id].hit.invalidate();
scene.nearestIntersection(traces_data[id].ray, traces_data[id].hit, !use_linespace);
...
...
assets/shaders/pathtracer/generators/gbuffer/depthtest.comp
View file @
969f57dd
...
...
@@ -6,7 +6,7 @@
#include <util/tracing/scene.glsl>
#include <util/math/random.glsl>
layout(rgba32f) uniform image2D
MS
u_gbuffer_texture_01;
layout(rgba32f) uniform image2D u_gbuffer_texture_01;
layout(rgba32f) uniform image2D u_render_target;
uniform int random_seed;
uniform int samples;
...
...
@@ -28,7 +28,7 @@ void main()
ivec2 target_size = u_render_target.imageSize();
vec2 random = rand2D(random_seed + int(id), target_size.x * target_size.y);
vec2 pixel = vec2(id%target_size.x, id/target_size.x) + random;
vec4 texel_01 = u_gbuffer_texture_01.imageLoad(ivec2(pixel)
, int(random.x * samples)
);
vec4 texel_01 = u_gbuffer_texture_01.imageLoad(ivec2(pixel));
traces_data[id].ray = scene.camera.getRayFromPixel(pixel, random, vec2(target_size));
traces_data[id].hit.invalidate();
...
...
assets/shaders/pathtracer/generators/gbuffer/gbuffer.geom
View file @
969f57dd
...
...
@@ -7,9 +7,9 @@ layout(triangle_strip, max_vertices = 3) out;
#include <util/scene/mesh.glsl>
#include <util/math/geometry.glsl>
#include <util/tracing/scene.glsl>
#include <pathtracer/buffers.glsl>
Scene
scene
;
uniform
mat4
u_mvp
;
uniform
uint
u_mesh_id
;
...
...
@@ -21,7 +21,7 @@ void main()
{
triangle_id
=
int
(
gl_in
[
0
].
gl_Position
.
x
);
Mesh
mesh
=
meshes
_data
[
u_mesh_id
];
Mesh
mesh
=
scene
.
meshes
[
u_mesh_id
];
Triangle
current
=
mesh
.
triangles
[
triangle_id
];
...
...
assets/shaders/pathtracer/pathtracer.comp
View file @
969f57dd
...
...
@@ -36,7 +36,6 @@ uniform int sampels_max = 80000;
uniform int samples_per_frame = 1;
layout(rgba32f) uniform image2D render_target;
layout(std430) buffer trace_buffer
{
Trace traces_data[];
...
...
@@ -76,20 +75,6 @@ struct Bounce
////
//////////////////////////////////////////////////////////////////////////
int iArray(const in int array[num_effects], int index)
{
for(int i=0; i<num_effects; ++i)
if(i==index)
return array[i];
}
int iArrayComp(const in int array1[num_effects], const in int array2[num_effects], int index)
{
for(int i=0; i<num_effects; ++i)
if(i==index)
return array1[i] < array2[i] ? 1 : (array1[i] > array2[i] ? -1 : 0);
}
subroutine uniform lightSample sampleLightRoutines[4];
LightData sampleLight(const in Light light, const in Vertex vertex, const in vec2 random_sample)
{
...
...
@@ -108,6 +93,13 @@ LightData sampleLight(const in Light light, const in Vertex vertex, const in vec
return result;
}
int iArrayComp(const in int array1[num_effects], const in int array2[num_effects], int index)
{
for(int i=0; i<num_effects; ++i)
if(i==index)
return array1[i] < array2[i] ? 1 : (array1[i] > array2[i] ? -1 : 0);
}
bool shouldUseBvh(const in Bounce bounce)
{
return (bounce.pdf_accumulation > (1-linespace_accuracy))
...
...
@@ -153,8 +145,6 @@ bool shade(inout Bounce bounce)
BSDFResult bsdf_result = material.computeBSDF(random_sample, vertex, bounce.ray);
bounce.path_distance += distance(bounce.ray.origin, vertex.position.xyz);
bool exceeds_bounces = false;
for(int i=0; i<num_effects; ++i)
{
...
...
@@ -166,6 +156,7 @@ bool shade(inout Bounce bounce)
}
}
bounce.path_distance += distance(bounce.ray.origin, vertex.position.xyz);
bounce.bsdf_id = int(bsdf_result.bsdf_id);
bounce.pdf_accumulation *= bsdf_result.probability_density;
bounce.ray = bsdf_result.generated_ray;
...
...
@@ -199,13 +190,6 @@ bool shade(inout Bounce bounce)
return true;
}
void trace(inout Bounce bounce)
{
//Invalidate before intersection test so that we don't have to conditionally invalidate afterwards
bounce.hit.invalidate();
scene.nearestIntersection(bounce.ray, bounce.hit, shouldUseBvh(bounce));
}
void main()
{
ivec2 target_size = render_target.imageSize();
...
...
@@ -215,12 +199,9 @@ void main()
if (!(int(gl_GlobalInvocationID.x) < target_size.x && int(gl_GlobalInvocationID.y) < target_size.y))
return;
// Get the trace generated by the external primary-ray-generator and initialize the Bounce struct.
Trace current = traces_data[id];
Bounce bounce;
bounce.hit =
current
.hit;
bounce.ray =
current
.ray;
bounce.hit =
traces_data[id]
.hit;
bounce.ray =
traces_data[id]
.ray;
bounce.path_distance = 0;
bounce.pdf_accumulation = 1.f;
bounce.bounce_amount = int[num_effects](0,0,0,0);
...
...
@@ -232,7 +213,7 @@ void main()
// continue with first-trace-then-shade until either shade returns false (not hitting something or constribution too low)
// or we exceed the global bounce limit.
for (bounce.count = 1; bounce.shade() && bounce.count <= bounce_count; ++bounce.count) {
bounce.
t
ra
ce(
);
scene.nearestIntersection(
bounce.ra
y, bounce.hit, shouldUseBvh(bounce)
);
}
ivec2 pixel = ivec2(bounce.ray.px, bounce.ray.py);
...
...
src/executables/pathtracing/main.cpp
View file @
969f57dd
...
...
@@ -529,7 +529,7 @@ void drawSettingsWindow()
static
auto
effectBounces
=
[](
const
std
::
string
&
label
,
raytrace
::
Effect
effect
)
{
if
(
int
val
=
pathtracer
->
getBounceThreshold
(
effect
);
ImGui
::
DragInt
(
label
.
c_str
(),
&
val
,
0.1
f
,
0
,
255
))
pathtracer
->
setBounceThreshold
(
effect
,
static_cast
<
uint8_t
>
(
val
)
)
;
pathtracer
->
setBounceThreshold
(
effect
,
val
);
};
effectBounces
(
"Diffusion"
,
raytrace
::
Effect
::
eDiffusion
);
...
...
@@ -577,7 +577,7 @@ void drawSettingsWindow()
static
auto
bounceControl
=
[](
const
std
::
string
&
label
,
raytrace
::
Effect
effect
)
{
if
(
int
val
=
pathtracer
->
getLinespaceBounces
(
effect
);
ImGui
::
DragInt
(
label
.
c_str
(),
&
val
,
0.1
f
,
0
,
pathtracer
->
getLinespaceBounces
(
effect
)))
pathtracer
->
setLinespaceBounces
(
effect
,
static_cast
<
uint8_t
>
(
val
)
)
;
pathtracer
->
setLinespaceBounces
(
effect
,
val
);
};
bounceControl
(
"Diffusion"
,
raytrace
::
Effect
::
eDiffusion
);
...
...
src/libraries/raytrace/data/collector_units/camera.cpp
View file @
969f57dd
...
...
@@ -12,15 +12,6 @@
namespace
glare
::
raytrace
{
CameraCollector
::
CameraCollector
()
{
}
CameraCollector
::~
CameraCollector
()
{
}
void
CameraCollector
::
clear
(
const
math
::
Flags
&
flags
)
{
...
...
@@ -50,9 +41,9 @@ namespace glare::raytrace
}
void
CameraCollector
::
apply
(
core
::
Program
&
program
)
void
CameraCollector
::
apply
(
core
::
Program
&
program
,
const
std
::
string
&
uniform_name
)
{
if
(
!
m_cameras
.
empty
())
program
.
uniformStruct
(
"scene
.camera"
,
m_cameras
[
m_active_camera
]);
program
.
uniformStruct
(
uniform_name
+
"
.camera"
,
m_cameras
[
m_active_camera
]);
}
}
src/libraries/raytrace/data/collector_units/camera.h
View file @
969f57dd
...
...
@@ -16,19 +16,17 @@ namespace glare::raytrace
class
CameraCollector
:
public
CollectorUnit
{
public:
CameraCollector
();
CameraCollector
()
=
default
;
CameraCollector
(
CameraCollector
&
other
)
=
default
;
CameraCollector
(
CameraCollector
&&
other
)
=
default
;
CameraCollector
&
operator
=
(
CameraCollector
&
other
)
=
default
;
CameraCollector
&
operator
=
(
CameraCollector
&&
other
)
=
default
;
~
CameraCollector
()
override
;
void
clear
(
const
math
::
Flags
&
flags
)
override
;
void
collect
(
const
math
::
Flags
&
flags
,
const
core
::
SceneNode
&
node
)
override
;
void
build
(
const
math
::
Flags
&
flags
)
override
;
void
apply
(
core
::
Program
&
program
)
override
;
void
apply
(
core
::
Program
&
program
,
const
std
::
string
&
uniform_name
)
override
;
private:
unsigned
m_active_camera
=
0
;
...
...
src/libraries/raytrace/data/collector_units/light.cpp
View file @
969f57dd
...
...
@@ -11,9 +11,6 @@
namespace
glare
::
raytrace
{
LightCollector
::
LightCollector
()
{}
LightCollector
::~
LightCollector
()
{}
void
LightCollector
::
clear
(
const
math
::
Flags
&
flags
)
{
if
(
flags
&
DirtyFlags
::
eLight
)
...
...
@@ -39,9 +36,9 @@ namespace glare::raytrace
}
}
void
LightCollector
::
apply
(
core
::
Program
&
program
)
void
LightCollector
::
apply
(
core
::
Program
&
program
,
const
std
::
string
&
uniform_name
)
{
program
.
uniform
(
"scene
.lights"
,
m_lights
.
empty
()
?
0
:
m_light_buffer
.
makeResident
(
gl
::
Access
::
eReadOnly
));
program
.
uniform
(
"scene
.num_lights"
,
static_cast
<
int
>
(
m_lights
.
size
()));
program
.
uniform
(
uniform_name
+
"
.lights"
,
m_lights
.
empty
()
?
0
:
m_light_buffer
.
makeResident
(
gl
::
Access
::
eReadOnly
));
program
.
uniform
(
uniform_name
+
"
.num_lights"
,
static_cast
<
int
>
(
m_lights
.
size
()));
}
}
\ No newline at end of file
src/libraries/raytrace/data/collector_units/light.h
View file @
969f57dd
...
...
@@ -17,19 +17,17 @@ namespace glare::raytrace
class
LightCollector
:
public
CollectorUnit
{
public:
LightCollector
();
LightCollector
()
=
default
;
LightCollector
(
LightCollector
&
other
)
=
default
;
LightCollector
(
LightCollector
&&
other
)
=
default
;
LightCollector
&
operator
=
(
LightCollector
&
other
)
=
default
;
LightCollector
&
operator
=
(
LightCollector
&&
other
)
=
default
;
~
LightCollector
()
override
;
void
clear
(
const
math
::
Flags
&
flags
)
override
;
void
collect
(
const
math
::
Flags
&
flags
,
const
core
::
SceneNode
&
node
)
override
;
void
build
(
const
math
::
Flags
&
flags
)
override
;
void
apply
(
core
::
Program
&
program
)
override
;
void
apply
(
core
::
Program
&
program
,
const
std
::
string
&
uniform_name
)
override
;
private:
core
::
Buffer
m_light_buffer
;
...
...
src/libraries/raytrace/data/collector_units/mesh.cpp
View file @
969f57dd
...
...
@@ -79,12 +79,12 @@ namespace glare::raytrace
return
m_use_bvh
;
}
void
MeshCollector
::
apply
(
core
::
Program
&
program
)
void
MeshCollector
::
apply
(
core
::
Program
&
program
,
const
std
::
string
&
uniform_name
)
{
program
.
uniform
(
"scene
.meshes"
,
m_meshes
.
empty
()
?
0
:
m_mesh_buffer
.
makeResident
(
gl
::
Access
::
eReadOnly
));
program
.
uniform
(
"scene
.bvh_nodes"
,
m_global_bvh
.
nodes
().
empty
()
?
0
:
m_global_bvh
.
buffer
().
makeResident
(
gl
::
Access
::
eReadOnly
));
program
.
uniform
(
"scene
.num_meshes"
,
static_cast
<
int
>
(
m_meshes
.
size
()));
program
.
uniform
(
"scene
.global_bvh"
,
m_use_bvh
);
program
.
uniform
(
uniform_name
+
"
.meshes"
,
m_meshes
.
empty
()
?
0
:
m_mesh_buffer
.
makeResident
(
gl
::
Access
::
eReadOnly
));
program
.
uniform
(
uniform_name
+
"
.bvh_nodes"
,
m_global_bvh
.
nodes
().
empty
()
?
0
:
m_global_bvh
.
buffer
().
makeResident
(
gl
::
Access
::
eReadOnly
));
program
.
uniform
(
uniform_name
+
"
.num_meshes"
,
static_cast
<
int
>
(
m_meshes
.
size
()));
program
.
uniform
(
uniform_name
+
"
.global_bvh"
,
m_use_bvh
);
}
void
MeshCollector
::
collectMeshRenderer
(
std
::
shared_ptr
<
core
::
MeshDrawable
>
mesh_renderer
)
...
...
@@ -157,7 +157,7 @@ namespace glare::raytrace
size_t
id
=
mesh_ids
[
i
];
m_id_mapping
[
id
]
=
i
;
const
auto
&
collector
=
m_local_collectors
[
id
];
m_meshes
[
i
]
=
collector
.
collector
->
makeMesh
(
m_material_buffer
.
makeResident
(
gl
::
Access
::
eReadOnly
)
+
static_cast
<
uint64_t
>
(
m_material_filter
[
collector
.
collector
->
materialID
()]),
collector
.
transform
);
m_meshes
[
i
]
=
collector
.
collector
->
makeMesh
(
m_material_buffer
.
makeResident
(
gl
::
Access
::
eReadOnly
)
+
sizeof
(
Material
)
*
static_cast
<
uint64_t
>
(
m_material_filter
[
collector
.
collector
->
materialID
()]),
collector
.
transform
);
m_meshes
[
i
].
id
=
i
;
mesh_ids
[
i
]
=
i
;
}
...
...
src/libraries/raytrace/data/collector_units/mesh.h
View file @
969f57dd
...
...
@@ -24,13 +24,12 @@ namespace glare::raytrace
MeshCollector
(
MeshCollector
&&
other
)
=
default
;
MeshCollector
&
operator
=
(
MeshCollector
&
other
)
=
default
;
MeshCollector
&
operator
=
(
MeshCollector
&&
other
)
=
default
;
~
MeshCollector
()
override
=
default
;
void
clear
(
const
math
::
Flags
&
flags
)
override
;
void
collect
(
const
math
::
Flags
&
flags
,
const
core
::
SceneNode
&
node
)
override
;
void
build
(
const
math
::
Flags
&
flags
)
override
;
void
apply
(
core
::
Program
&
program
)
override
;
void
apply
(
core
::
Program
&
program
,
const
std
::
string
&
uniform_name
)
override
;
const
std
::
map
<
size_t
,
InstancedCollector
>&
localCollectors
()
const
;
const
std
::
map
<
size_t
,
size_t
>&
idMapping
()
const
;
...
...
src/libraries/raytrace/data/collector_units/skybox.cpp
View file @
969f57dd
...
...
@@ -10,9 +10,6 @@
namespace
glare
::
raytrace
{
SkyboxCollector
::
SkyboxCollector
()
{}
SkyboxCollector
::~
SkyboxCollector
()
{}
void
SkyboxCollector
::
collect
(
const
math
::
Flags
&
flags
,
const
core
::
SceneNode
&
node
)
{
if
(
flags
&
DirtyFlags
::
eSkybox
)
...
...
@@ -23,16 +20,16 @@ namespace glare::raytrace
}
}
void
SkyboxCollector
::
apply
(
core
::
Program
&
program
)
void
SkyboxCollector
::
apply
(
core
::
Program
&
program
,
const
std
::
string
&
uniform_name
)
{
if
(
m_skybox
)
{
program
.
uniformStruct
(
"scene
.environment"
,
*
m_skybox
);
program
.
uniformStruct
(
uniform_name
+
"
.environment"
,
*
m_skybox
);
}
else
{
program
.
uniform
(
"scene
.environment.color"
,
glm
::
vec4
(
0.7
f
,
0.9
f
,
0.97
f
,
1
));
program
.
uniform
(
"scene
.environment.has_cubemap"
,
0
);
program
.
uniform
(
uniform_name
+
"
.environment.color"
,
glm
::
vec4
(
0.7
f
,
0.9
f
,
0.97
f
,
1
));
program
.
uniform
(
uniform_name
+
"
.environment.has_cubemap"
,
0
);
}
}
}
\ No newline at end of file
src/libraries/raytrace/data/collector_units/skybox.h
View file @
969f57dd
...
...
@@ -16,18 +16,16 @@ namespace glare::raytrace
class
SkyboxCollector
:
public
CollectorUnit
{
public:
SkyboxCollector
();
SkyboxCollector
()
=
default
;
SkyboxCollector
(
SkyboxCollector
&
other
)
=
default
;
SkyboxCollector
(
SkyboxCollector
&&
other
)
=
default
;
SkyboxCollector
&
operator
=
(
SkyboxCollector
&
other
)
=
default
;
SkyboxCollector
&
operator
=
(
SkyboxCollector
&&
other
)
=
default
;
~
SkyboxCollector
()
override
;
void
clear
(
const
math
::
Flags
&
flags
)
override
{}
void
build
(
const
math
::
Flags
&
flags
)
override
{}
void
collect
(
const
math
::
Flags
&
flags
,
const
core
::
SceneNode
&
node
)
override
;
void
apply
(
core
::
Program
&
program
)
override
;
void
apply
(
core
::
Program
&
program
,
const
std
::
string
&
uniform_name
)
override
;
private:
std
::
shared_ptr
<
core
::
Skybox
>
m_skybox
;
...
...
src/libraries/raytrace/data/global_collector.cpp
View file @
969f57dd
...
...
@@ -104,12 +104,12 @@ namespace glare::raytrace
m_dirty_flags
.
clear
();
}
void
SceneCollector
::
apply
(
core
::
Program
&
program
)
void
SceneCollector
::
apply
(
core
::
Program
&
program
,
const
std
::
string
&
uniform_name
)
{
for
(
auto
&&
unit
:
m_units
)
{
// Here, we apply data to the ShaderProgram, which can mean things like attaching a buffer or setting a bunch of uniforms.
unit
.
second
->
apply
(
program
);
unit
.
second
->
apply
(
program
,
uniform_name
);
}
}
...
...
src/libraries/raytrace/data/global_collector.h
View file @
969f57dd
...
...
@@ -48,7 +48,7 @@ namespace glare::raytrace
bool
isActive
()
const
;
void
setActive
(
bool
active
);
void
apply
(
core
::
Program
&
program
);
void
apply
(
core
::
Program
&
program
,
const
std
::
string
&
uniform_name
);
template
<
typename
TUnit
>
const
TUnit
&
getUnit
(
std
::
string
name
)
const
...
...
src/libraries/raytrace/data/global_collector_unit.h
View file @
969f57dd
...
...
@@ -31,7 +31,7 @@ namespace glare::raytrace
virtual
void
collect
(
const
math
::
Flags
&
flags
,
const
core
::
SceneNode
&
node
)
=
0
;
virtual
void
build
(
const
math
::
Flags
&
flags
)
=
0
;
virtual
void
apply
(
core
::
Program
&
program
)
{};
virtual
void
apply
(
core
::
Program
&
program
,
const
std
::
string
&
uniform_name
)
{};
};
}
...
...
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment