📄 vprogram.c
字号:
Description : ENTRYPOINT: Sets current program for subsequent calls.
************************************************************************************/
GLAPI_EXT void APIENTRY glBindProgramARB(GLenum target, GLuint program)
{
__GL_GET_CONTEXT();
GLES_TIME_START(GLES_TIMES_glBindProgram);
if(target != GL_VERTEX_PROGRAM_ARB)
{
SetError(gc, GL_INVALID_ENUM);
GLES_TIME_STOP(GLES_TIMES_glBindProgram);
return;
}
BindProgram(gc, program);
GLES_TIME_STOP(GLES_TIMES_glBindProgram);
}
/***********************************************************************************
Function Name : glDeleteProgramsARB
Inputs : n, programs
Outputs : -
Returns : -
Description : ENTRYPOINT: Deletes a list of n programs.
Deletes internal sVertexProgram structures for named programs and
if they were currently bound, binds default program.
************************************************************************************/
GLAPI_EXT void APIENTRY glDeleteProgramsARB(GLsizei n, const GLuint *programs)
{
IMG_UINT32 ui32Start, ui32RangeVal;
GLESnamesArray *psArray;
IMG_INT32 i;
__GL_GET_CONTEXT();
GLES_TIME_START(GLES_TIMES_glDeletePrograms);
if(n < 0)
{
SetError(gc, GL_INVALID_VALUE);
GLES_TIME_STOP(GLES_TIMES_glDeletePrograms);
return;
}
else if (n == 0)
{
GLES_TIME_STOP(GLES_TIMES_glDeletePrograms);
return;
}
psArray = gc->sVertexProgram.psNamesArray;
/*
** Send the prorgam names in ranges to the names module to be
** deleted. Ignore any references to default programs.
** If a programs that is being deleted is currently bound,
** bind the default programs to its target.
*/
ui32Start = ui32RangeVal = programs[0];
for (i=0; i < n; i++, ui32RangeVal++)
{
/* skip default textures */
if (programs[i] == 0)
{
/* delete up to this one */
LOCK_NAMES_ARRAY(psArray);
NamedItemDeleteRange(gc, psArray, ui32Start, ui32RangeVal-ui32Start);
UNLOCK_NAMES_ARRAY(psArray);
/* skip over this one by setting start to the next one */
ui32Start = programs[i+1];
ui32RangeVal = ui32Start-1; /* because it gets incremented later */
continue;
}
/*
* If the program is currently bound, bind the default program
* to its target.
*/
if(gc->sVertexProgram.psCurrentProgram->ui32Name == programs[i])
{
BindProgram(gc, 0);
}
if (programs[i] != ui32RangeVal)
{
/* delete up to this one */
LOCK_NAMES_ARRAY(psArray);
NamedItemDeleteRange(gc, psArray, ui32Start, ui32RangeVal-ui32Start);
UNLOCK_NAMES_ARRAY(psArray);
ui32Start = ui32RangeVal = programs[i];
}
}
LOCK_NAMES_ARRAY(psArray);
NamedItemDeleteRange(gc, psArray, ui32Start, ui32RangeVal-ui32Start);
UNLOCK_NAMES_ARRAY(psArray);
GLES_TIME_STOP(GLES_TIMES_glDeletePrograms);
}
/***********************************************************************************
Function Name : glGenProgramsARB
Inputs : n
Outputs : programs
Returns : -
Description : ENTRYPOINT: Generates a set of n names for programs
************************************************************************************/
GLAPI_EXT void APIENTRY glGenProgramsARB(GLsizei n, GLuint *programs)
{
__GL_GET_CONTEXT();
GLES_TIME_START(GLES_TIMES_glGenPrograms);
if (n < 0)
{
SetError(gc, GL_INVALID_VALUE);
GLES_TIME_STOP(GLES_TIMES_glGenPrograms);
return;
}
else if (n == 0)
{
GLES_TIME_STOP(GLES_TIMES_glGenPrograms);
return;
}
if (programs == NULL)
{
GLES_TIME_STOP(GLES_TIMES_glGenPrograms);
return;
}
GLES_ASSERT(gc->sVertexProgram.psNamesArray != NULL);
LOCK_NAMES_ARRAY(gc->sVertexProgram.psNamesArray);
GenNames(gc, gc->sVertexProgram.psNamesArray, (IMG_UINT32)n, programs);
UNLOCK_NAMES_ARRAY(gc->sVertexProgram.psNamesArray);
GLES_TIME_STOP(GLES_TIMES_glGenPrograms);
}
/***********************************************************************************
Function Name : CreateProgramState
Inputs : gc, psSharedContext
Outputs : -
Returns : Success
Description : Initialises the program state and creates/shares the name
array. Creates the default object (name 0).
************************************************************************************/
IMG_BOOL CreateProgramState(GLESContext *gc, GLESContext *psSharedContext)
{
GLESVertexProgram *psProgram;
/*
** Init program object structures, unless we're sharing program
** objects with another context, in which case psNamesArray will
** already have been initialized.
*/
if (gc->sVertexProgram.psNamesArray == IMG_NULL)
{
if(psSharedContext)
{
gc->sVertexProgram.psNamesArray = psSharedContext->sVertexProgram.psNamesArray;
gc->sVertexProgram.psNamesArray->ui32Refcount++;
}
else
{
gc->sVertexProgram.psNamesArray = CreateNamesArray(gc, GLES_NAMETYPE_PROGRAM);
if(!gc->sVertexProgram.psNamesArray)
{
DPF((DBG_ERROR,"Couldn't create names array for programs"));
return IMG_FALSE;
}
}
}
/*
** Set up the prorgam object for the default program.
** Because the default program is not shared, it is
** not hung off of the names array structure.
*/
psProgram = CreateProgram(gc, 0);
if(!psProgram)
{
DPF((DBG_ERROR,"Couldn't create default program"));
return IMG_FALSE;
}
GLES_ASSERT(psProgram->ui32Name == 0);
GLES_ASSERT(psProgram->ui32Refcount == 1);
gc->sVertexProgram.psDefaultProgram = psProgram;
return IMG_TRUE;
}
/***********************************************************************************
Function Name : InitProgramState
Inputs : gc
Outputs : -
Returns : -
Description : Initialises the program state machine.
************************************************************************************/
IMG_VOID InitProgramState(GLESContext *gc)
{
/* Binds the default program. */
BindProgram(gc, 0);
}
/***********************************************************************************
Function Name : FreeProgram
Inputs : gc, psProgram
Outputs : -
Returns : -
Description : Frees all structures/data associated with a program
************************************************************************************/
static IMG_VOID FreeProgram(GLESContext *gc, GLESVertexProgram *psProgram)
{
GLES_ASSERT(psProgram->ui32Refcount == 0);
if(psProgram->pui32Code)
GLESFree(gc, (IMG_VOID *)psProgram->pui32Code);
if(psProgram->psStateBinding)
GLESFree(gc, (IMG_VOID *)psProgram->psStateBinding);
if(psProgram->psLocalConstants)
GLESFree(gc, (IMG_VOID *)psProgram->psLocalConstants);
GLESFree(gc, psProgram);
}
/***********************************************************************************
Function Name : FreeProgramState
Inputs : gc
Outputs : -
Returns : -
Description : Unbinds all non-default programs and frees the default program.
If no other contexts are sharing the names array, will delete
this also.
************************************************************************************/
IMG_VOID FreeProgramState(GLESContext *gc)
{
GLESVertexProgram *psProgram;
/* Unbind non-default program object */
BindProgram(gc, 0);
/* Free default program object */
psProgram = gc->sVertexProgram.psDefaultProgram;
psProgram->ui32Refcount--;
GLES_ASSERT(psProgram->ui32Refcount == 0);
FreeProgram(gc, psProgram);
gc->sVertexProgram.psDefaultProgram = IMG_NULL;
LOCK_NAMES_ARRAY(gc->sVertexProgram.psNamesArray);
DestroyNamesArray(gc, gc->sVertexProgram.psNamesArray);
UNLOCK_NAMES_ARRAY(gc->sVertexProgram.psNamesArray);
gc->sVertexProgram.psNamesArray = IMG_NULL;
}
/***********************************************************************************
Function Name : DisposeProgram
Inputs : gc, pvData
Outputs : -
Returns : -
Description : Generic program free function; called from names.c
************************************************************************************/
static IMG_VOID DisposeProgram(GLESContext *gc, IMG_VOID *pvData)
{
GLESVertexProgram *psProgram = (GLESVertexProgram *)pvData;
psProgram->ui32Refcount--;
GLES_ASSERT((IMG_INT32)psProgram->ui32Refcount >= 0);
if (psProgram->ui32Refcount == 0)
{
FreeProgram(gc, psProgram);
}
}
/***********************************************************************************
Function Name : SetupProgramNameArray
Inputs : psNamesArray
Outputs : -
Returns : -
Description : Sets up names array for program objects.
************************************************************************************/
IMG_VOID SetupProgramNameArray(GLESnamesArray *psNamesArray)
{
psNamesArray->ui32Type = GLES_NAMETYPE_PROGRAM;
psNamesArray->pfnFree = DisposeProgram;
}
/***********************************************************************************
Function Name : GetConstantFromBinding
Inputs : gc, psStateBinding
Outputs : -
Returns : -
Description : Given a binding it will set inside the binding structure an
actual value based on an existent state or derived state
************************************************************************************/
static IMG_VOID GetConstantFromBinding(GLESContext *gc, GLESVPStateBinding *psStateBinding)
{
GLESmatrix matrix1;
IMG_UINT32 ui32MatrixNumber;
IMG_UINT32 ui32MatrixElement;
GLEStransform *psTransform;
/* this is an optimisation so that if a program binds a inv/trans/invtrans of a matrix
we only calculate once rather than 4 times, because there are 4 bindings */
switch(psStateBinding->eBindingType)
{
case GLES_VP_BINDING_MATRIX_MODELVIEW_ROW0:
case GLES_VP_BINDING_MATRIX_MODELVIEW_ROW1:
case GLES_VP_BINDING_MATRIX_MODELVIEW_ROW2:
case GLES_VP_BINDING_MATRIX_MODELVIEW_ROW3:
{
psTransform = gc->sTransform.psModelView;
ui32MatrixElement = psStateBinding->eBindingType - GLES_VP_BINDING_MATRIX_MODELVIEW_ROW0;
if(psStateBinding->ui32Index1 != GLES_MATRIX_MODE_NORMAL)
{
if(psTransform->bUpdateInverse)
{
(*gc->sProcs.pfnComputeInverseTranspose)(gc, psTransform);
psTransform->bUpdateInverse = IMG_FALSE;
}
}
switch(psStateBinding->ui32Index1)
{
case GLES_MATRIX_MODE_NORMAL: /* transpose matrix for VGP */
psStateBinding->sData.fX = psTransform->sMatrix.afMatrix[0][ui32MatrixElement];
psStateBinding->sData.fY = psTransform->sM
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -