GPULamp: Separate GPULamp from GPUMaterial
Since we need GPULamps for draw engines, it makes sense to separate them.
This commit is contained in:
parent
8e0bfee1e5
commit
eca256bc32
|
@ -129,7 +129,7 @@
|
|||
|
||||
#include "CCGSubSurf.h"
|
||||
|
||||
#include "GPU_material.h"
|
||||
#include "GPU_lamp.h"
|
||||
|
||||
/* Vertex parent modifies original BMesh which is not safe for threading.
|
||||
* Ideally such a modification should be handled as a separate DAG update
|
||||
|
|
|
@ -115,7 +115,7 @@
|
|||
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "GPU_material.h"
|
||||
#include "GPU_lamp.h"
|
||||
|
||||
#include "object_intern.h"
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include "BKE_paint.h"
|
||||
#include "BKE_scene.h"
|
||||
|
||||
#include "GPU_lamp.h"
|
||||
#include "GPU_material.h"
|
||||
#include "GPU_buffers.h"
|
||||
|
||||
|
|
|
@ -97,6 +97,7 @@
|
|||
|
||||
#include "GPU_draw.h"
|
||||
#include "GPU_framebuffer.h"
|
||||
#include "GPU_lamp.h"
|
||||
#include "GPU_material.h"
|
||||
#include "GPU_compositing.h"
|
||||
#include "GPU_extensions.h"
|
||||
|
|
|
@ -61,6 +61,7 @@ set(SRC
|
|||
intern/gpu_framebuffer.c
|
||||
intern/gpu_immediate.c
|
||||
intern/gpu_init_exit.c
|
||||
intern/gpu_lamp.c
|
||||
intern/gpu_material.c
|
||||
intern/gpu_matrix.c
|
||||
intern/gpu_select.c
|
||||
|
@ -114,6 +115,7 @@ set(SRC
|
|||
|
||||
intern/gpu_codegen.h
|
||||
intern/gpu_private.h
|
||||
intern/gpu_lamp_private.h
|
||||
intern/gpu_select_private.h
|
||||
intern/gpu_shader_private.h
|
||||
)
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2005 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Brecht Van Lommel, Clément Foucault.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file GPU_lamp.h
|
||||
* \ingroup gpu
|
||||
*/
|
||||
|
||||
#ifndef __GPU_LAMP_H__
|
||||
#define __GPU_LAMP_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Scene;
|
||||
struct Object;
|
||||
struct RenderEngineType;
|
||||
|
||||
typedef struct GPULamp GPULamp;
|
||||
|
||||
typedef struct LampEngineData {
|
||||
struct GPUFrameBuffer *framebuffers[4];
|
||||
struct GPUTexture *textures[4];
|
||||
void *storage[4];
|
||||
} LampEngineData;
|
||||
|
||||
GPULamp *GPU_lamp_from_engine(struct Scene *scene, struct Object *ob, Object *par, struct RenderEngineType *re);
|
||||
GPULamp *GPU_lamp_from_blender(struct Scene *scene, struct Object *ob, struct Object *par);
|
||||
void GPU_lamp_free(struct Object *ob);
|
||||
|
||||
bool GPU_lamp_override_visible(GPULamp *lamp, struct SceneRenderLayer *srl, struct Material *ma);
|
||||
bool GPU_lamp_has_shadow_buffer(GPULamp *lamp);
|
||||
void GPU_lamp_update_buffer_mats(GPULamp *lamp);
|
||||
void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4]);
|
||||
void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp);
|
||||
int GPU_lamp_shadow_buffer_type(GPULamp *lamp);
|
||||
int GPU_lamp_shadow_bind_code(GPULamp *lamp);
|
||||
float *GPU_lamp_dynpersmat(GPULamp *lamp);
|
||||
|
||||
void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4]);
|
||||
void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy);
|
||||
void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2,
|
||||
float coeff_const, float coeff_lin, float coeff_quad);
|
||||
void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend);
|
||||
int GPU_lamp_shadow_layer(GPULamp *lamp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __GPU_LAMP_H__ */
|
|
@ -45,7 +45,6 @@ struct Image;
|
|||
struct ImageUser;
|
||||
struct Material;
|
||||
struct Object;
|
||||
struct Image;
|
||||
struct Scene;
|
||||
struct SceneRenderLayer;
|
||||
struct GPUVertexAttribs;
|
||||
|
@ -61,7 +60,7 @@ struct World;
|
|||
typedef struct GPUNode GPUNode;
|
||||
typedef struct GPUNodeLink GPUNodeLink;
|
||||
typedef struct GPUMaterial GPUMaterial;
|
||||
typedef struct GPULamp GPULamp;
|
||||
|
||||
typedef struct GPUParticleInfo GPUParticleInfo;
|
||||
|
||||
/* Functions to create GPU Materials nodes */
|
||||
|
@ -224,7 +223,6 @@ void GPU_material_free(struct ListBase *gpumaterial);
|
|||
|
||||
void GPU_materials_free(void);
|
||||
|
||||
bool GPU_lamp_override_visible(GPULamp *lamp, struct SceneRenderLayer *srl, struct Material *ma);
|
||||
void GPU_material_bind(
|
||||
GPUMaterial *material, int oblay, int viewlay, double time, int mipmap,
|
||||
float viewmat[4][4], float viewinv[4][4], float cameraborder[4], bool scenelock);
|
||||
|
@ -310,26 +308,8 @@ GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma);
|
|||
void GPU_free_shader_export(GPUShaderExport *shader);
|
||||
|
||||
/* Lamps */
|
||||
|
||||
GPULamp *GPU_lamp_from_blender(struct Scene *scene, struct Object *ob, struct Object *par);
|
||||
void GPU_lamp_free(struct Object *ob);
|
||||
|
||||
bool GPU_lamp_has_shadow_buffer(GPULamp *lamp);
|
||||
void GPU_lamp_update_buffer_mats(GPULamp *lamp);
|
||||
void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4]);
|
||||
void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp);
|
||||
int GPU_lamp_shadow_buffer_type(GPULamp *lamp);
|
||||
int GPU_lamp_shadow_bind_code(GPULamp *lamp);
|
||||
float *GPU_lamp_dynpersmat(GPULamp *lamp);
|
||||
|
||||
void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4]);
|
||||
void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy);
|
||||
void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2,
|
||||
float coeff_const, float coeff_lin, float coeff_quad);
|
||||
void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend);
|
||||
int GPU_lamp_shadow_layer(GPULamp *lamp);
|
||||
GPUNodeLink *GPU_lamp_get_data(
|
||||
GPUMaterial *mat, GPULamp *lamp,
|
||||
GPUMaterial *mat, struct GPULamp *lamp,
|
||||
GPUNodeLink **r_col, GPUNodeLink **r_lv, GPUNodeLink **r_dist, GPUNodeLink **r_shadow, GPUNodeLink **r_energy);
|
||||
|
||||
/* World */
|
||||
|
|
|
@ -0,0 +1,475 @@
|
|||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2006 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Brecht Van Lommel, Clément Foucault.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/gpu/intern/gpu_lamp.c
|
||||
* \ingroup gpu
|
||||
*
|
||||
* Manages Opengl lights.
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_lamp_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_group.h"
|
||||
|
||||
#include "GPU_framebuffer.h"
|
||||
#include "GPU_glew.h"
|
||||
#include "GPU_lamp.h"
|
||||
#include "GPU_material.h"
|
||||
#include "GPU_shader.h"
|
||||
#include "GPU_texture.h"
|
||||
|
||||
#include "gpu_lamp_private.h"
|
||||
|
||||
bool GPU_lamp_override_visible(GPULamp *lamp, SceneRenderLayer *srl, Material *ma)
|
||||
{
|
||||
if (srl && srl->light_override)
|
||||
return BKE_group_object_exists(srl->light_override, lamp->ob);
|
||||
else if (ma && ma->group)
|
||||
return BKE_group_object_exists(ma->group, lamp->ob);
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
static void gpu_lamp_calc_winmat(GPULamp *lamp)
|
||||
{
|
||||
float temp, angle, pixsize, wsize;
|
||||
|
||||
if (lamp->type == LA_SUN) {
|
||||
wsize = lamp->la->shadow_frustum_size;
|
||||
orthographic_m4(lamp->winmat, -wsize, wsize, -wsize, wsize, lamp->d, lamp->clipend);
|
||||
}
|
||||
else if (lamp->type == LA_SPOT) {
|
||||
angle = saacos(lamp->spotsi);
|
||||
temp = 0.5f * lamp->size * cosf(angle) / sinf(angle);
|
||||
pixsize = lamp->d / temp;
|
||||
wsize = pixsize * 0.5f * lamp->size;
|
||||
/* compute shadows according to X and Y scaling factors */
|
||||
perspective_m4(
|
||||
lamp->winmat,
|
||||
-wsize * lamp->spotvec[0], wsize * lamp->spotvec[0],
|
||||
-wsize * lamp->spotvec[1], wsize * lamp->spotvec[1],
|
||||
lamp->d, lamp->clipend);
|
||||
}
|
||||
}
|
||||
|
||||
void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4])
|
||||
{
|
||||
float mat[4][4];
|
||||
float obmat_scale[3];
|
||||
|
||||
lamp->lay = lay;
|
||||
lamp->hide = hide;
|
||||
|
||||
normalize_m4_m4_ex(mat, obmat, obmat_scale);
|
||||
|
||||
copy_v3_v3(lamp->vec, mat[2]);
|
||||
copy_v3_v3(lamp->co, mat[3]);
|
||||
copy_m4_m4(lamp->obmat, mat);
|
||||
invert_m4_m4(lamp->imat, mat);
|
||||
|
||||
if (lamp->type == LA_SPOT) {
|
||||
/* update spotlamp scale on X and Y axis */
|
||||
lamp->spotvec[0] = obmat_scale[0] / obmat_scale[2];
|
||||
lamp->spotvec[1] = obmat_scale[1] / obmat_scale[2];
|
||||
}
|
||||
|
||||
if (GPU_lamp_has_shadow_buffer(lamp)) {
|
||||
/* makeshadowbuf */
|
||||
gpu_lamp_calc_winmat(lamp);
|
||||
}
|
||||
}
|
||||
|
||||
void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy)
|
||||
{
|
||||
lamp->energy = energy;
|
||||
if (lamp->mode & LA_NEG) lamp->energy = -lamp->energy;
|
||||
|
||||
lamp->col[0] = r;
|
||||
lamp->col[1] = g;
|
||||
lamp->col[2] = b;
|
||||
}
|
||||
|
||||
void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2,
|
||||
float coeff_const, float coeff_lin, float coeff_quad)
|
||||
{
|
||||
lamp->dist = distance;
|
||||
lamp->att1 = att1;
|
||||
lamp->att2 = att2;
|
||||
lamp->coeff_const = coeff_const;
|
||||
lamp->coeff_lin = coeff_lin;
|
||||
lamp->coeff_quad = coeff_quad;
|
||||
}
|
||||
|
||||
void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend)
|
||||
{
|
||||
lamp->spotsi = cosf(spotsize * 0.5f);
|
||||
lamp->spotbl = (1.0f - lamp->spotsi) * spotblend;
|
||||
}
|
||||
|
||||
static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *la, GPULamp *lamp)
|
||||
{
|
||||
lamp->scene = scene;
|
||||
lamp->ob = ob;
|
||||
lamp->par = par;
|
||||
lamp->la = la;
|
||||
|
||||
/* add_render_lamp */
|
||||
lamp->mode = la->mode;
|
||||
lamp->type = la->type;
|
||||
|
||||
lamp->energy = la->energy;
|
||||
if (lamp->mode & LA_NEG) lamp->energy = -lamp->energy;
|
||||
|
||||
lamp->col[0] = la->r;
|
||||
lamp->col[1] = la->g;
|
||||
lamp->col[2] = la->b;
|
||||
|
||||
GPU_lamp_update(lamp, ob->lay, (ob->restrictflag & OB_RESTRICT_RENDER), ob->obmat);
|
||||
|
||||
lamp->spotsi = la->spotsize;
|
||||
if (lamp->mode & LA_HALO)
|
||||
if (lamp->spotsi > DEG2RADF(170.0f))
|
||||
lamp->spotsi = DEG2RADF(170.0f);
|
||||
lamp->spotsi = cosf(lamp->spotsi * 0.5f);
|
||||
lamp->spotbl = (1.0f - lamp->spotsi) * la->spotblend;
|
||||
lamp->k = la->k;
|
||||
|
||||
lamp->dist = la->dist;
|
||||
lamp->falloff_type = la->falloff_type;
|
||||
lamp->att1 = la->att1;
|
||||
lamp->att2 = la->att2;
|
||||
lamp->coeff_const = la->coeff_const;
|
||||
lamp->coeff_lin = la->coeff_lin;
|
||||
lamp->coeff_quad = la->coeff_quad;
|
||||
lamp->curfalloff = la->curfalloff;
|
||||
|
||||
/* initshadowbuf */
|
||||
lamp->bias = 0.02f * la->bias;
|
||||
lamp->size = la->bufsize;
|
||||
lamp->d = la->clipsta;
|
||||
lamp->clipend = la->clipend;
|
||||
|
||||
/* arbitrary correction for the fact we do no soft transition */
|
||||
lamp->bias *= 0.25f;
|
||||
}
|
||||
|
||||
static void gpu_lamp_shadow_free(GPULamp *lamp)
|
||||
{
|
||||
if (lamp->tex) {
|
||||
GPU_texture_free(lamp->tex);
|
||||
lamp->tex = NULL;
|
||||
}
|
||||
if (lamp->depthtex) {
|
||||
GPU_texture_free(lamp->depthtex);
|
||||
lamp->depthtex = NULL;
|
||||
}
|
||||
if (lamp->fb) {
|
||||
GPU_framebuffer_free(lamp->fb);
|
||||
lamp->fb = NULL;
|
||||
}
|
||||
if (lamp->blurtex) {
|
||||
GPU_texture_free(lamp->blurtex);
|
||||
lamp->blurtex = NULL;
|
||||
}
|
||||
if (lamp->blurfb) {
|
||||
GPU_framebuffer_free(lamp->blurfb);
|
||||
lamp->blurfb = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static GPUTexture *gpu_lamp_create_vsm_shadow_map(int size)
|
||||
{
|
||||
return GPU_texture_create_2D_custom(size, size, 2, GPU_RG32F, NULL, NULL);
|
||||
}
|
||||
|
||||
GPULamp *GPU_lamp_from_engine(Scene *scene, Object *ob, Object *par, struct RenderEngineType *re)
|
||||
{
|
||||
GPULamp *lamp;
|
||||
LinkData *link;
|
||||
|
||||
for (link = ob->gpulamp.first; link; link = link->next) {
|
||||
lamp = (GPULamp *)link->data;
|
||||
|
||||
if ((lamp->par == par) && (lamp->scene == scene) && (lamp->re == re))
|
||||
return link->data;
|
||||
}
|
||||
|
||||
lamp = MEM_callocN(sizeof(GPULamp), "GPULamp");
|
||||
|
||||
link = MEM_callocN(sizeof(LinkData), "GPULampLink");
|
||||
link->data = lamp;
|
||||
BLI_addtail(&ob->gpulamp, link);
|
||||
|
||||
lamp->scene = scene;
|
||||
lamp->ob = ob;
|
||||
lamp->par = par;
|
||||
lamp->la = ob->data;
|
||||
lamp->re = re;
|
||||
|
||||
return lamp;
|
||||
}
|
||||
|
||||
GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
|
||||
{
|
||||
Lamp *la;
|
||||
GPULamp *lamp;
|
||||
LinkData *link;
|
||||
|
||||
for (link = ob->gpulamp.first; link; link = link->next) {
|
||||
lamp = (GPULamp *)link->data;
|
||||
|
||||
if (lamp->par == par && lamp->scene == scene)
|
||||
return link->data;
|
||||
}
|
||||
|
||||
lamp = MEM_callocN(sizeof(GPULamp), "GPULamp");
|
||||
|
||||
link = MEM_callocN(sizeof(LinkData), "GPULampLink");
|
||||
link->data = lamp;
|
||||
BLI_addtail(&ob->gpulamp, link);
|
||||
|
||||
la = ob->data;
|
||||
gpu_lamp_from_blender(scene, ob, par, la, lamp);
|
||||
|
||||
if ((la->type == LA_SPOT && (la->mode & (LA_SHAD_BUF | LA_SHAD_RAY))) ||
|
||||
(la->type == LA_SUN && (la->mode & LA_SHAD_RAY)))
|
||||
{
|
||||
/* opengl */
|
||||
lamp->fb = GPU_framebuffer_create();
|
||||
if (!lamp->fb) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
|
||||
if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
|
||||
/* Shadow depth map */
|
||||
lamp->depthtex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
|
||||
if (!lamp->depthtex) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
|
||||
if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->depthtex, 0)) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
|
||||
/* Shadow color map */
|
||||
lamp->tex = gpu_lamp_create_vsm_shadow_map(lamp->size);
|
||||
if (!lamp->tex) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
|
||||
if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0)) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
|
||||
if (!GPU_framebuffer_check_valid(lamp->fb, NULL)) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
|
||||
/* FBO and texture for blurring */
|
||||
lamp->blurfb = GPU_framebuffer_create();
|
||||
if (!lamp->blurfb) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
|
||||
lamp->blurtex = gpu_lamp_create_vsm_shadow_map(lamp->size * 0.5);
|
||||
if (!lamp->blurtex) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
|
||||
if (!GPU_framebuffer_texture_attach(lamp->blurfb, lamp->blurtex, 0)) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
|
||||
/* we need to properly bind to test for completeness */
|
||||
GPU_texture_bind_as_framebuffer(lamp->blurtex);
|
||||
|
||||
if (!GPU_framebuffer_check_valid(lamp->blurfb, NULL)) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
|
||||
GPU_framebuffer_texture_unbind(lamp->blurfb, lamp->blurtex);
|
||||
}
|
||||
else {
|
||||
lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
|
||||
if (!lamp->tex) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
|
||||
if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0)) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
|
||||
if (!GPU_framebuffer_check_valid(lamp->fb, NULL)) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
}
|
||||
|
||||
GPU_framebuffer_restore();
|
||||
|
||||
lamp->shadow_color[0] = la->shdwr;
|
||||
lamp->shadow_color[1] = la->shdwg;
|
||||
lamp->shadow_color[2] = la->shdwb;
|
||||
}
|
||||
else {
|
||||
lamp->shadow_color[0] = 1.0;
|
||||
lamp->shadow_color[1] = 1.0;
|
||||
lamp->shadow_color[2] = 1.0;
|
||||
}
|
||||
|
||||
return lamp;
|
||||
}
|
||||
|
||||
void GPU_lamp_free(Object *ob)
|
||||
{
|
||||
GPULamp *lamp;
|
||||
LinkData *link;
|
||||
LinkData *nlink;
|
||||
Material *ma;
|
||||
|
||||
for (link = ob->gpulamp.first; link; link = link->next) {
|
||||
lamp = link->data;
|
||||
|
||||
while (lamp->materials.first) {
|
||||
nlink = lamp->materials.first;
|
||||
ma = nlink->data;
|
||||
BLI_freelinkN(&lamp->materials, nlink);
|
||||
|
||||
if (ma->gpumaterial.first)
|
||||
GPU_material_free(&ma->gpumaterial);
|
||||
}
|
||||
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
|
||||
MEM_freeN(lamp);
|
||||
}
|
||||
|
||||
BLI_freelistN(&ob->gpulamp);
|
||||
}
|
||||
|
||||
bool GPU_lamp_has_shadow_buffer(GPULamp *lamp)
|
||||
{
|
||||
return (!(lamp->scene->gm.flag & GAME_GLSL_NO_SHADOWS) &&
|
||||
!(lamp->scene->gm.flag & GAME_GLSL_NO_LIGHTS) &&
|
||||
lamp->tex && lamp->fb);
|
||||
}
|
||||
|
||||
void GPU_lamp_update_buffer_mats(GPULamp *lamp)
|
||||
{
|
||||
float rangemat[4][4], persmat[4][4];
|
||||
|
||||
/* initshadowbuf */
|
||||
invert_m4_m4(lamp->viewmat, lamp->obmat);
|
||||
normalize_v3(lamp->viewmat[0]);
|
||||
normalize_v3(lamp->viewmat[1]);
|
||||
normalize_v3(lamp->viewmat[2]);
|
||||
|
||||
/* makeshadowbuf */
|
||||
mul_m4_m4m4(persmat, lamp->winmat, lamp->viewmat);
|
||||
|
||||
/* opengl depth buffer is range 0.0..1.0 instead of -1.0..1.0 in blender */
|
||||
unit_m4(rangemat);
|
||||
rangemat[0][0] = 0.5f;
|
||||
rangemat[1][1] = 0.5f;
|
||||
rangemat[2][2] = 0.5f;
|
||||
rangemat[3][0] = 0.5f;
|
||||
rangemat[3][1] = 0.5f;
|
||||
rangemat[3][2] = 0.5f;
|
||||
|
||||
mul_m4_m4m4(lamp->persmat, rangemat, persmat);
|
||||
}
|
||||
|
||||
void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4])
|
||||
{
|
||||
GPU_lamp_update_buffer_mats(lamp);
|
||||
|
||||
/* opengl */
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
GPU_texture_bind_as_framebuffer(lamp->tex);
|
||||
if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE)
|
||||
GPU_shader_bind(GPU_shader_get_builtin_shader(GPU_SHADER_VSM_STORE));
|
||||
|
||||
/* set matrices */
|
||||
copy_m4_m4(viewmat, lamp->viewmat);
|
||||
copy_m4_m4(winmat, lamp->winmat);
|
||||
*winsize = lamp->size;
|
||||
}
|
||||
|
||||
void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp)
|
||||
{
|
||||
if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
|
||||
GPU_shader_unbind();
|
||||
GPU_framebuffer_blur(lamp->fb, lamp->tex, lamp->blurfb, lamp->blurtex);
|
||||
}
|
||||
|
||||
GPU_framebuffer_texture_unbind(lamp->fb, lamp->tex);
|
||||
GPU_framebuffer_restore();
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
int GPU_lamp_shadow_buffer_type(GPULamp *lamp)
|
||||
{
|
||||
return lamp->la->shadowmap_type;
|
||||
}
|
||||
|
||||
int GPU_lamp_shadow_bind_code(GPULamp *lamp)
|
||||
{
|
||||
return lamp->tex ? GPU_texture_opengl_bindcode(lamp->tex) : -1;
|
||||
}
|
||||
|
||||
float *GPU_lamp_dynpersmat(GPULamp *lamp)
|
||||
{
|
||||
return &lamp->dynpersmat[0][0];
|
||||
}
|
||||
|
||||
int GPU_lamp_shadow_layer(GPULamp *lamp)
|
||||
{
|
||||
if (lamp->fb && lamp->tex && (lamp->mode & (LA_LAYER | LA_LAYER_SHADOW)))
|
||||
return lamp->lay;
|
||||
else
|
||||
return -1;
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2005 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Brecht Van Lommel, Clément Foucault.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file gpu_lamp_private.h
|
||||
* \ingroup gpu
|
||||
*/
|
||||
|
||||
#ifndef __GPU_LAMP_PRIVATE_H__
|
||||
#define __GPU_LAMP_PRIVATE_H__
|
||||
|
||||
#include "BLI_sys_types.h" /* for bool */
|
||||
|
||||
struct GPULamp {
|
||||
Scene *scene;
|
||||
Object *ob;
|
||||
Object *par;
|
||||
Lamp *la;
|
||||
struct RenderEngineType *re;
|
||||
|
||||
/* Old Viewport (pre-2.8) */
|
||||
int type, mode, lay, hide;
|
||||
|
||||
float dynenergy, dyncol[3];
|
||||
float energy, col[3];
|
||||
|
||||
float co[3], vec[3];
|
||||
float dynco[3], dynvec[3];
|
||||
float obmat[4][4];
|
||||
float imat[4][4];
|
||||
float dynimat[4][4];
|
||||
|
||||
float spotsi, spotbl, k;
|
||||
float spotvec[2];
|
||||
float dyndist, dynatt1, dynatt2;
|
||||
float dist, att1, att2;
|
||||
float coeff_const, coeff_lin, coeff_quad;
|
||||
float shadow_color[3];
|
||||
|
||||
float bias, d, clipend;
|
||||
int size;
|
||||
|
||||
int falloff_type;
|
||||
struct CurveMapping *curfalloff;
|
||||
|
||||
float winmat[4][4];
|
||||
float viewmat[4][4];
|
||||
float persmat[4][4];
|
||||
float dynpersmat[4][4];
|
||||
|
||||
GPUFrameBuffer *fb;
|
||||
GPUFrameBuffer *blurfb;
|
||||
GPUTexture *tex;
|
||||
GPUTexture *depthtex;
|
||||
GPUTexture *blurtex;
|
||||
|
||||
ListBase materials;
|
||||
|
||||
/* New viewport */
|
||||
struct LampEngineData data;
|
||||
};
|
||||
|
||||
#endif /* __GPU_LAMP_PRIVATE_H__ */
|
|
@ -60,11 +60,13 @@
|
|||
|
||||
#include "GPU_extensions.h"
|
||||
#include "GPU_framebuffer.h"
|
||||
#include "GPU_lamp.h"
|
||||
#include "GPU_material.h"
|
||||
#include "GPU_shader.h"
|
||||
#include "GPU_texture.h"
|
||||
|
||||
#include "gpu_codegen.h"
|
||||
#include "gpu_lamp_private.h"
|
||||
|
||||
#ifdef WITH_OPENSUBDIV
|
||||
# include "BKE_DerivedMesh.h"
|
||||
|
@ -128,50 +130,6 @@ struct GPUMaterial {
|
|||
bool is_opensubdiv;
|
||||
};
|
||||
|
||||
struct GPULamp {
|
||||
Scene *scene;
|
||||
Object *ob;
|
||||
Object *par;
|
||||
Lamp *la;
|
||||
|
||||
int type, mode, lay, hide;
|
||||
|
||||
float dynenergy, dyncol[3];
|
||||
float energy, col[3];
|
||||
|
||||
float co[3], vec[3];
|
||||
float dynco[3], dynvec[3];
|
||||
float obmat[4][4];
|
||||
float imat[4][4];
|
||||
float dynimat[4][4];
|
||||
|
||||
float spotsi, spotbl, k;
|
||||
float spotvec[2];
|
||||
float dyndist, dynatt1, dynatt2;
|
||||
float dist, att1, att2;
|
||||
float coeff_const, coeff_lin, coeff_quad;
|
||||
float shadow_color[3];
|
||||
|
||||
float bias, d, clipend;
|
||||
int size;
|
||||
|
||||
int falloff_type;
|
||||
struct CurveMapping *curfalloff;
|
||||
|
||||
float winmat[4][4];
|
||||
float viewmat[4][4];
|
||||
float persmat[4][4];
|
||||
float dynpersmat[4][4];
|
||||
|
||||
GPUFrameBuffer *fb;
|
||||
GPUFrameBuffer *blurfb;
|
||||
GPUTexture *tex;
|
||||
GPUTexture *depthtex;
|
||||
GPUTexture *blurtex;
|
||||
|
||||
ListBase materials;
|
||||
};
|
||||
|
||||
/* Forward declaration so shade_light_textures() can use this, while still keeping the code somewhat organized */
|
||||
static void texture_rgb_blend(
|
||||
GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg,
|
||||
|
@ -308,16 +266,6 @@ void GPU_material_free(ListBase *gpumaterial)
|
|||
BLI_freelistN(gpumaterial);
|
||||
}
|
||||
|
||||
bool GPU_lamp_override_visible(GPULamp *lamp, SceneRenderLayer *srl, Material *ma)
|
||||
{
|
||||
if (srl && srl->light_override)
|
||||
return BKE_group_object_exists(srl->light_override, lamp->ob);
|
||||
else if (ma && ma->group)
|
||||
return BKE_group_object_exists(ma->group, lamp->ob);
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
void GPU_material_bind(
|
||||
GPUMaterial *material, int oblay, int viewlay, double time, int mipmap,
|
||||
float viewmat[4][4], float viewinv[4][4], float camerafactors[4], bool scenelock)
|
||||
|
@ -2222,391 +2170,6 @@ void GPU_materials_free(void)
|
|||
|
||||
/* Lamps and shadow buffers */
|
||||
|
||||
static void gpu_lamp_calc_winmat(GPULamp *lamp)
|
||||
{
|
||||
float temp, angle, pixsize, wsize;
|
||||
|
||||
if (lamp->type == LA_SUN) {
|
||||
wsize = lamp->la->shadow_frustum_size;
|
||||
orthographic_m4(lamp->winmat, -wsize, wsize, -wsize, wsize, lamp->d, lamp->clipend);
|
||||
}
|
||||
else if (lamp->type == LA_SPOT) {
|
||||
angle = saacos(lamp->spotsi);
|
||||
temp = 0.5f * lamp->size * cosf(angle) / sinf(angle);
|
||||
pixsize = lamp->d / temp;
|
||||
wsize = pixsize * 0.5f * lamp->size;
|
||||
/* compute shadows according to X and Y scaling factors */
|
||||
perspective_m4(
|
||||
lamp->winmat,
|
||||
-wsize * lamp->spotvec[0], wsize * lamp->spotvec[0],
|
||||
-wsize * lamp->spotvec[1], wsize * lamp->spotvec[1],
|
||||
lamp->d, lamp->clipend);
|
||||
}
|
||||
}
|
||||
|
||||
void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4])
|
||||
{
|
||||
float mat[4][4];
|
||||
float obmat_scale[3];
|
||||
|
||||
lamp->lay = lay;
|
||||
lamp->hide = hide;
|
||||
|
||||
normalize_m4_m4_ex(mat, obmat, obmat_scale);
|
||||
|
||||
copy_v3_v3(lamp->vec, mat[2]);
|
||||
copy_v3_v3(lamp->co, mat[3]);
|
||||
copy_m4_m4(lamp->obmat, mat);
|
||||
invert_m4_m4(lamp->imat, mat);
|
||||
|
||||
if (lamp->type == LA_SPOT) {
|
||||
/* update spotlamp scale on X and Y axis */
|
||||
lamp->spotvec[0] = obmat_scale[0] / obmat_scale[2];
|
||||
lamp->spotvec[1] = obmat_scale[1] / obmat_scale[2];
|
||||
}
|
||||
|
||||
if (GPU_lamp_has_shadow_buffer(lamp)) {
|
||||
/* makeshadowbuf */
|
||||
gpu_lamp_calc_winmat(lamp);
|
||||
}
|
||||
}
|
||||
|
||||
void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy)
|
||||
{
|
||||
lamp->energy = energy;
|
||||
if (lamp->mode & LA_NEG) lamp->energy = -lamp->energy;
|
||||
|
||||
lamp->col[0] = r;
|
||||
lamp->col[1] = g;
|
||||
lamp->col[2] = b;
|
||||
}
|
||||
|
||||
void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2,
|
||||
float coeff_const, float coeff_lin, float coeff_quad)
|
||||
{
|
||||
lamp->dist = distance;
|
||||
lamp->att1 = att1;
|
||||
lamp->att2 = att2;
|
||||
lamp->coeff_const = coeff_const;
|
||||
lamp->coeff_lin = coeff_lin;
|
||||
lamp->coeff_quad = coeff_quad;
|
||||
}
|
||||
|
||||
void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend)
|
||||
{
|
||||
lamp->spotsi = cosf(spotsize * 0.5f);
|
||||
lamp->spotbl = (1.0f - lamp->spotsi) * spotblend;
|
||||
}
|
||||
|
||||
static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *la, GPULamp *lamp)
|
||||
{
|
||||
lamp->scene = scene;
|
||||
lamp->ob = ob;
|
||||
lamp->par = par;
|
||||
lamp->la = la;
|
||||
|
||||
/* add_render_lamp */
|
||||
lamp->mode = la->mode;
|
||||
lamp->type = la->type;
|
||||
|
||||
lamp->energy = la->energy;
|
||||
if (lamp->mode & LA_NEG) lamp->energy = -lamp->energy;
|
||||
|
||||
lamp->col[0] = la->r;
|
||||
lamp->col[1] = la->g;
|
||||
lamp->col[2] = la->b;
|
||||
|
||||
GPU_lamp_update(lamp, ob->lay, (ob->restrictflag & OB_RESTRICT_RENDER), ob->obmat);
|
||||
|
||||
lamp->spotsi = la->spotsize;
|
||||
if (lamp->mode & LA_HALO)
|
||||
if (lamp->spotsi > DEG2RADF(170.0f))
|
||||
lamp->spotsi = DEG2RADF(170.0f);
|
||||
lamp->spotsi = cosf(lamp->spotsi * 0.5f);
|
||||
lamp->spotbl = (1.0f - lamp->spotsi) * la->spotblend;
|
||||
lamp->k = la->k;
|
||||
|
||||
lamp->dist = la->dist;
|
||||
lamp->falloff_type = la->falloff_type;
|
||||
lamp->att1 = la->att1;
|
||||
lamp->att2 = la->att2;
|
||||
lamp->coeff_const = la->coeff_const;
|
||||
lamp->coeff_lin = la->coeff_lin;
|
||||
lamp->coeff_quad = la->coeff_quad;
|
||||
lamp->curfalloff = la->curfalloff;
|
||||
|
||||
/* initshadowbuf */
|
||||
lamp->bias = 0.02f * la->bias;
|
||||
lamp->size = la->bufsize;
|
||||
lamp->d = la->clipsta;
|
||||
lamp->clipend = la->clipend;
|
||||
|
||||
/* arbitrary correction for the fact we do no soft transition */
|
||||
lamp->bias *= 0.25f;
|
||||
}
|
||||
|
||||
static void gpu_lamp_shadow_free(GPULamp *lamp)
|
||||
{
|
||||
if (lamp->tex) {
|
||||
GPU_texture_free(lamp->tex);
|
||||
lamp->tex = NULL;
|
||||
}
|
||||
if (lamp->depthtex) {
|
||||
GPU_texture_free(lamp->depthtex);
|
||||
lamp->depthtex = NULL;
|
||||
}
|
||||
if (lamp->fb) {
|
||||
GPU_framebuffer_free(lamp->fb);
|
||||
lamp->fb = NULL;
|
||||
}
|
||||
if (lamp->blurtex) {
|
||||
GPU_texture_free(lamp->blurtex);
|
||||
lamp->blurtex = NULL;
|
||||
}
|
||||
if (lamp->blurfb) {
|
||||
GPU_framebuffer_free(lamp->blurfb);
|
||||
lamp->blurfb = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static GPUTexture *gpu_lamp_create_vsm_shadow_map(int size)
|
||||
{
|
||||
return GPU_texture_create_2D_custom(size, size, 2, GPU_RG32F, NULL, NULL);
|
||||
}
|
||||
|
||||
GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
|
||||
{
|
||||
Lamp *la;
|
||||
GPULamp *lamp;
|
||||
LinkData *link;
|
||||
|
||||
for (link = ob->gpulamp.first; link; link = link->next) {
|
||||
lamp = (GPULamp *)link->data;
|
||||
|
||||
if (lamp->par == par && lamp->scene == scene)
|
||||
return link->data;
|
||||
}
|
||||
|
||||
lamp = MEM_callocN(sizeof(GPULamp), "GPULamp");
|
||||
|
||||
link = MEM_callocN(sizeof(LinkData), "GPULampLink");
|
||||
link->data = lamp;
|
||||
BLI_addtail(&ob->gpulamp, link);
|
||||
|
||||
la = ob->data;
|
||||
gpu_lamp_from_blender(scene, ob, par, la, lamp);
|
||||
|
||||
if ((la->type == LA_SPOT && (la->mode & (LA_SHAD_BUF | LA_SHAD_RAY))) ||
|
||||
(la->type == LA_SUN && (la->mode & LA_SHAD_RAY)))
|
||||
{
|
||||
/* opengl */
|
||||
lamp->fb = GPU_framebuffer_create();
|
||||
if (!lamp->fb) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
|
||||
if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
|
||||
/* Shadow depth map */
|
||||
lamp->depthtex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
|
||||
if (!lamp->depthtex) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
|
||||
if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->depthtex, 0)) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
|
||||
/* Shadow color map */
|
||||
lamp->tex = gpu_lamp_create_vsm_shadow_map(lamp->size);
|
||||
if (!lamp->tex) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
|
||||
if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0)) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
|
||||
if (!GPU_framebuffer_check_valid(lamp->fb, NULL)) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
|
||||
/* FBO and texture for blurring */
|
||||
lamp->blurfb = GPU_framebuffer_create();
|
||||
if (!lamp->blurfb) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
|
||||
lamp->blurtex = gpu_lamp_create_vsm_shadow_map(lamp->size * 0.5);
|
||||
if (!lamp->blurtex) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
|
||||
if (!GPU_framebuffer_texture_attach(lamp->blurfb, lamp->blurtex, 0)) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
|
||||
/* we need to properly bind to test for completeness */
|
||||
GPU_texture_bind_as_framebuffer(lamp->blurtex);
|
||||
|
||||
if (!GPU_framebuffer_check_valid(lamp->blurfb, NULL)) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
|
||||
GPU_framebuffer_texture_unbind(lamp->blurfb, lamp->blurtex);
|
||||
}
|
||||
else {
|
||||
lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
|
||||
if (!lamp->tex) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
|
||||
if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0)) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
|
||||
if (!GPU_framebuffer_check_valid(lamp->fb, NULL)) {
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
return lamp;
|
||||
}
|
||||
}
|
||||
|
||||
GPU_framebuffer_restore();
|
||||
|
||||
lamp->shadow_color[0] = la->shdwr;
|
||||
lamp->shadow_color[1] = la->shdwg;
|
||||
lamp->shadow_color[2] = la->shdwb;
|
||||
}
|
||||
else {
|
||||
lamp->shadow_color[0] = 1.0;
|
||||
lamp->shadow_color[1] = 1.0;
|
||||
lamp->shadow_color[2] = 1.0;
|
||||
}
|
||||
|
||||
return lamp;
|
||||
}
|
||||
|
||||
void GPU_lamp_free(Object *ob)
|
||||
{
|
||||
GPULamp *lamp;
|
||||
LinkData *link;
|
||||
LinkData *nlink;
|
||||
Material *ma;
|
||||
|
||||
for (link = ob->gpulamp.first; link; link = link->next) {
|
||||
lamp = link->data;
|
||||
|
||||
while (lamp->materials.first) {
|
||||
nlink = lamp->materials.first;
|
||||
ma = nlink->data;
|
||||
BLI_freelinkN(&lamp->materials, nlink);
|
||||
|
||||
if (ma->gpumaterial.first)
|
||||
GPU_material_free(&ma->gpumaterial);
|
||||
}
|
||||
|
||||
gpu_lamp_shadow_free(lamp);
|
||||
|
||||
MEM_freeN(lamp);
|
||||
}
|
||||
|
||||
BLI_freelistN(&ob->gpulamp);
|
||||
}
|
||||
|
||||
bool GPU_lamp_has_shadow_buffer(GPULamp *lamp)
|
||||
{
|
||||
return (!(lamp->scene->gm.flag & GAME_GLSL_NO_SHADOWS) &&
|
||||
!(lamp->scene->gm.flag & GAME_GLSL_NO_LIGHTS) &&
|
||||
lamp->tex && lamp->fb);
|
||||
}
|
||||
|
||||
void GPU_lamp_update_buffer_mats(GPULamp *lamp)
|
||||
{
|
||||
float rangemat[4][4], persmat[4][4];
|
||||
|
||||
/* initshadowbuf */
|
||||
invert_m4_m4(lamp->viewmat, lamp->obmat);
|
||||
normalize_v3(lamp->viewmat[0]);
|
||||
normalize_v3(lamp->viewmat[1]);
|
||||
normalize_v3(lamp->viewmat[2]);
|
||||
|
||||
/* makeshadowbuf */
|
||||
mul_m4_m4m4(persmat, lamp->winmat, lamp->viewmat);
|
||||
|
||||
/* opengl depth buffer is range 0.0..1.0 instead of -1.0..1.0 in blender */
|
||||
unit_m4(rangemat);
|
||||
rangemat[0][0] = 0.5f;
|
||||
rangemat[1][1] = 0.5f;
|
||||
rangemat[2][2] = 0.5f;
|
||||
rangemat[3][0] = 0.5f;
|
||||
rangemat[3][1] = 0.5f;
|
||||
rangemat[3][2] = 0.5f;
|
||||
|
||||
mul_m4_m4m4(lamp->persmat, rangemat, persmat);
|
||||
}
|
||||
|
||||
void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4])
|
||||
{
|
||||
GPU_lamp_update_buffer_mats(lamp);
|
||||
|
||||
/* opengl */
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
GPU_texture_bind_as_framebuffer(lamp->tex);
|
||||
if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE)
|
||||
GPU_shader_bind(GPU_shader_get_builtin_shader(GPU_SHADER_VSM_STORE));
|
||||
|
||||
/* set matrices */
|
||||
copy_m4_m4(viewmat, lamp->viewmat);
|
||||
copy_m4_m4(winmat, lamp->winmat);
|
||||
*winsize = lamp->size;
|
||||
}
|
||||
|
||||
void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp)
|
||||
{
|
||||
if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
|
||||
GPU_shader_unbind();
|
||||
GPU_framebuffer_blur(lamp->fb, lamp->tex, lamp->blurfb, lamp->blurtex);
|
||||
}
|
||||
|
||||
GPU_framebuffer_texture_unbind(lamp->fb, lamp->tex);
|
||||
GPU_framebuffer_restore();
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
int GPU_lamp_shadow_buffer_type(GPULamp *lamp)
|
||||
{
|
||||
return lamp->la->shadowmap_type;
|
||||
}
|
||||
|
||||
int GPU_lamp_shadow_bind_code(GPULamp *lamp)
|
||||
{
|
||||
return lamp->tex ? GPU_texture_opengl_bindcode(lamp->tex) : -1;
|
||||
}
|
||||
|
||||
float *GPU_lamp_dynpersmat(GPULamp *lamp)
|
||||
{
|
||||
return &lamp->dynpersmat[0][0];
|
||||
}
|
||||
|
||||
int GPU_lamp_shadow_layer(GPULamp *lamp)
|
||||
{
|
||||
if (lamp->fb && lamp->tex && (lamp->mode & (LA_LAYER | LA_LAYER_SHADOW)))
|
||||
return lamp->lay;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
GPUNodeLink *GPU_lamp_get_data(
|
||||
GPUMaterial *mat, GPULamp *lamp,
|
||||
GPUNodeLink **r_col, GPUNodeLink **r_lv, GPUNodeLink **r_dist, GPUNodeLink **r_shadow, GPUNodeLink **r_energy)
|
||||
|
|
|
@ -76,6 +76,7 @@
|
|||
#include "RE_pipeline.h"
|
||||
#include "RE_shader_ext.h"
|
||||
|
||||
#include "GPU_lamp.h"
|
||||
#include "GPU_material.h"
|
||||
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "DNA_lamp_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "GPU_lamp.h"
|
||||
#include "GPU_material.h"
|
||||
|
||||
RAS_OpenGLLight::RAS_OpenGLLight(RAS_OpenGLRasterizer *ras)
|
||||
|
|
Loading…
Reference in New Issue