📄 lighting.c
字号:
/*=================================================================================
FILE: lighting.c
SERVICES: Functionality for lighting tutorials
DESCRIPTION: This file contains all the initialization, event handlers and
other functions specific to the lighting tutorials.
Copyright (c) 1999-2003 QUALCOMM Incorporated.
All Rights Reserved.
QUALCOMM Proprietary/GTDR
=================================================================================*/
/* include files */
#include "lighting.h"
/* local function prototypes */
static boolean TutorI3D_LightingDirectionColorHandleEvent(TutorI3D* pMe, AEEEvent event,
uint16 wParam, uint32 dwParam);
static boolean TutorI3D_LightingMaterialHandleEvent(TutorI3D* pMe, AEEEvent event,
uint16 wParam, uint32 dwParam);
static boolean OnLightingDirectionColor(TutorI3D* pMe);
static boolean OnLightingMaterial(TutorI3D* pMe);
static boolean isColorLightingMode(AEE3DLightingMode mode, AEE3DLightType type);
static boolean isLightingColorOption(LightingDirColOption lightDirColOp);
static boolean isLightingDirectionOption(LightingDirColOption lightDirColOp);
static boolean isDirectionLightingMode(AEE3DLightingMode mode, AEE3DLightType type);
/*===========================================================================
FUNCTION: TutorI3D_InitLightingScreen
DESCRIPTION
Initializes the lighting screen. This function sets up the
rectangles, menus, variables, etc. needed for this screen.
PROTOTYPE:
boolean TutorI3D_InitLightingScreen(TutorI3D* pMe)
PARAMETERS:
pMe: [in]: Pointer to TutorI3D sturcture
DEPENDENCIES
none
RETURN VALUE
TRUE: if initialization was successful
FALSE: if failed
SIDE EFFECTS
none
===========================================================================*/
boolean TutorI3D_InitLightingScreen(TutorI3D* pMe)
{
AEEMenuColors menuColors;
MEMSET(&menuColors, 0, sizeof(AEEMenuColors));
// Set the clipping rectangle for 3D drawing functions
// while in the sub states.
SETAEERECT (&pMe->screen3DRect, DRAWING_AREA_3D_UP_LEFT_X,
DRAWING_AREA_3D_UP_LEFT_Y,
DRAWING_AREA_3D_WIDTH,
DRAWING_AREA_3D_HEIGHT-5);
// Set the rectangle for the sub menus (bottom of screen)
SETAEERECT (&pMe->menuBottomRect, pMe->screen3DRect.x, DRAWING_AREA_3D_HEIGHT-5,
pMe->di.cxScreen, pMe->di.cyScreen - (DRAWING_AREA_3D_HEIGHT-5));
// Rectangle where the API function is written at top of the screen
SETAEERECT(&pMe->menuTopRect, pMe->screen3DRect.x, pMe->screen3DRect.y,
pMe->screen3DRect.dx, pMe->charHeight + 3);
// The 3D draw area defined by screen3DRect minus the API name rectangle
// at the top of the screen (menuTopRect).
SETAEERECT(&pMe->screenAPI3DRect, pMe->screen3DRect.x,
pMe->menuTopRect.y + pMe->menuTopRect.dy,
pMe->screen3DRect.dx,
pMe->menuBottomRect.y - (pMe->menuTopRect.y + pMe->menuTopRect.dy ));
// create lighting menu instance
if(ISHELL_CreateInstance(pMe->a.m_pIShell, AEECLSID_SOFTKEYCTL,
(void **)&pMe->m_pSubMenu) != SUCCESS)
{
return FALSE;
}
IMENUCTL_SetActive( pMe->m_pSubMenu, FALSE );
IMENUCTL_Reset(pMe->m_pSubMenu);
IMENUCTL_DeleteAll(pMe->m_pSubMenu);
IMENUCTL_SetRect (pMe->m_pSubMenu, &pMe->menuBottomRect);
// direction and color sub menu item
IMENUCTL_AddItem(pMe->m_pSubMenu, TUTORI3D_RES_FILE,
IDS_LIGHTING_DIRECTION_COLOR, IDS_LIGHTING_DIRECTION_COLOR,
NULL, (uint32) NULL);
// material sub menu item
IMENUCTL_AddItem(pMe->m_pSubMenu, TUTORI3D_RES_FILE,
IDS_LIGHTING_MATERIAL, IDS_LIGHTING_MATERIAL,
NULL, (uint32) NULL);
// yellow on black for selected items
menuColors.cSelBack = CLR_BLACK;
menuColors.cSelText = CLR_YELLOW;
menuColors.wMask = MC_SEL_BACK | MC_SEL_TEXT ;
IMENUCTL_SetColors(pMe->m_pSubMenu, &menuColors);
I3D_SetClipRect(pMe->m_p3D, &pMe->screen3DRect);
return TRUE;
}
/*===========================================================================
FUNCTION: TutorI3D_DrawLightingMenu
DESCRIPTION
Redraws the lighting menu to the screen and sets it active.
The rect for the menu is pMe->menuBottomRect
PROTOTYPE:
boolean TutorI3D_DrawLightingMenu(TutorI3D* pMe)
PARAMETERS:
pMe: [in]: Pointer to TutorI3D sturcture
DEPENDENCIES
none
RETURN VALUE
TRUE: if menu was redrawn
FALSE: if there was an error
SIDE EFFECTS
none
===========================================================================*/
boolean TutorI3D_DrawLightingMenu(TutorI3D* pMe)
{
AECHAR szBuf[30];
// Fill back menu background with same color as unselected menu item background
IDISPLAY_FillRect(pMe->a.m_pIDisplay, &pMe->menuBottomRect, CLR_SYS_ITEM);
if(!IMENUCTL_Redraw(pMe->m_pSubMenu))
{
return FALSE;
}
// Seperate from draw area with a line
IDISPLAY_DrawHLine(pMe->a.m_pIDisplay, pMe->menuBottomRect.x, pMe->menuBottomRect.y, pMe->menuBottomRect.dx);
// Draw title
if(ISHELL_LoadResString(pMe->a.m_pIShell, TUTORI3D_RES_FILE, IDS_LIGHTING, szBuf,
sizeof(szBuf)) == 0)
{
return FALSE;
}
if(IDISPLAY_DrawText(pMe->a.m_pIDisplay, AEE_FONT_NORMAL, szBuf,
-1, (pMe->menuBottomRect.x + pMe->menuBottomRect.dx)/2,
pMe->menuBottomRect.y + 3, NULL,
IDF_ALIGN_CENTER | IDF_TEXT_TRANSPARENT) != SUCCESS)
{
DBGPRINTF("Error: Lighting menu title not displayed");
}
// allow commands
IMENUCTL_SetActive( pMe->m_pSubMenu, TRUE );
return TRUE;
}
/*===========================================================================
FUNCTION
TutorI3D_LightingHandleEvent
DESCRIPTION
This is the Event Handler for the lighting screen. All events while in
the lighting state or a substate of the lighting state are processed
by this event handler.
PROTOTYPE:
boolean TutorI3D_LightingHandleEvent(TutorI3D* pMe, AEEEvent event,
uint16 wParam, uint32 dwParam)
PARAMETERS:
pMe [In] : Pointer to TutorI3D sturcture
ecode [In]: Specifies the Event sent to the event handler
wParam, dwParam [In]: Event specific data.
DEPENDENCIES
none
RETURN VALUE
TRUE: If the event handler has processed the event
FALSE: If the event handler did not process the event
SIDE EFFECTS
none
===========================================================================*/
boolean TutorI3D_LightingHandleEvent(TutorI3D* pMe, AEEEvent event,
uint16 wParam, uint32 dwParam)
{
/* Send event to appropriate sub event handler or handle event here, depending
on the current state. */
if(pMe->state == STATE_LIGHTING_DIRECTION_COLOR)
{
return TutorI3D_LightingDirectionColorHandleEvent(pMe, event, wParam, dwParam);
}
else if(pMe->state == STATE_LIGHTING_MATERIAL)
{
return TutorI3D_LightingMaterialHandleEvent(pMe, event, wParam, dwParam);
}
else if (pMe->state == STATE_LIGHTING)
{
switch(event)
{
case EVT_KEY:
switch(wParam)
{
case AVK_CLR:
/* The User has requested to go back to the main menu.
First: Close the current menu (Free associated memory)
Second: set the next state we're going to.
Third: set the changeState flag here to indicate
we're going back a state. Once the current 3D frame
has finished rendering (ie. when we receive the
AEE3D_EVENT_FRAME_UPDATE_DISPLAY), we actually
change states.
The reason we do this is because we don't want to
change states immediately when the user
requests to go back a state. This is because we're going
to be drawing to the frame buffer (menus, etc.) when going
back a state. So what we do is, we wait for the current 3D
frame to finish rendering first, then switch states when we know
it's ok to draw to the frame buffer.
When going forward states, the menus, text, etc. are drawn either
before the rendering for the frame begins
(ie. before I3D_StartFrame() is called) or after it has completed.
(ie. in the respective ManipulateBuf functions).
*/
TutorI3D_CloseMenu(&pMe->m_pSubMenu);
pMe->nextState = STATE_MAIN;
pMe->changeState = TRUE;
break;
default:
return IMENUCTL_HandleEvent(pMe->m_pSubMenu, EVT_KEY,
wParam, dwParam);
}
return TRUE;
case EVT_COMMAND:
switch(wParam)
{
// the two tutorials here use different models, so
// initialize the appropriate model for the tutorials
// before changing states
case IDS_LIGHTING_DIRECTION_COLOR:
IMENUCTL_SetActive(pMe->m_pSubMenu, FALSE);
TutorI3D_InitSmoothSphere(pMe);
pMe->state = STATE_LIGHTING_DIRECTION_COLOR;
OnLightingDirectionColor(pMe);
break;
case IDS_LIGHTING_MATERIAL:
IMENUCTL_SetActive(pMe->m_pSubMenu, FALSE);
TutorI3D_InitSphere(pMe);
pMe->state = STATE_LIGHTING_MATERIAL;
OnLightingMaterial(pMe);
break;
default:
return FALSE;
}
return TRUE;
default:
return FALSE;
}
}
else
return FALSE;
}
/*===========================================================================
FUNCTION
TutorI3D_LightingDirectionColorHandleEvent
DESCRIPTION
This is the Event Handler for the lighting direction and color tutorial.
All events while in the lighting direction color state are processed
by this event handler.
PROTOTYPE:
static boolean TutorI3D_LightingDirectionColorHandleEvent(TutorI3D* pMe,
AEEEvent event,
uint16 wParam,
uint32 dwParam)
PARAMETERS:
pMe [In] : Pointer to TutorI3D sturcture
ecode [In]: Specifies the Event sent to the event handler
wParam, dwParam [In]: Event specific data.
DEPENDENCIES
none
RETURN VALUE
TRUE: If the event handler has processed the event
FALSE: If the event handler did not process the event
SIDE EFFECTS
none
===========================================================================*/
static boolean TutorI3D_LightingDirectionColorHandleEvent(TutorI3D* pMe, AEEEvent event,
uint16 wParam, uint32 dwParam)
{
switch(event)
{
case EVT_KEY_RELEASE:
pMe->keyIsPressed = FALSE;
return TRUE;
case EVT_KEY_PRESS:
{
AEE3DLight light;
AEE3DPoint direction;
int dirUnit=0;
int colUnit=0;
pMe->lastKeyPresswParam = wParam;
pMe->lastKeyPressdwParam = dwParam;
pMe->keyIsPressed = TRUE;
if(wParam == AVK_UP || wParam == AVK_DOWN)
{
dirUnit = (wParam == AVK_UP ? LIGHT_DIRECTION_UNIT : -LIGHT_DIRECTION_UNIT);
colUnit = (wParam == AVK_UP ? LIGHT_COLOR_UNIT : -LIGHT_COLOR_UNIT);
I3D_GetLight(pMe->m_p3D, pMe->lightTypeOp, &light);
if(pMe->lightDirColOp == LIGHT_X )
light.direction.x += dirUnit;
else if(pMe->lightDirColOp == LIGHT_Y)
light.direction.y += dirUnit;
else if(pMe->lightDirColOp == LIGHT_Z)
light.direction.z += dirUnit;
else if(pMe->lightDirColOp == LIGHT_RED)
light.color.r += colUnit;
else if(pMe->lightDirColOp == LIGHT_GREEN)
light.color.g += colUnit;
else if(pMe->lightDirColOp == LIGHT_BLUE)
light.color.b += colUnit;
else if(pMe->lightDirColOp == LIGHT_ALPHA)
light.color.a += colUnit;
//GetUnitVector returns a Q12 unit vector. Multiply this by 2^2=4
//to get a Q14 unit vector as SetLight expects
I3DUtil_GetUnitVector(pMe->m_p3DUtil, &light.direction, &direction);
direction.x <<= 2;
direction.y <<= 2;
direction.z <<= 2;
light.direction = direction;
I3D_SetLight(pMe->m_p3D, &light);
return TRUE;
}
else // key wasn't AVK_UP or AVK_DOWN
return FALSE;
} // end case EVT_KEY_PRESS
case EVT_KEY:
{
switch(wParam)
{
AEE3DLightingMode mode;
case AVK_1:
I3D_GetLightingMode(pMe->m_p3D, &mode);
if(isDirectionLightingMode(mode, pMe->lightTypeOp))
pMe->lightDirColOp = LIGHT_X;
break;
case AVK_2:
I3D_GetLightingMode(pMe->m_p3D, &mode);
if(isDirectionLightingMode(mode, pMe->lightTypeOp))
pMe->lightDirColOp = LIGHT_Y;
break;
case AVK_3:
I3D_GetLightingMode(pMe->m_p3D, &mode);
if(isDirectionLightingMode(mode, pMe->lightTypeOp))
pMe->lightDirColOp = LIGHT_Z;
break;
case AVK_4:
I3D_GetLightingMode(pMe->m_p3D, &mode);
if(isColorLightingMode(mode, pMe->lightTypeOp))
pMe->lightDirColOp = LIGHT_RED;
break;
case AVK_5:
I3D_GetLightingMode(pMe->m_p3D, &mode);
if(isColorLightingMode(mode, pMe->lightTypeOp))
pMe->lightDirColOp = LIGHT_GREEN;
break;
case AVK_6:
I3D_GetLightingMode(pMe->m_p3D, &mode);
if(isColorLightingMode(mode, pMe->lightTypeOp))
pMe->lightDirColOp = LIGHT_BLUE;
break;
case AVK_7:
I3D_GetLightingMode(pMe->m_p3D, &mode);
if(isColorLightingMode(mode, pMe->lightTypeOp))
pMe->lightDirColOp = LIGHT_ALPHA;
break;
// toggle lighting type selection if the lighting mode allows it
case AVK_8:
{
I3D_GetLightingMode(pMe->m_p3D, &mode);
if(pMe->lightTypeOp == AEE3D_LIGHT_DIFFUSED)
{
// specail case - AEE3D_LIGHT_MODE_DIFFUSED_COLOR_SPECULAR
// mode shares direction for diffuse and specular lighting.
// here, we're going from diffused to specular, so set a valid
// option if a direction is the current option (ie. a color option)
if(mode == AEE3D_LIGHT_MODE_DIFFUSED_COLOR_SPECULAR &&
isLightingDirectionOption(pMe->lightDirColOp) )
{
pMe->lightDirColOp = LIGHT_RED;
}
// select specular parameters only in the right mode
if(mode == AEE3D_LIGHT_MODE_DIFFUSED_COLOR_SPECULAR ||
mode == AEE3D_LIGHT_MODE_COLOR_DIFFUSED_COLOR_SPECULAR)
{
// if we lose color info by switching lighting modes,
// make sure we have a valid option selected. Directions
// are always valid
if(isLightingColorOption(pMe->lightDirColOp) &&
isColorLightingMode(mode, AEE3D_LIGHT_DIFFUSED) &&
!isColorLightingMode(mode, AEE3D_LIGHT_SPECULAR) )
{
pMe->lightDirColOp = LIGHT_X;
}
pMe->lightTypeOp = AEE3D_LIGHT_SPECULAR;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -