Class: Mittsu::OpenGLProgram
- Inherits:
-
Object
- Object
- Mittsu::OpenGLProgram
- Defined in:
- lib/mittsu/renderers/opengl/opengl_program.rb
Instance Attribute Summary collapse
-
#attributes ⇒ Object
Returns the value of attribute attributes.
-
#code ⇒ Object
Returns the value of attribute code.
-
#fragment_shader ⇒ Object
Returns the value of attribute fragment_shader.
-
#id ⇒ Object
readonly
Returns the value of attribute id.
-
#program ⇒ Object
readonly
Returns the value of attribute program.
-
#uniforms ⇒ Object
readonly
Returns the value of attribute uniforms.
-
#used_times ⇒ Object
Returns the value of attribute used_times.
-
#vertex_shader ⇒ Object
Returns the value of attribute vertex_shader.
Instance Method Summary collapse
-
#initialize(renderer, code, material, parameters) ⇒ OpenGLProgram
constructor
A new instance of OpenGLProgram.
Constructor Details
#initialize(renderer, code, material, parameters) ⇒ OpenGLProgram
Returns a new instance of OpenGLProgram.
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 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 |
# File 'lib/mittsu/renderers/opengl/opengl_program.rb', line 8 def initialize(renderer, code, material, parameters) defines = material.defines || {} # TODO: setting to default object... ? uniforms = material[:_opengl_shader][:uniforms] attributes = material.attributes || [] # TODO: setting to default array... ? vertex_shader = material[:_opengl_shader][:vertex_shader] fragment_shader = material[:_opengl_shader][:fragment_shader] # TODO: necessary for OpenGL? # index0_attribute_name = material.index0_attribute_name # # if index0_attribute_name.nil? && parameters[:morph_targets] # # programs with morph_targets displace position of attribute 0 # # index0_attribute_name = 'position' # end shadow_map_type_define = 'SHADOWMAP_TYPE_BASIC' if parameters[:shadow_map_type] == PCFShadowMap shadow_map_type_define = 'SHADOWMAP_TYPE_PCF_SOFT' elsif parameters[:shadow_map_type] == PCFSoftShadowMap shadow_map_type_define = 'SHADOWMAP_TYPE_PCF_SOFT' end env_map_type_define = 'ENVMAP_TYPE_CUBE' env_map_mode_define = 'ENVMAP_MODE_REFLECTION' env_map_blending_define = 'ENVMAP_BLENDING_MULTIPLY' if parameters[:env_map] case material.env_map.mapping when CubeReflectionMapping, CubeRefractionMapping env_map_type_define = 'ENVMAP_TYPE_CUBE' when EquirectangularReflectionMapping, EquirectangularRefractionMapping env_map_type_define = 'ENVMAP_TYPE_EQUIREC' when SphericalReflectionMapping env_map_type_define = 'ENVMAP_TYPE_SPHERE' end case material.env_map.mapping when CubeRefractionMapping, EquirectangularRefractionMapping env_map_mode_define 'ENVMAP_MODE_REFRACTION' end case material.combine when MultiplyOperation env_map_blending_define = 'ENVMAP_BLENDING_MULTIPLY' when MixOperation env_map_blending_define = 'ENVMAP_BLENDING_MIX' when AddOperation env_map_blending_define = 'ENVMAP_BLENDING_ADD' end end gamma_factor_define = (renderer.gamma_factor > 0) ? renderer.gamma_factor : 1.0 # puts 'building new program' # custom_defines = generate_defines(defines) # @program = glCreateProgram if false # material.is_a?(RawShaderMaterial) # TODO: when RawShaderMaterial exists prefix_vertex = '' prefix_fragment = '' else prefix_vertex = [ '#version 330', # TODO: do we need precision for an OpenGL program? # "precision #{parameters[:precision]} float;", # "precision #{parameters[:precision]} int;", custom_defines, parameters[:supports_vertex_textures] ? '#define VERTEX_TEXTURES' : '', renderer.gamma_input ? '#define GAMMA_INPUT' : '', renderer.gamma_output ? '#define GAMMA_OUTPUT' : '', "#define GAMMA_FACTOR #{gamma_factor_define}", "#define MAX_DIR_LIGHTS #{parameters[:max_dir_lights]}", "#define MAX_POINT_LIGHTS #{parameters[:max_point_lights]}", "#define MAX_SPOT_LIGHTS #{parameters[:max_spot_lights]}", "#define MAX_HEMI_LIGHTS #{parameters[:max_hemi_lights]}", "#define MAX_SHADOWS #{parameters[:max_shadows]}", "#define MAX_BONES #{parameters[:max_bones]}", parameters[:map] ? '#define USE_MAP' : '', parameters[:env_map] ? '#define USE_ENVMAP' : '', parameters[:env_map] ? "#define #{env_map_mode_define}" : '', parameters[:light_map] ? '#define USE_LIGHTMAP' : '', parameters[:bump_map] ? '#define USE_BUMPMAP' : '', parameters[:normal_map] ? '#define USE_NORMALMAP' : '', parameters[:specular_map] ? '#define USE_SPECULARMAP' : '', parameters[:alpha_map] ? '#define USE_ALPHAMAP' : '', parameters[:vertex_colors] ? '#define USE_COLOR' : '', parameters[:flat_shading] ? '#define FLAT_SHADED': '', parameters[:skinning] ? '#define USE_SKINNING' : '', parameters[:use_vertex_texture] ? '#define BONE_TEXTURE' : '', parameters[:morph_targets] ? '#define USE_MORPHTARGETS' : '', parameters[:morph_normals] ? '#define USE_MORPHNORMALS' : '', parameters[:wrap_around] ? '#define WRAP_AROUND' : '', parameters[:double_sided] ? '#define DOUBLE_SIDED' : '', parameters[:flip_sided] ? '#define FLIP_SIDED' : '', parameters[:shadow_map_enabled] ? '#define USE_SHADOWMAP' : '', parameters[:shadow_map_enabled] ? "#define #{shadow_map_type_define}" : '', parameters[:shadow_map_debug] ? '#define SHADOWMAP_DEBUG' : '', parameters[:shadow_map_cascade] ? '#define SHADOWMAP_CASCADE' : '', parameters[:size_attenuation] ? '#define USE_SIZEATTENUATION' : '', parameters[:logarithmic_depth_buffer] ? '#define USE_LOGDEPTHBUF' : '', #renderer._glExtensionFragDepth ? '#define USE_LOGDEPTHBUF_EXT' : '', 'uniform mat4 modelMatrix;', 'uniform mat4 modelViewMatrix;', 'uniform mat4 projectionMatrix;', 'uniform mat4 viewMatrix;', 'uniform mat3 normalMatrix;', 'uniform vec3 cameraPosition;', 'in vec3 position;', 'in vec3 normal;', 'in vec2 uv;', 'in vec2 uv2;', '#ifdef USE_COLOR', ' in vec3 color;', '#endif', '#ifdef USE_MORPHTARGETS', ' in vec3 morphTarget0;', ' in vec3 morphTarget1;', ' in vec3 morphTarget2;', ' in vec3 morphTarget3;', ' #ifdef USE_MORPHNORMALS', ' in vec3 morphNormal0;', ' in vec3 morphNormal1;', ' in vec3 morphNormal2;', ' in vec3 morphNormal3;', ' #else', ' in vec3 morphTarget4;', ' in vec3 morphTarget5;', ' in vec3 morphTarget6;', ' in vec3 morphTarget7;', ' #endif', '#endif', '#ifdef USE_SKINNING', ' in vec4 skinIndex;', ' in vec4 skinWeight;', '#endif', ].reject(&:empty?).join("\n") + "\n" prefix_fragment = [ '#version 330', # TODO: do we need precision for an OpenGL program? # "precison #{parameters[:precision]} float;", # "precison #{parameters[:precision]} int;", # (parameters[:bump_map] || parameters[:normal_map] || parameters[:flat_shading]) ? '#extension GL_OES_standard_derivatives : enable' : '', # TODO: oes extension in OpenGL? custom_defines, "#define MAX_DIR_LIGHTS #{parameters[:max_dir_lights]}", "#define MAX_POINT_LIGHTS #{parameters[:max_point_lights]}", "#define MAX_SPOT_LIGHTS #{parameters[:max_spot_lights]}", "#define MAX_HEMI_LIGHTS #{parameters[:max_hemi_lights]}", "#define MAX_SHADOWS #{parameters[:max_shadows]}", parameters[:alpha_test] ? "#define ALPHATEST #{parameters[:alpha_test].to_f}" : '', renderer.gamma_input ? '#define GAMMA_INPUT' : '', renderer.gamma_output ? '#define GAMMA_OUTPUT' : '', "#define GAMMA_FACTOR #{gamma_factor_define}", (parameters[:use_fog] && parameters[:fog]) ? '#define USE_FOG' : '', (parameters[:use_fog] && parameters[:fog_exp]) ? '#define FOG_EXP2' : '', parameters[:map] ? '#define USE_MAP' : '', parameters[:env_map] ? '#define USE_ENVMAP' : '', parameters[:env_map] ? "#define #{env_map_type_define}" : '', parameters[:env_map] ? "#define #{env_map_mode_define}" : '', parameters[:env_map] ? "#define #{env_map_blending_define}" : '', parameters[:light_map] ? '#define USE_LIGHTMAP' : '', parameters[:bump_map] ? '#define USE_BUMPMAP' : '', parameters[:normal_map] ? '#define USE_NORMALMAP' : '', parameters[:specular_map] ? '#define USE_SPECULARMAP' : '', parameters[:alpha_map] ? '#define USE_ALPHAMAP' : '', parameters[:vertex_colors] ? '#define USE_COLOR' : '', parameters[:flat_shading] ? '#define FLAT_SHADED' : '', parameters[:metal] ? '#define METAL' : '', parameters[:wrap_around] ? '#define WRAP_AROUND' : '', parameters[:double_sided] ? '#define DOUBLE_SIDED' : '', parameters[:flip_sided] ? '#define FLIP_SIDED' : '', parameters[:shadow_map_enabled] ? '#define USE_SHADOWMAP' : '', parameters[:shadow_map_enabled] ? "#define #{shadow_map_type_define}" : '', parameters[:shadow_map_debug] ? '#define SHADOWMAP_DEBUG' : '', parameters[:'shadow_map_cascade'] ? '#define SHADOWMAP_CASCADE' : '', parameters[:logarithmic_depth_buffer] ? '#define USE_LOGDEPTHBUF' : '', #renderer._glExtensionFragDepth ? '#define USE_LOGDEPTHBUF_EXT' : '', 'uniform mat4 viewMatrix;', 'uniform vec3 cameraPosition;', 'layout(location = 0) out vec4 fragColor;' ].reject(&:empty?).join("\n") + "\n" end gl_vertex_shader = OpenGLShader.new(GL_VERTEX_SHADER, prefix_vertex + vertex_shader) gl_fragment_shader = OpenGLShader.new(GL_FRAGMENT_SHADER, prefix_fragment + fragment_shader) glAttachShader(@program, gl_vertex_shader.shader) glAttachShader(@program, gl_fragment_shader.shader) # if !index0_attribute_name.nil? # TODO: is this necessary in OpenGL ??? # Force a particular attribute to index 0. # because potentially expensive emulation is done by __browser__ if attribute 0 is disabled. (no browser here!) # And, color, for example is often automatically bound to index 0 so disabling it # glBindAttributeLocation(program, 0, index0_attribute_name) # end glLinkProgram(@program) log_info = program_info_log if !link_status puts "ERROR: Mittsu::OpenGLProgram: shader error: #{glGetError}, GL_INVALID_STATUS, #{glGetProgramParameter(program, GL_VALIDATE_STATUS)}, glGetProgramParameterInfoLog, #{program_log_info}" end if !log_info.empty? puts "WARNING: Mittsu::OpenGLProgram: glGetProgramInfoLog, #{log_info}" # TODO: useless in OpenGL ??? # puts "WARNING: #{glGetExtension( 'OPENGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader )}" # puts "WARNING: #{glGetExtension( 'OPENGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader )}" end # clean up glDeleteShader(gl_vertex_shader.shader) glDeleteShader(gl_fragment_shader.shader) # cache uniform locations identifiers = [ 'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'modelMatrix', 'cameraPosition', 'morphTargetInfluences', 'bindMatrix', 'bindMatrixInverse' ] if parameters[:use_vertex_texture] identifiers << 'boneTexture' identifiers << 'boneTextureWidth' identifiers << 'boneTextureHeight' else identifiers << 'boneGlobalMatrices' end if parameters[:logarithmic_depth_buffer] identifiers << 'logDepthBufFC' end uniforms.each do |k, v| identifiers << k.to_s end @uniforms = cache_uniform_locations(program, identifiers) # cache attributes locations identifiers = [ 'position', 'normal', 'uv', 'uv2', 'tangent', 'color', 'skinIndex', 'skinWeight', 'lineDistance' ] parameters[:max_morph_targets].times do |i| identifiers << "morphTarget#{i}" end parameters[:max_morph_normals].times do |i| identifiers << "morphNormal#{i}" end attributes.each do |k, v| identifiers << k end @attributes = cache_attribute_locations(program, identifiers) @id = (@@id ||= 1).tap { @@id += 1 } @code = code @used_times = 2 @vertex_shader = gl_vertex_shader @fragment_shader = gl_fragment_shader end |
Instance Attribute Details
#attributes ⇒ Object
Returns the value of attribute attributes.
5 6 7 |
# File 'lib/mittsu/renderers/opengl/opengl_program.rb', line 5 def attributes @attributes end |
#code ⇒ Object
Returns the value of attribute code.
6 7 8 |
# File 'lib/mittsu/renderers/opengl/opengl_program.rb', line 6 def code @code end |
#fragment_shader ⇒ Object
Returns the value of attribute fragment_shader.
6 7 8 |
# File 'lib/mittsu/renderers/opengl/opengl_program.rb', line 6 def fragment_shader @fragment_shader end |
#id ⇒ Object (readonly)
Returns the value of attribute id.
5 6 7 |
# File 'lib/mittsu/renderers/opengl/opengl_program.rb', line 5 def id @id end |
#program ⇒ Object (readonly)
Returns the value of attribute program.
5 6 7 |
# File 'lib/mittsu/renderers/opengl/opengl_program.rb', line 5 def program @program end |
#uniforms ⇒ Object (readonly)
Returns the value of attribute uniforms.
5 6 7 |
# File 'lib/mittsu/renderers/opengl/opengl_program.rb', line 5 def uniforms @uniforms end |
#used_times ⇒ Object
Returns the value of attribute used_times.
6 7 8 |
# File 'lib/mittsu/renderers/opengl/opengl_program.rb', line 6 def used_times @used_times end |
#vertex_shader ⇒ Object
Returns the value of attribute vertex_shader.
6 7 8 |
# File 'lib/mittsu/renderers/opengl/opengl_program.rb', line 6 def vertex_shader @vertex_shader end |