Commit: b5f9746dae9c9463705f78d15dcc7d23e66cdad5
Author: Brecht Van Lommel
Date:   Fri Nov 27 21:06:23 2015 +0100
Branches: master
https://developer.blender.org/rBb5f9746dae9c9463705f78d15dcc7d23e66cdad5

OpenGL: update simple shader API.

Restore fixed function lighting code for now and control use of GLSL shader
with a variable, make light types more clear, reduce state changes, some other
minor tweaks.

===================================================================

M       source/blender/gpu/GPU_simple_shader.h
M       source/blender/gpu/intern/gpu_simple_shader.c

===================================================================

diff --git a/source/blender/gpu/GPU_simple_shader.h 
b/source/blender/gpu/GPU_simple_shader.h
index 2392962..b62abc6 100644
--- a/source/blender/gpu/GPU_simple_shader.h
+++ b/source/blender/gpu/GPU_simple_shader.h
@@ -41,7 +41,7 @@ extern "C" {
 /* Fixed Function Shader */
 
 typedef enum GPUSimpleShaderOption {
-       GPU_SHADER_OVERRIDE_DIFFUSE = (1<<0),   /* replace diffuse with glcolor 
*/
+       GPU_SHADER_USE_COLOR =        (1<<0),   /* use glColor, for lighting it 
replaces diffuse */
        GPU_SHADER_LIGHTING =         (1<<1),   /* use lighting */
        GPU_SHADER_TWO_SIDED =        (1<<2),   /* flip normals towards viewer 
*/
        GPU_SHADER_TEXTURE_2D =       (1<<3),   /* use 2D texture to replace 
diffuse color */
@@ -55,25 +55,32 @@ void GPU_simple_shaders_init(void);
 void GPU_simple_shaders_exit(void);
 
 void GPU_simple_shader_bind(int options);
-void GPU_simple_shader_unbind(void);
+int GPU_simple_shader_bound_options(void);
 
 void GPU_simple_shader_colors(const float diffuse[3], const float specular[3],
        int shininess, float alpha);
 
-bool GPU_simple_shader_need_normals(void);
-
 /* Fixed Function Lighting */
 
+typedef enum GPULightType {
+       GPU_LIGHT_POINT,
+       GPU_LIGHT_SPOT,
+       GPU_LIGHT_SUN
+} GPULightType;
+
 typedef struct GPULightData {
-       float position[4];
-       float diffuse[4];
-       float specular[4];
+       GPULightType type;
+
+       float position[3];
+       float direction[3];
+
+       float diffuse[3];
+       float specular[3];
 
        float constant_attenuation;
        float linear_attenuation;
        float quadratic_attenuation;
 
-       float spot_direction[3];
        float spot_cutoff;
        float spot_exponent;
 } GPULightData;
diff --git a/source/blender/gpu/intern/gpu_simple_shader.c 
b/source/blender/gpu/intern/gpu_simple_shader.c
index bd77466..74ca23e 100644
--- a/source/blender/gpu/intern/gpu_simple_shader.c
+++ b/source/blender/gpu/intern/gpu_simple_shader.c
@@ -52,13 +52,13 @@
 
 /* State */
 
-// #define NUM_OPENGL_LIGHTS 8
+static const bool USE_GLSL = false;
 
 static struct {
        GPUShader *cached_shaders[GPU_SHADER_OPTION_COMBINATIONS];
        bool failed_shaders[GPU_SHADER_OPTION_COMBINATIONS];
 
-       bool need_normals;
+       int bound_options;
 
        int lights_enabled;
        int lights_directional;
@@ -104,7 +104,7 @@ static int detect_options()
        if (glIsEnabled(GL_TEXTURE_2D))
                options |= GPU_SHADER_TEXTURE_2D;
        if (glIsEnabled(GL_COLOR_MATERIAL))
-               options |= GPU_SHADER_OVERRIDE_DIFFUSE;
+               options |= GPU_SHADER_USE_COLOR;
 
        if (glIsEnabled(GL_LIGHTING))
                options |= GPU_SHADER_LIGHTING;
@@ -136,7 +136,7 @@ static GPUShader *gpu_simple_shader(int options)
                /* create shader if it doesn't exist yet */
                char defines[64*GPU_SHADER_OPTIONS_NUM] = "";
 
-               if (options & GPU_SHADER_OVERRIDE_DIFFUSE)
+               if (options & GPU_SHADER_USE_COLOR)
                        strcat(defines, "#define USE_COLOR\n");
                if (options & GPU_SHADER_TWO_SIDED)
                        strcat(defines, "#define USE_TWO_SIDED\n");
@@ -173,18 +173,53 @@ static GPUShader *gpu_simple_shader(int options)
 
 void GPU_simple_shader_bind(int options)
 {
-       GPUShader *shader = gpu_simple_shader(options);
+       if (USE_GLSL) {
+               if (options) {
+                       GPUShader *shader = gpu_simple_shader(options);
 
-       if (shader)
-               GPU_shader_bind(shader);
+                       if (shader)
+                               GPU_shader_bind(shader);
+               }
+               else {
+                       GPU_shader_unbind();
+               }
+       }
+       else {
+               int bound_options = GPU_MATERIAL_STATE.bound_options;
 
-       /* temporary hack, should be solved outside of this file */
-       GPU_MATERIAL_STATE.need_normals = (options & GPU_SHADER_LIGHTING);
+               if (options & GPU_SHADER_LIGHTING) {
+                       glEnable(GL_LIGHTING);
+
+                       if (options & GPU_SHADER_USE_COLOR)
+                               glEnable(GL_COLOR_MATERIAL);
+                       else
+                               glDisable(GL_COLOR_MATERIAL);
+
+                       if (options & GPU_SHADER_TWO_SIDED)
+                               glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
+                       else
+                               glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 
GL_FALSE);
+               }
+               else if (bound_options & GPU_SHADER_LIGHTING) {
+                       glDisable(GL_LIGHTING);
+                       glDisable(GL_COLOR_MATERIAL);
+                       glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
+               }
+
+               if (options & GPU_SHADER_TEXTURE_2D)
+                       glEnable(GL_TEXTURE_2D);
+               else if (bound_options & GPU_SHADER_TEXTURE_2D)
+                       glDisable(GL_TEXTURE_2D);
+       }
+
+       GPU_MATERIAL_STATE.bound_options = options;
 }
 
-void GPU_simple_shader_unbind(void)
+int GPU_simple_shader_bound_options(void)
 {
-       GPU_shader_unbind();
+       /* ideally this should disappear, anything that uses this is making 
fragile
+        * assumptions that the simple shader is bound and not another shader */
+       return GPU_MATERIAL_STATE.bound_options;
 }
 
 /* Material Colors */
@@ -194,10 +229,16 @@ void GPU_simple_shader_colors(const float diffuse[3], 
const float specular[3],
 {
        float gl_diffuse[4], gl_specular[4];
 
-       copy_v3_v3(gl_diffuse, diffuse);
+       if (diffuse)
+               copy_v3_v3(gl_diffuse, diffuse);
+       else
+               zero_v3(gl_diffuse);
        gl_diffuse[3] = alpha;
 
-       copy_v3_v3(gl_specular, specular);
+       if (specular)
+               copy_v3_v3(gl_specular, specular);
+       else
+               zero_v3(gl_specular);
        gl_specular[3] = 1.0f;
 
        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, gl_diffuse);
@@ -205,43 +246,75 @@ void GPU_simple_shader_colors(const float diffuse[3], 
const float specular[3],
        glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, CLAMPIS(shininess, 1, 
128));
 }
 
-bool GPU_simple_shader_need_normals(void)
-{
-       return GPU_MATERIAL_STATE.need_normals;
-}
-
 void GPU_simple_shader_light_set(int light_num, GPULightData *light)
 {
        int light_bit = (1 << light_num);
 
+       /* note that light position is affected by the current modelview 
matrix! */
+
        GPU_MATERIAL_STATE.lights_enabled &= ~light_bit;
        GPU_MATERIAL_STATE.lights_directional &= ~light_bit;
 
        if (light) {
-               glEnable(GL_LIGHT0+light_num);
+               float position[4], diffuse[4], specular[4];
 
-               glLightfv(GL_LIGHT0+light_num, GL_POSITION, light->position); 
-               glLightfv(GL_LIGHT0+light_num, GL_DIFFUSE, light->diffuse);
-               glLightfv(GL_LIGHT0+light_num, GL_SPECULAR, light->specular);
+               glEnable(GL_LIGHT0+light_num);
 
-               glLightf(GL_LIGHT0+light_num, GL_CONSTANT_ATTENUATION, 
light->constant_attenuation);
-               glLightf(GL_LIGHT0+light_num, GL_LINEAR_ATTENUATION, 
light->linear_attenuation);
-               glLightf(GL_LIGHT0+light_num, GL_QUADRATIC_ATTENUATION, 
light->quadratic_attenuation);
+               /* position */
+               if (light->type == GPU_LIGHT_SUN) {
+                       copy_v3_v3(position, light->direction);
+                       position[3] = 0.0f;
+               }
+               else {
+                       copy_v3_v3(position, light->position);
+                       position[3] = 1.0f;
+               }
+               glLightfv(GL_LIGHT0+light_num, GL_POSITION, position);
+
+               /* energy */
+               copy_v3_v3(diffuse, light->diffuse);
+               copy_v3_v3(specular, light->specular);
+               diffuse[3] = 1.0f;
+               specular[3] = 1.0f;
+               glLightfv(GL_LIGHT0+light_num, GL_DIFFUSE, diffuse);
+               glLightfv(GL_LIGHT0+light_num, GL_SPECULAR, specular);
+
+               /* attenuation */
+               if (light->type == GPU_LIGHT_SUN) {
+                       glLightf(GL_LIGHT0+light_num, GL_CONSTANT_ATTENUATION, 
1.0f);
+                       glLightf(GL_LIGHT0+light_num, GL_LINEAR_ATTENUATION, 
0.0f);
+                       glLightf(GL_LIGHT0+light_num, GL_QUADRATIC_ATTENUATION, 
0.0f);
+               }
+               else {
+                       glLightf(GL_LIGHT0+light_num, GL_CONSTANT_ATTENUATION, 
light->constant_attenuation);
+                       glLightf(GL_LIGHT0+light_num, GL_LINEAR_ATTENUATION, 
light->linear_attenuation);
+                       glLightf(GL_LIGHT0+light_num, GL_QUADRATIC_ATTENUATION, 
light->quadratic_attenuation);
+               }
 
-               glLightfv(GL_LIGHT0+light_num, GL_SPOT_DIRECTION, 
light->spot_direction);
-               glLightf(GL_LIGHT0+light_num, GL_SPOT_CUTOFF, 
light->spot_cutoff);
-               glLightf(GL_LIGHT0+light_num, GL_SPOT_EXPONENT, 
light->spot_exponent);
+               /* spot */
+               glLightfv(GL_LIGHT0+light_num, GL_SPOT_DIRECTION, 
light->direction);
+               if (light->type == GPU_LIGHT_SPOT) {
+                       glLightf(GL_LIGHT0+light_num, GL_SPOT_CUTOFF, 
light->spot_cutoff);
+                       glLightf(GL_LIGHT0+light_num, GL_SPOT_EXPONENT, 
light->spot_exponent);
+               }
+               else {
+                       glLightf(GL_LIGHT0+light_num, GL_SPOT_CUTOFF, 180.0f);
+                       glLightf(GL_LIGHT0+light_num, GL_SPOT_EXPONENT, 0.0f);
+               }
 
                GPU_MATERIAL_STATE.lights_enabled |= light_bit;
                if (light->position[3] == 0.0f)
                        GPU_MATERIAL_STATE.lights_directional |= light_bit;
        }
        else {
-               const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+               if (USE_GLSL) {
+                       /* glsl shader needs these zero to skip them */
+                       const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
 
-               glLightfv(GL_LIGHT0+light_num, GL_POSITION, zero); 
-               glLightfv(GL_LIGHT0+light_num, GL_DIFFUSE, zero); 
-               glLightfv(GL_LIGHT0+light_num, GL_SPECULAR, zero);
+                       glLightfv(GL_LIGHT0+light_num, GL_POSITION, zero);
+                       glLightfv(GL_LIGHT0+light_num, GL_DIFFUSE, zero);
+                       glLightfv(GL_LIGHT0+light_num, GL_SPECULAR, zero);
+               }
 
                glDisable(GL_LIGHT0+light_num);
        }

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to