// Set light parameters (unused) void light_setparam(int param, double value) { switch(param){ case 1: Imodv_light_position[0] = value; break; case 2: Imodv_light_position[1] = value; break; case 3: Imodv_light_position[2] = value; break; case 4: Imodv_light_att[0] = value; glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, Imodv_light_att[0]); return; case 5: Imodv_light_att[1] = value; glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, Imodv_light_att[1]); return; case 6: Imodv_light_att[2] = value; glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, Imodv_light_att[2]); return; case 7: Imodv_light_dist = value; break; } light_update(); }
inline void update( char_data* ch ) { light_update( ch ); affect_update( ch ); if( !plague_update( ch ) ) poison_update( ch ); return; }
/* * Set the light position */ void light_move(int *x, int *y) { float xn,yn,zn; double xa, ya; int lim = 800; if (Imodv_light_dist > 0.0){ Imodv_light_position[0] = *x; Imodv_light_position[1] = *y; light_update(); return; } if (*x > lim) *x = lim; if (*x < -lim) *x = -lim; if (*y > lim) *y = lim; if (*y < -lim) *y = -lim; /* 4/3/07: The behavior of the light by setting normals with the original method (sin(xa), sin(ya)) gave very little range. Rotating a normal by angles gave huge variation in sensitivity with position. Fitting a curve to the ratios (xn/zn) found at detectable even steps in rotation gave the formula used here. Books and man pages don't help about what is going on with this position. */ xa = (double)*x * 0.1; ya = (double)*y * 0.1; zn = 1.0; xn = (float)(pow(10., fabs(0.011 * xa) + 0.845099) - 7.); yn = (float)(pow(10., fabs(0.011 * ya) + 0.845098) - 7.); if (xa < 0.) xn = -xn; if (ya > 0.) yn = -yn; // printf("angles %.1f %.1f Normal %.4f %.4f %.4f\n", xa, ya, xn, yn, zn); Imodv_light_position[0] = xn; Imodv_light_position[1] = yn; Imodv_light_position[2] = zn; light_update(); return; }
/***************************************************************************** * light_activate * * Uses the Direct3DDevice7::LightEnable method to active the light * *****************************************************************************/ void light_activate(struct d3d_light *light) { struct d3d_device *device; TRACE("light %p.\n", light); if (!light->active_viewport || !light->active_viewport->active_device) return; device = light->active_viewport->active_device; light_update(light); if (!(light->light.dwFlags & D3DLIGHT_ACTIVE)) { IDirect3DDevice7_LightEnable(&device->IDirect3DDevice7_iface, light->dwLightIndex, TRUE); light->light.dwFlags |= D3DLIGHT_ACTIVE; } }
/***************************************************************************** * light_activate * * Uses the Direct3DDevice7::LightEnable method to active the light * *****************************************************************************/ void light_activate(IDirect3DLightImpl* This) { IDirect3DDeviceImpl* device; TRACE("(%p)\n", This); if (!This->active_viewport || !This->active_viewport->active_device) return; device = This->active_viewport->active_device; light_update(This); /* If was not active, activate it */ if ((This->light.dwFlags & D3DLIGHT_ACTIVE) == 0) { IDirect3DDevice7_LightEnable(ICOM_INTERFACE(device,IDirect3DDevice7), This->dwLightIndex, TRUE); This->light.dwFlags |= D3DLIGHT_ACTIVE; } }
static HRESULT WINAPI d3d_light_SetLight(IDirect3DLight *iface, D3DLIGHT *data) { struct d3d_light *light = impl_from_IDirect3DLight(iface); DWORD flags = data->dwSize >= sizeof(D3DLIGHT2) ? ((D3DLIGHT2 *)data)->dwFlags : D3DLIGHT_ACTIVE; D3DLIGHT7 *light7 = &light->light7; TRACE("iface %p, data %p.\n", iface, data); if ((!data->dltType) || (data->dltType > D3DLIGHT_PARALLELPOINT)) return DDERR_INVALIDPARAMS; if (data->dltType == D3DLIGHT_PARALLELPOINT) FIXME("D3DLIGHT_PARALLELPOINT not implemented.\n"); /* Translate D3DLIGHT2 structure to D3DLIGHT7. */ light7->dltType = data->dltType; light7->dcvDiffuse = data->dcvColor; if (!(flags & D3DLIGHT_NO_SPECULAR)) light7->dcvSpecular = data->dcvColor; else light7->dcvSpecular = *(const D3DCOLORVALUE *)zero_value; light7->dcvAmbient = data->dcvColor; light7->dvPosition = data->dvPosition; light7->dvDirection = data->dvDirection; light7->dvRange = data->dvRange; light7->dvFalloff = data->dvFalloff; light7->dvAttenuation0 = data->dvAttenuation0; light7->dvAttenuation1 = data->dvAttenuation1; light7->dvAttenuation2 = data->dvAttenuation2; light7->dvTheta = data->dvTheta; light7->dvPhi = data->dvPhi; wined3d_mutex_lock(); memcpy(&light->light, data, sizeof(D3DLIGHT)); if (!(light->light.dwFlags & D3DLIGHT_ACTIVE) && flags & D3DLIGHT_ACTIVE) light_activate(light); else if (light->light.dwFlags & D3DLIGHT_ACTIVE && !(flags & D3DLIGHT_ACTIVE)) light_deactivate(light); else if (flags & D3DLIGHT_ACTIVE) light_update(light); light->light.dwFlags = flags; wined3d_mutex_unlock(); return D3D_OK; }
static HRESULT WINAPI IDirect3DLightImpl_SetLight(IDirect3DLight *iface, D3DLIGHT *lpLight) { IDirect3DLightImpl *This = impl_from_IDirect3DLight(iface); LPD3DLIGHT7 light7 = &This->light7; TRACE("iface %p, light %p.\n", iface, lpLight); if (TRACE_ON(ddraw)) { TRACE(" Light definition :\n"); dump_light((LPD3DLIGHT2) lpLight); } if ( (lpLight->dltType == 0) || (lpLight->dltType > D3DLIGHT_PARALLELPOINT) ) return DDERR_INVALIDPARAMS; if ( lpLight->dltType == D3DLIGHT_PARALLELPOINT ) FIXME("D3DLIGHT_PARALLELPOINT no supported\n"); /* Translate D3DLIGH2 structure to D3DLIGHT7 */ light7->dltType = lpLight->dltType; light7->dcvDiffuse = lpLight->dcvColor; if ((((LPD3DLIGHT2)lpLight)->dwFlags & D3DLIGHT_NO_SPECULAR) != 0) light7->dcvSpecular = lpLight->dcvColor; else light7->dcvSpecular = *(const D3DCOLORVALUE*)zero_value; light7->dcvAmbient = lpLight->dcvColor; light7->dvPosition = lpLight->dvPosition; light7->dvDirection = lpLight->dvDirection; light7->dvRange = lpLight->dvRange; light7->dvFalloff = lpLight->dvFalloff; light7->dvAttenuation0 = lpLight->dvAttenuation0; light7->dvAttenuation1 = lpLight->dvAttenuation1; light7->dvAttenuation2 = lpLight->dvAttenuation2; light7->dvTheta = lpLight->dvTheta; light7->dvPhi = lpLight->dvPhi; wined3d_mutex_lock(); memcpy(&This->light, lpLight, lpLight->dwSize); if (This->light.dwFlags & D3DLIGHT_ACTIVE) light_update(This); wined3d_mutex_unlock(); return D3D_OK; }
/*! * Main display function; called whenever the scene needs to be redrawn. */ static void display(void) { Lib3dsNode *c,*t; Lib3dsFloat fov, roll; float near, far, dist; float *campos; float *tgt; Lib3dsMatrix M; Lib3dsCamera *cam; Lib3dsVector v; Lib3dsNode *p; if( file != NULL && file->background.solid.use ) glClearColor(file->background.solid.col[0], file->background.solid.col[1], file->background.solid.col[2], 1.); /* TODO: fog */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if( anti_alias ) glEnable(GL_POLYGON_SMOOTH); else glDisable(GL_POLYGON_SMOOTH); if (!file) { return; } glLightModelfv(GL_LIGHT_MODEL_AMBIENT, file->ambient); c=lib3ds_file_node_by_name(file, camera, LIB3DS_CAMERA_NODE); t=lib3ds_file_node_by_name(file, camera, LIB3DS_TARGET_NODE); if( t != NULL ) tgt = t->data.target.pos; if( c != NULL ) { fov = c->data.camera.fov; roll = c->data.camera.roll; campos = c->data.camera.pos; } if ((cam = lib3ds_file_camera_by_name(file, camera)) == NULL) return; near = cam->near_range; far = cam->far_range; if (c == NULL || t == NULL) { if( c == NULL ) { fov = cam->fov; roll = cam->roll; campos = cam->position; } if( t == NULL ) tgt = cam->target; } glMatrixMode(GL_PROJECTION); glLoadIdentity(); /* KLUDGE alert: OpenGL can't handle a near clip plane of zero, * so if the camera's near plane is zero, we give it a small number. * In addition, many .3ds files I've seen have a far plane that's * much too close and the model gets clipped away. I haven't found * a way to tell OpenGL not to clip the far plane, so we move it * further away. A factor of 10 seems to make all the models I've * seen visible. */ if( near <= 0. ) near = far * .001; gluPerspective( fov, 1.0*gl_width/gl_height, near, far); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRotatef(-90, 1.0,0,0); /* User rotates the view about the target point */ lib3ds_vector_sub(v, tgt, campos); dist = lib3ds_vector_length(v); glTranslatef(0.,dist, 0.); glRotatef(view_rotx, 1., 0., 0.); glRotatef(view_roty, 0., 1., 0.); glRotatef(view_rotz, 0., 0., 1.); glTranslatef(0.,-dist, 0.); lib3ds_matrix_camera(M, campos, tgt, roll); glMultMatrixf(&M[0][0]); /* Lights. Set them from light nodes if possible. If not, use the * light objects directly. */ { static const GLfloat a[] = {0.0f, 0.0f, 0.0f, 1.0f}; static GLfloat c[] = {1.0f, 1.0f, 1.0f, 1.0f}; static GLfloat p[] = {0.0f, 0.0f, 0.0f, 1.0f}; Lib3dsLight *l; int li=GL_LIGHT0; for (l=file->lights; l; l=l->next) { glEnable(li); light_update(l); c[0] = l->color[0]; c[1] = l->color[1]; c[2] = l->color[2]; glLightfv(li, GL_AMBIENT, a); glLightfv(li, GL_DIFFUSE, c); glLightfv(li, GL_SPECULAR, c); p[0] = l->position[0]; p[1] = l->position[1]; p[2] = l->position[2]; glLightfv(li, GL_POSITION, p); if (l->spot_light) { p[0] = l->spot[0] - l->position[0]; p[1] = l->spot[1] - l->position[1]; p[2] = l->spot[2] - l->position[2]; glLightfv(li, GL_SPOT_DIRECTION, p); } ++li; } } if( show_object ) { for (p=file->nodes; p!=0; p=p->next) { render_node(p); } } if( show_bounds ) draw_bounds(tgt); if( show_cameras ) { for( cam = file->cameras; cam != NULL; cam = cam->next ) { lib3ds_matrix_camera(M, cam->position, cam->target, cam->roll); lib3ds_matrix_inv(M); glPushMatrix(); glMultMatrixf(&M[0][0]); glScalef(size/20, size/20, size/20); glCallList(cameraList); glPopMatrix(); } } if( show_lights ) { Lib3dsLight *light; for( light = file->lights; light != NULL; light = light->next ) draw_light(light->position, light->color); glMaterialfv(GL_FRONT, GL_EMISSION, black); } glutSwapBuffers(); }
/* * Set up lighting for an object from color and material properties */ void light_on(Iobj *obj, int modind) { Iview *vw = Imodv->mod[modind]->view; GLfloat red = obj->red; GLfloat green = obj->green; GLfloat blue = obj->blue; GLfloat alpha = (1.0 - (float)obj->trans / 100.0f); GLfloat params[4]; GLfloat spec, amb, diffuse, shine; /* could make this conditional on both-side lighting flag set if there are problems */ GLenum face = GL_FRONT_AND_BACK; if (obj->flags & IMOD_OBJFLAG_FCOLOR){ red = (float)obj->fillred / 255.0f; green = (float)obj->fillgreen / 255.0f; blue = (float)obj->fillblue / 255.0f; } spec = obj->specular / 255.0f; amb = obj->ambient / 255.0f; diffuse = obj->diffuse / 255.0f; shine = ((255 - obj->shininess) / 50.0f ) + 1.0f; glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); params[0] = (float)red * amb; params[1] = (float)green * amb; params[2] = (float)blue * amb; params[3] = alpha; glMaterialfv(face, GL_AMBIENT, params); params[0] = (float)red * diffuse; params[1] = (float)green * diffuse; params[2] = (float)blue * diffuse; params[3] = alpha; glMaterialfv(face, GL_DIFFUSE, params); params[0] = spec + (red); params[1] = spec + (green); params[2] = spec + (blue); params[3] = alpha; glMaterialfv(face, GL_SPECULAR, params); /* DNM 9/3/02: this was glMateriali but did not seem to matter */ glMaterialf(face, GL_SHININESS, shine); /* glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glEnable(GL_COLOR_MATERIAL); */ glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); /* glLightfv(GL_LIGHT0, GL_POSITION, Imodv_light_position); */ /* glTranslatef(vw->trans.x, vw->trans.y, (vw->trans.z * Imodv->imod->zscale)); */ glScalef(vw->scale.x, vw->scale.y, vw->scale.z * Imodv->mod[modind]->zscale); light_update(); glPopMatrix(); }
static display_target ghost_prepare_frame (sync_info *sync, void *params, int iparam) { glass_data *gdata = (glass_data *) params; /*GXTexObj spiderweb_tex_obj;*/ Mtx mvtmp, rot, mvtmp2; Mtx sep_scale; /*TPL_GetTexture (&spiderwebTPL, spiderweb, &spiderweb_tex_obj);*/ GX_InvalidateTexAll (); rendertarget_texture (RTT_WIDTH, RTT_HEIGHT, COPYFMT, GX_FALSE, GX_PF_RGB8_Z24, GX_ZC_LINEAR); GX_SetZMode (GX_FALSE, GX_LEQUAL, GX_FALSE); GX_SetBlendMode (GX_BM_NONE, GX_BL_ONE, GX_BL_ONE, GX_LO_SET); GX_SetColorUpdate (GX_TRUE); GX_SetAlphaUpdate (GX_FALSE); screenspace_rect (gdata->plain_texture_shader, GX_VTXFMT1, 0); GX_SetCopyClear ((GXColor) { 128, 128, 128, 0 }, 0x00ffffff); GX_CopyTex (gdata->grabbed_texture, GX_TRUE); GX_PixModeSync (); rendertarget_texture (RTT_WIDTH, RTT_HEIGHT, COPYFMT, GX_FALSE, GX_PF_RGB8_Z24, GX_ZC_LINEAR); GX_SetCopyClear ((GXColor) { 128, 128, 128, 0 }, 0x00ffffff); GX_SetColorUpdate (GX_TRUE); GX_SetAlphaUpdate (GX_FALSE); /* We need a grey background! This isn't very efficient though. */ GX_CopyTex (gdata->grabbed_texture, GX_TRUE); GX_SetCopyClear ((GXColor) { 0, 0, 0, 0 }, 0x00ffffff); GX_SetZMode (GX_FALSE, GX_LEQUAL, GX_FALSE); GX_SetBlendMode (GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); GX_SetColorUpdate (GX_TRUE); GX_SetAlphaUpdate (GX_FALSE); GX_SetCullMode (GX_CULL_NONE); guMtxIdentity (mvtmp); guMtxRotAxisDeg (rot, &((guVector) { 0, 1, 0 }), gdata->thr); guMtxConcat (rot, mvtmp, mvtmp); guMtxRotAxisDeg (rot, &((guVector) { 1, 0, 0 }), gdata->thr * 0.7); guMtxConcat (rot, mvtmp, mvtmp); if (sync->time_offset < 1000) gdata->xoffset = -(float) (1000 - sync->time_offset) / 10.0; else if (sync->time_offset > 16000) gdata->xoffset = (float) (sync->time_offset - 16000) / 10.0; else gdata->xoffset = 0.0; /*guMtxScale (sep_scale, 6.0, 6.0, 6.0);*/ set_sep_scale (sep_scale, sync); guMtxTransApply (mvtmp, mvtmp2, gdata->xoffset, 0, 0); object_set_matrices (&scene, &gdata->obj_loc, scene.camera, mvtmp2, sep_scale, perspmat, GX_PERSPECTIVE); light_update (scene.camera, &light0); shader_load (gdata->refraction_shader); object_set_arrays (&blobby_thing_obj, OBJECT_POS | OBJECT_NORM, GX_VTXFMT0, 0); object_render (&blobby_thing_obj, OBJECT_POS | OBJECT_NORM, GX_VTXFMT0); /* guMtxTransApply (mvtmp, mvtmp2, 13, 0, 0); object_set_matrices (&scene, &gdata->obj_loc, scene.camera, mvtmp2, sep_scale, NULL, 0); object_render (&spooky_ghost_obj, OBJECT_POS | OBJECT_NORM, GX_VTXFMT0); guMtxTransApply (mvtmp, mvtmp2, -13, 0, 0); object_set_matrices (&scene, &gdata->obj_loc, scene.camera, mvtmp2, sep_scale, NULL, 0); object_render (&spooky_ghost_obj, OBJECT_POS | OBJECT_NORM, GX_VTXFMT0); */ GX_CopyTex (gdata->grabbed_texture, GX_TRUE); GX_PixModeSync (); return MAIN_BUFFER; }