int GPC_RenderTools::applyLights(int objectlayer, const MT_Transform& viewmat) { // taken from blender source, incompatibility between Blender Object / GameObject KX_Scene* kxscene = (KX_Scene*)m_auxilaryClientInfo; float glviewmat[16]; unsigned int count; std::vector<struct RAS_LightObject*>::iterator lit = m_lights.begin(); for(count=0; count<m_numgllights; count++) glDisable((GLenum)(GL_LIGHT0+count)); viewmat.getValue(glviewmat); glPushMatrix(); glLoadMatrixf(glviewmat); for (lit = m_lights.begin(), count = 0; !(lit==m_lights.end()) && count < m_numgllights; ++lit) { RAS_LightObject* lightdata = (*lit); KX_LightObject *kxlight = (KX_LightObject*)lightdata->m_light; if(kxlight->ApplyLight(kxscene, objectlayer, count)) count++; } glPopMatrix(); return count; }
GPULamp *RAS_OpenGLLight::GetGPULamp() { KX_LightObject* kxlight = (KX_LightObject*)m_light; if (m_glsl) return GPU_lamp_from_blender(kxlight->GetScene()->GetBlenderScene(), kxlight->GetBlenderObject(), kxlight->GetBlenderGroupObject()); else return NULL; }
CValue* KX_LightObject::GetReplica() { KX_LightObject* replica = new KX_LightObject(*this); replica->ProcessReplica(); replica->m_lightobj.m_light = replica; m_rendertools->AddLight(&replica->m_lightobj); return replica; }
void RAS_OpenGLRasterizer::ProcessLighting(bool uselights, const MT_Transform& viewmat) { bool enable = false; int layer= -1; /* find the layer */ if (uselights) { if (m_clientobject) layer = static_cast<KX_GameObject*>(m_clientobject)->GetLayer(); } /* avoid state switching */ if (m_lastlightlayer == layer && m_lastauxinfo == m_auxilaryClientInfo) return; m_lastlightlayer = layer; m_lastauxinfo = m_auxilaryClientInfo; /* enable/disable lights as needed */ if (layer >= 0) { //enable = ApplyLights(layer, viewmat); // taken from blender source, incompatibility between Blender Object / GameObject KX_Scene* kxscene = (KX_Scene*)m_auxilaryClientInfo; float glviewmat[16]; unsigned int count; std::vector<struct RAS_LightObject*>::iterator lit = m_lights.begin(); for (count=0; count<m_numgllights; count++) glDisable((GLenum)(GL_LIGHT0+count)); viewmat.getValue(glviewmat); glPushMatrix(); glLoadMatrixf(glviewmat); for (lit = m_lights.begin(), count = 0; !(lit==m_lights.end()) && count < m_numgllights; ++lit) { RAS_LightObject* lightdata = (*lit); KX_LightObject *kxlight = (KX_LightObject*)lightdata->m_light; if (kxlight->ApplyLight(kxscene, layer, count)) count++; } glPopMatrix(); enable = count > 0; } if (enable) EnableOpenGLLights(); else DisableOpenGLLights(); }
RAS_OpenGLLight::~RAS_OpenGLLight() { GPULamp *lamp; KX_LightObject *kxlight = (KX_LightObject *)m_light; Lamp *la = (Lamp *)kxlight->GetBlenderObject()->data; if ((lamp = GetGPULamp())) { float obmat[4][4] = {{0}}; GPU_lamp_update(lamp, 0, 0, obmat); GPU_lamp_update_distance(lamp, la->dist, la->att1, la->att2, la->coeff_const, la->coeff_lin, la->coeff_quad); GPU_lamp_update_spot(lamp, la->spotsize, la->spotblend); } }
CValue* KX_LightObject::GetReplica() { KX_LightObject* replica = new KX_LightObject(*this); replica->ProcessReplica(); replica->m_lightobj = m_lightobj->Clone(); replica->m_lightobj->m_light = replica; m_rasterizer->AddLight(replica->m_lightobj); if (m_base) m_base = NULL; return replica; }
Image *RAS_OpenGLLight::GetTextureImage(short texslot) { KX_LightObject *kxlight = (KX_LightObject *)m_light; Lamp *la = (Lamp *)kxlight->GetBlenderObject()->data; if (texslot >= MAX_MTEX || texslot < 0) { printf("KX_LightObject::GetTextureImage(): texslot exceeds slot bounds (0-%d)\n", MAX_MTEX - 1); return NULL; } if (la->mtex[texslot]) return la->mtex[texslot]->tex->ima; return NULL; }
int KX_LightObject::pyattr_set_layer(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) { KX_LightObject *self = static_cast<KX_LightObject *>(self_v); int layer = PyLong_AsLong(value); if (layer == -1 && PyErr_Occurred()) { PyErr_Format(PyExc_TypeError, "expected an integer for attribute \"%s\"", attrdef->m_name); return PY_SET_ATTR_FAIL; } if (layer < 1) { PyErr_Format(PyExc_TypeError, "expected an integer greater than 1 for attribute \"%s\"", attrdef->m_name); return PY_SET_ATTR_FAIL; } else if(layer > MAX_LIGHT_LAYERS) { PyErr_Format(PyExc_TypeError, "expected an integer less than %i for attribute \"%s\"", MAX_LIGHT_LAYERS, attrdef->m_name); return PY_SET_ATTR_FAIL; } self->SetLayer(layer); return PY_SET_ATTR_SUCCESS; }
void RAS_OpenGLLight::Update() { GPULamp *lamp; KX_LightObject* kxlight = (KX_LightObject*)m_light; if ((lamp = GetGPULamp()) != NULL && kxlight->GetSGNode()) { float obmat[4][4]; // lights don't get their openGL matrix updated, do it now if (kxlight->GetSGNode()->IsDirty()) kxlight->GetOpenGLMatrix(); float *dobmat = kxlight->GetOpenGLMatrixPtr()->getPointer(); for (int i=0; i<4; i++) for (int j=0; j<4; j++, dobmat++) obmat[i][j] = (float)*dobmat; GPU_lamp_update(lamp, m_layer, 0, obmat); GPU_lamp_update_colors(lamp, m_color[0], m_color[1], m_color[2], m_energy); GPU_lamp_update_distance(lamp, m_distance, m_att1, m_att2); GPU_lamp_update_spot(lamp, m_spotsize, m_spotblend); } }
void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene) { CListValue *lightlist = scene->GetLightList(); int i, drawmode; m_rendertools->SetAuxilaryClientInfo(scene); for(i=0; i<lightlist->GetCount(); i++) { KX_GameObject *gameobj = (KX_GameObject*)lightlist->GetValue(i); KX_LightObject *light = (KX_LightObject*)gameobj; light->Update(); if(m_drawingmode == RAS_IRasterizer::KX_TEXTURED && light->HasShadowBuffer()) { /* make temporary camera */ RAS_CameraData camdata = RAS_CameraData(); KX_Camera *cam = new KX_Camera(scene, scene->m_callbacks, camdata, true, true); cam->SetName("__shadow__cam__"); MT_Transform camtrans; /* switch drawmode for speed */ drawmode = m_rasterizer->GetDrawingMode(); m_rasterizer->SetDrawingMode(RAS_IRasterizer::KX_SHADOW); /* binds framebuffer object, sets up camera .. */ light->BindShadowBuffer(m_rasterizer, cam, camtrans); /* update scene */ scene->CalculateVisibleMeshes(m_rasterizer, cam, light->GetShadowLayer()); /* render */ m_rasterizer->ClearDepthBuffer(); scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools); /* unbind framebuffer object, restore drawmode, free camera */ light->UnbindShadowBuffer(m_rasterizer); m_rasterizer->SetDrawingMode(drawmode); cam->Release(); } } }
bool RAS_OpenGLLight::ApplyFixedFunctionLighting(KX_Scene *kxscene, int oblayer, int slot) { KX_Scene *lightscene = (KX_Scene *)m_scene; KX_LightObject *kxlight = (KX_LightObject *)m_light; float vec[4]; int scenelayer = ~0; if (kxscene && kxscene->GetBlenderScene()) scenelayer = kxscene->GetBlenderScene()->lay; /* only use lights in the same layer as the object */ if (!(m_layer & oblayer)) return false; /* only use lights in the same scene, and in a visible layer */ if (kxscene != lightscene || !(m_layer & scenelayer)) return false; // lights don't get their openGL matrix updated, do it now if (kxlight->GetSGNode()->IsDirty()) kxlight->GetOpenGLMatrix(); MT_CmMatrix4x4& worldmatrix = *kxlight->GetOpenGLMatrixPtr(); vec[0] = worldmatrix(0, 3); vec[1] = worldmatrix(1, 3); vec[2] = worldmatrix(2, 3); vec[3] = 1.0f; if (m_type == RAS_ILightObject::LIGHT_SUN) { vec[0] = worldmatrix(0, 2); vec[1] = worldmatrix(1, 2); vec[2] = worldmatrix(2, 2); //vec[0] = base->object->obmat[2][0]; //vec[1] = base->object->obmat[2][1]; //vec[2] = base->object->obmat[2][2]; vec[3] = 0.0f; glLightfv((GLenum)(GL_LIGHT0 + slot), GL_POSITION, vec); } else { //vec[3] = 1.0; glLightfv((GLenum)(GL_LIGHT0 + slot), GL_POSITION, vec); glLightf((GLenum)(GL_LIGHT0 + slot), GL_CONSTANT_ATTENUATION, 1.0f); glLightf((GLenum)(GL_LIGHT0 + slot), GL_LINEAR_ATTENUATION, m_att1 / m_distance); // without this next line it looks backward compatible. //attennuation still is acceptable glLightf((GLenum)(GL_LIGHT0 + slot), GL_QUADRATIC_ATTENUATION, m_att2 / (m_distance * m_distance)); if (m_type == RAS_ILightObject::LIGHT_SPOT) { vec[0] = -worldmatrix(0, 2); vec[1] = -worldmatrix(1, 2); vec[2] = -worldmatrix(2, 2); //vec[0] = -base->object->obmat[2][0]; //vec[1] = -base->object->obmat[2][1]; //vec[2] = -base->object->obmat[2][2]; glLightfv((GLenum)(GL_LIGHT0 + slot), GL_SPOT_DIRECTION, vec); glLightf((GLenum)(GL_LIGHT0 + slot), GL_SPOT_CUTOFF, m_spotsize / 2.0f); glLightf((GLenum)(GL_LIGHT0 + slot), GL_SPOT_EXPONENT, 128.0f * m_spotblend); } else { glLightf((GLenum)(GL_LIGHT0 + slot), GL_SPOT_CUTOFF, 180.0f); } } if (m_nodiffuse) { vec[0] = vec[1] = vec[2] = vec[3] = 0.0f; } else { vec[0] = m_energy * m_color[0]; vec[1] = m_energy * m_color[1]; vec[2] = m_energy * m_color[2]; vec[3] = 1.0f; } glLightfv((GLenum)(GL_LIGHT0 + slot), GL_DIFFUSE, vec); if (m_nospecular) { vec[0] = vec[1] = vec[2] = vec[3] = 0.0f; } else if (m_nodiffuse) { vec[0] = m_energy * m_color[0]; vec[1] = m_energy * m_color[1]; vec[2] = m_energy * m_color[2]; vec[3] = 1.0f; } glLightfv((GLenum)(GL_LIGHT0 + slot), GL_SPECULAR, vec); glEnable((GLenum)(GL_LIGHT0 + slot)); return true; }
// Texture object initialization static int Texture_init(Texture *self, PyObject *args, PyObject *kwds) { // parameters - game object with video texture PyObject *obj = NULL; // material ID short matID = 0; // texture ID short texID = 0; // texture object with shared texture ID Texture * texObj = NULL; static const char *kwlist[] = {"gameObj", "materialID", "textureID", "textureObj", NULL}; // get parameters if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|hhO!", const_cast<char**>(kwlist), &obj, &matID, &texID, &TextureType, &texObj)) return -1; // if parameters are available if (obj != NULL) { // process polygon material or blender material try { // get pointer to texture image RAS_IPolyMaterial * mat = getMaterial(obj, matID); KX_LightObject * lamp = getLamp(obj); if (mat != NULL) { // is it blender material or polygon material if (mat->GetFlag() & RAS_BLENDERGLSL) { self->m_imgTexture = static_cast<KX_BlenderMaterial*>(mat)->getImage(texID); self->m_useMatTexture = false; } else { // get blender material texture self->m_matTexture = static_cast<KX_BlenderMaterial*>(mat)->getTex(texID); self->m_useMatTexture = true; } } else if (lamp != NULL) { self->m_imgTexture = lamp->GetLightData()->GetTextureImage(texID); self->m_useMatTexture = false; } // check if texture is available, if not, initialization failed if (self->m_imgTexture == NULL && self->m_matTexture == NULL) // throw exception if initialization failed THRWEXCP(MaterialNotAvail, S_OK); // if texture object is provided if (texObj != NULL) { // copy texture code self->m_actTex = texObj->m_actTex; self->m_mipmap = texObj->m_mipmap; if (texObj->m_source != NULL) Texture_setSource(self, reinterpret_cast<PyObject*>(texObj->m_source), NULL); } else // otherwise generate texture code glGenTextures(1, (GLuint*)&self->m_actTex); } catch (Exception & exp) { exp.report(); return -1; } } // initialization succeded return 0; }