Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2015-11-27 23:06:23 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2015-11-28 17:35:34 +0300
commitb5f9746dae9c9463705f78d15dcc7d23e66cdad5 (patch)
treef1400a73ba4b369afd671e95e34e78a5f687d913 /source
parent263f4cd3426f19eccde79f6eeeec758c03a234ac (diff)
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.
Diffstat (limited to 'source')
-rw-r--r--source/blender/gpu/GPU_simple_shader.h23
-rw-r--r--source/blender/gpu/intern/gpu_simple_shader.c137
2 files changed, 120 insertions, 40 deletions
diff --git a/source/blender/gpu/GPU_simple_shader.h b/source/blender/gpu/GPU_simple_shader.h
index 239296209b4..b62abc6152a 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 bd7746648c8..74ca23e8854 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);
}