our
$VERSION
=
'1.01'
;
our
@ISA
=
qw(OpenGL::Shader::Common)
;
sub
new {
my
$this
=
shift
;
my
$class
=
ref
(
$this
) ||
$this
;
my
$self
= OpenGL::Shader::Common->new(
@_
);
return
undef
if
(!
$self
);
bless
(
$self
,
$class
);
return
undef
if
(OpenGL::glpCheckExtension(
'GL_ARB_shader_objects'
));
return
undef
if
(OpenGL::glpCheckExtension(
'GL_ARB_fragment_shader'
));
return
undef
if
(OpenGL::glpCheckExtension(
'GL_ARB_vertex_shader'
));
$self
->{type} =
''
;
$self
->{version} =
''
;
$self
->{description} =
''
;
$self
->{fragment_const} =
''
;
$self
->{vertex_const} =
''
;
return
$self
;
}
sub
DESTROY {
my
(
$self
) =
@_
;
if
(
$self
->{program}) {
glDetachObjectARB(
$self
->{program},
$self
->{fragment_id})
if
(
$self
->{fragment_id});
glDetachObjectARB(
$self
->{program},
$self
->{vertex_id})
if
(
$self
->{vertex_id});
glDeleteProgramsARB_p(
$self
->{program});
}
glDeleteProgramsARB_p(
$self
->{fragment_id})
if
(
$self
->{fragment_id});
glDeleteProgramsARB_p(
$self
->{vertex_id})
if
(
$self
->{vertex_id});
}
sub
Load {
my
(
$self
,
$fragment
,
$vertex
) =
@_
;
if
(
$fragment
) {
$self
->{fragment_id} = glCreateShaderObjectARB(
$self
->{fragment_const});
return
undef
if
(!
$self
->{fragment_id});
glShaderSourceARB_p(
$self
->{fragment_id},
$fragment
);
glCompileShaderARB(
$self
->{fragment_id});
my
$stat
= glGetInfoLogARB_p(
$self
->{fragment_id});
return
"Fragment shader: $stat"
if
(
$stat
);
}
if
(
$vertex
) {
$self
->{vertex_id} = glCreateShaderObjectARB(
$self
->{vertex_const});
return
undef
if
(!
$self
->{vertex_id});
glShaderSourceARB_p(
$self
->{vertex_id},
$vertex
);
glCompileShaderARB(
$self
->{vertex_id});
my
$stat
= glGetInfoLogARB_p(
$self
->{vertex_id});
return
"Vertex shader: $stat"
if
(
$stat
);
}
my
$sp
= glCreateProgramObjectARB();
glAttachObjectARB(
$sp
,
$self
->{fragment_id})
if
(
$fragment
);
glAttachObjectARB(
$sp
,
$self
->{vertex_id})
if
(
$vertex
);
glLinkProgramARB(
$sp
);
my
$linked
= glGetObjectParameterivARB_p(
$sp
, GL_OBJECT_LINK_STATUS_ARB);
if
(!
$linked
) {
my
$stat
= glGetInfoLogARB_p(
$sp
);
return
"Link shader: $stat"
if
(
$stat
);
return
'Unable to link shader'
;
}
$self
->{program} =
$sp
;
return
''
;
}
sub
Enable {
my
(
$self
) =
@_
;
glUseProgramObjectARB(
$self
->{program})
if
(
$self
->{program});
}
sub
Disable {
my
(
$self
) =
@_
;
glUseProgramObjectARB(0)
if
(
$self
->{program});
}
sub
MapAttr {
my
(
$self
,
$attr
) =
@_
;
return
undef
if
(!
$self
->{program});
my
$id
= glGetAttribLocationARB_p(
$self
->{program},
$attr
);
return
undef
if
(
$id
< 0);
return
$id
;
}
sub
Map {
my
(
$self
,
$var
) =
@_
;
return
undef
if
(!
$self
->{program});
my
$id
= glGetUniformLocationARB_p(
$self
->{program},
$var
);
return
undef
if
(
$id
< 0);
return
$id
;
}
sub
SetVector {
my
(
$self
,
$var
,
@values
) =
@_
;
my
$id
=
$self
->Map(
$var
);
return
'Unable to map $var'
if
(!
defined
(
$id
));
my
$count
=
scalar
(
@values
);
eval
(
'glUniform'
.
$count
.
'fARB($id,@values)'
);
return
''
;
}
sub
SetMatrix {
my
(
$self
,
$var
,
$oga
) =
@_
;
my
$id
=
$self
->Map(
$var
);
return
'Unable to map $var'
if
(!
defined
(
$id
));
glUniformMatrix4fvARB_c(
$id
,1,0,
$oga
->ptr());
return
''
;
}
1;