Skip to content

Commit fbc4e5e

Browse files
committed
add shader-compiling infrastructure
1 parent 0ba4fdc commit fbc4e5e

1 file changed

Lines changed: 56 additions & 0 deletions

File tree

  • lib/PDL/Graphics/TriD

lib/PDL/Graphics/TriD/GL.pm

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,13 @@ use OpenGL::Modern qw(
163163
glGenBuffers_p glBindBuffer glDeleteBuffers_p glBufferData_c
164164
glGenTextures_p glBindTexture glDeleteTextures_p
165165
glTexImage2D_c glTexParameteri
166+
glCreateShader glDeleteShader glShaderSource_p glCompileShader
167+
glAttachShader glDetachShader
168+
glGetShaderiv_p glGetShaderInfoLog_p
169+
glCreateProgram glDeleteProgram glLinkProgram glUseProgram
170+
glGetProgramiv_p glGetProgramInfoLog_p
171+
GL_COMPILE_STATUS GL_LINK_STATUS GL_FALSE
172+
GL_VERTEX_SHADER GL_FRAGMENT_SHADER GL_CURRENT_PROGRAM
166173
GL_VERTEX_ARRAY GL_COLOR_ARRAY GL_TEXTURE_COORD_ARRAY GL_NORMAL_ARRAY
167174
GL_LIGHTING_BIT GL_ENABLE_BIT GL_DEPTH_TEST GL_LIGHTING GL_LIGHT0
168175
GL_LIGHT_MODEL_TWO_SIDE GL_TRUE GL_POSITION
@@ -232,6 +239,9 @@ sub togl_bind {
232239
if (defined $this->{Impl}{indx_buf}) {
233240
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, $this->{Impl}{indx_buf}); # unbind the VAO before you unbind the Index Buffer
234241
}
242+
if (my ($program_key) = grep /^program/, keys %{ $this->{Impl} }) {
243+
glUseProgram($this->{Impl}{$program_key});
244+
}
235245
}
236246
sub togl_unbind {
237247
my ($this) = @_;
@@ -244,6 +254,48 @@ sub togl_unbind {
244254
glBindTexture(GL_TEXTURE_2D, 0);
245255
glDisable(GL_TEXTURE_2D);
246256
}
257+
glUseProgram(0) if grep /^program/, keys %{ $this->{Impl} };
258+
}
259+
sub compile_shader {
260+
my ($this, $type, $src) = @_;
261+
my $shader = glCreateShader($type);
262+
glShaderSource_p($shader, $src);
263+
glCompileShader($shader);
264+
my $status = glGetShaderiv_p($shader, GL_COMPILE_STATUS);
265+
if ($status == GL_FALSE) {
266+
my $str = sprintf("%s shader compilation failed!\n",
267+
$type == GL_VERTEX_SHADER ? "Vertex" : "Fragment");
268+
$str .= glGetShaderInfoLog_p($shader);
269+
glDeleteShader($shader);
270+
die $str;
271+
}
272+
$shader;
273+
}
274+
sub compile_program {
275+
my ($this, $vsrc, $fsrc, $prelink) = @_;
276+
my $vShader = $this->compile_shader(GL_VERTEX_SHADER, $vsrc);
277+
my $fShader = $fsrc && eval { $this->compile_shader(GL_FRAGMENT_SHADER, $fsrc) };
278+
if (my $err = $@) {
279+
glDeleteShader($vShader);
280+
die $err;
281+
}
282+
my $program = glCreateProgram();
283+
glAttachShader($program, $vShader);
284+
glAttachShader($program, $fShader) if $fsrc;
285+
$prelink->($program) if $prelink;
286+
glLinkProgram($program);
287+
my $status = glGetProgramiv_p($program, GL_LINK_STATUS);
288+
glDetachShader($program, $vShader);
289+
glDetachShader($program, $fShader) if $fsrc;
290+
glDeleteShader($vShader);
291+
glDeleteShader($fShader) if $fsrc;
292+
if ($status == GL_FALSE) {
293+
my $str = "Program linker failed.\n";
294+
$str .= glGetProgramInfoLog_p($program);
295+
glDeleteProgram($program);
296+
die $str;
297+
}
298+
$program;
247299
}
248300
sub togl {
249301
my ($this, $points) = @_;
@@ -284,6 +336,10 @@ sub DESTROY {
284336
glBindTexture(GL_TEXTURE_2D, 0) if glGetIntegerv_p(GL_TEXTURE_BINDING_2D) == $tex_id;
285337
glDeleteTextures_p($tex_id);
286338
}
339+
if (my $program = $this->{Impl}{program}) {
340+
glUseProgram(0) if glGetIntegerv_p(GL_CURRENT_PROGRAM) == $program;
341+
glDeleteProgram($_) for grep $_, $program;
342+
}
287343
}
288344
}
289345

0 commit comments

Comments
 (0)