464 lines
13 KiB
C
464 lines
13 KiB
C
/*
|
|
** Copyright 1991,1992, Silicon Graphics, Inc.
|
|
** All Rights Reserved.
|
|
**
|
|
** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
|
|
** the contents of this file may not be disclosed to third parties, copied or
|
|
** duplicated in any form, in whole or in part, without the prior written
|
|
** permission of Silicon Graphics, Inc.
|
|
**
|
|
** RESTRICTED RIGHTS LEGEND:
|
|
** Use, duplication or disclosure by the Government is subject to restrictions
|
|
** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
|
|
** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
|
|
** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
|
|
** rights reserved under the Copyright Laws of the United States.
|
|
**
|
|
*/
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
#ifdef GL_EXT_paletted_texture
|
|
GLboolean __glCheckColorTableArgs(__GLcontext *gc, GLenum format, GLenum type)
|
|
{
|
|
switch (format)
|
|
{
|
|
case GL_RED:
|
|
case GL_GREEN: case GL_BLUE:
|
|
case GL_ALPHA: case GL_RGB:
|
|
case GL_RGBA:
|
|
#ifdef GL_EXT_bgra
|
|
case GL_BGRA_EXT:
|
|
case GL_BGR_EXT:
|
|
#endif
|
|
break;
|
|
default:
|
|
bad_enum:
|
|
__glSetError(GL_INVALID_ENUM);
|
|
return GL_FALSE;
|
|
}
|
|
|
|
switch (type) {
|
|
case GL_BYTE:
|
|
case GL_UNSIGNED_BYTE:
|
|
case GL_SHORT:
|
|
case GL_UNSIGNED_SHORT:
|
|
case GL_INT:
|
|
case GL_UNSIGNED_INT:
|
|
case GL_FLOAT:
|
|
break;
|
|
default:
|
|
goto bad_enum;
|
|
}
|
|
|
|
return GL_TRUE;
|
|
}
|
|
|
|
void APIPRIVATE __glim_ColorTableEXT(GLenum target,
|
|
GLenum internalFormat, GLsizei width,
|
|
GLenum format, GLenum type,
|
|
const GLvoid *data, GLboolean _IsDlist)
|
|
{
|
|
__GLtexture *tex;
|
|
GLint level;
|
|
__GLpixelSpanInfo spanInfo;
|
|
GLenum baseFormat;
|
|
RGBQUAD *newData;
|
|
|
|
__GL_SETUP_NOT_IN_BEGIN_VALIDATE();
|
|
|
|
switch(internalFormat)
|
|
{
|
|
case GL_RGB: case 3:
|
|
case GL_R3_G3_B2: case GL_RGB4:
|
|
case GL_RGB5: case GL_RGB8:
|
|
case GL_RGB10: case GL_RGB12:
|
|
case GL_RGB16:
|
|
baseFormat = GL_RGB;
|
|
break;
|
|
case GL_RGBA: case 4:
|
|
case GL_RGBA2: case GL_RGBA4:
|
|
case GL_RGBA8: case GL_RGB5_A1:
|
|
case GL_RGBA12: case GL_RGBA16:
|
|
case GL_RGB10_A2:
|
|
baseFormat = GL_RGBA;
|
|
break;
|
|
default:
|
|
__glSetError(GL_INVALID_ENUM);
|
|
return;
|
|
}
|
|
|
|
// width must be a positive power of two greater than zero
|
|
if (width <= 0 || (width & (width-1)) != 0)
|
|
{
|
|
__glSetError(GL_INVALID_VALUE);
|
|
return;
|
|
}
|
|
|
|
if (!__glCheckColorTableArgs(gc, format, type))
|
|
{
|
|
return;
|
|
}
|
|
|
|
tex = __glLookUpTexture(gc, target);
|
|
|
|
if (target == GL_PROXY_TEXTURE_1D ||
|
|
target == GL_PROXY_TEXTURE_2D)
|
|
{
|
|
// Consider - How do MCD's indicate their palette support?
|
|
|
|
// We're only in this case if it's a legal proxy target value
|
|
// so there's no need to do a real check
|
|
ASSERTOPENGL(tex != NULL, "Invalid proxy target");
|
|
|
|
tex->paletteRequestedFormat = internalFormat;
|
|
tex->paletteTotalSize = width;
|
|
tex->paletteSize = tex->paletteTotalSize;
|
|
|
|
// Proxies have no data so there's no need to do any more
|
|
return;
|
|
}
|
|
|
|
if (data == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (tex == NULL)
|
|
{
|
|
__glSetError(GL_INVALID_ENUM);
|
|
return;
|
|
}
|
|
|
|
// Allocate palette storage
|
|
newData = GCREALLOC(gc, tex->paletteTotalData, sizeof(RGBQUAD)*width);
|
|
if (newData == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
tex->paletteBaseFormat = baseFormat;
|
|
tex->paletteRequestedFormat = internalFormat;
|
|
tex->paletteTotalSize = width;
|
|
__glSetPaletteSubdivision(tex, tex->paletteTotalSize);
|
|
tex->paletteTotalData = newData;
|
|
tex->paletteData = tex->paletteTotalData;
|
|
|
|
// This routine can be called on any kind of texture, not necessarily
|
|
// color-indexed ones. If it is a color-index texture then we
|
|
// need to set the appropriate baseFormat and extract procs
|
|
// according to the palette data
|
|
if (tex->level[0].internalFormat == GL_COLOR_INDEX8_EXT ||
|
|
tex->level[0].internalFormat == GL_COLOR_INDEX16_EXT)
|
|
{
|
|
for (level = 0; level < gc->constants.maxMipMapLevel; level++)
|
|
{
|
|
tex->level[level].baseFormat = tex->paletteBaseFormat;
|
|
// Pick proper extraction proc
|
|
if (tex->level[0].internalFormat == GL_COLOR_INDEX8_EXT)
|
|
{
|
|
__glSetPaletteLevelExtract8(tex, &tex->level[level],
|
|
tex->level[level].border);
|
|
}
|
|
else
|
|
{
|
|
ASSERTOPENGL(tex->level[0].internalFormat ==
|
|
GL_COLOR_INDEX16_EXT,
|
|
"Unexpected internalFormat\n");
|
|
|
|
__glSetPaletteLevelExtract16(tex, &tex->level[level],
|
|
tex->level[level].border);
|
|
}
|
|
}
|
|
|
|
// We need to repick the texture procs because the baseFormat
|
|
// field has changed
|
|
__GL_DELAY_VALIDATE(gc);
|
|
}
|
|
|
|
// Copy user palette data into BGRA form
|
|
spanInfo.dstImage = tex->paletteTotalData;
|
|
__glInitTextureUnpack(gc, &spanInfo, width, 1, format, type, data,
|
|
GL_BGRA_EXT, _IsDlist);
|
|
__glInitUnpacker(gc, &spanInfo);
|
|
__glInitPacker(gc, &spanInfo);
|
|
(*gc->procs.copyImage)(gc, &spanInfo, GL_TRUE);
|
|
|
|
// Don't update the optimized palette unless it would actually
|
|
// get used
|
|
if (tex->level[0].internalFormat == GL_COLOR_INDEX8_EXT ||
|
|
tex->level[0].internalFormat == GL_COLOR_INDEX16_EXT)
|
|
{
|
|
__GLtextureObject *pto;
|
|
|
|
pto = __glLookUpTextureObject(gc, target);
|
|
__glGenUpdateTexturePalette(gc, tex, pto->loadKey,
|
|
0, tex->paletteTotalSize);
|
|
}
|
|
}
|
|
|
|
void APIPRIVATE __glim_ColorSubTableEXT(GLenum target, GLsizei start,
|
|
GLsizei count, GLenum format,
|
|
GLenum type, const GLvoid *data,
|
|
GLboolean _IsDlist)
|
|
{
|
|
__GLtexture *tex;
|
|
__GLpixelSpanInfo spanInfo;
|
|
|
|
__GL_SETUP_NOT_IN_BEGIN_VALIDATE();
|
|
|
|
if (!__glCheckColorTableArgs(gc, format, type))
|
|
{
|
|
return;
|
|
}
|
|
|
|
tex = __glLookUpTexture(gc, target);
|
|
if (tex == NULL ||
|
|
target == GL_PROXY_TEXTURE_1D ||
|
|
target == GL_PROXY_TEXTURE_2D)
|
|
{
|
|
__glSetError(GL_INVALID_ENUM);
|
|
return;
|
|
}
|
|
|
|
if (data == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Validate start and count
|
|
if (start > tex->paletteTotalSize ||
|
|
start+count > tex->paletteTotalSize)
|
|
{
|
|
__glSetError(GL_INVALID_VALUE);
|
|
return;
|
|
}
|
|
|
|
// Copy user palette data into BGRA form
|
|
spanInfo.dstImage = tex->paletteTotalData;
|
|
__glInitTextureUnpack(gc, &spanInfo, count, 1, format, type, data,
|
|
GL_BGRA_EXT, _IsDlist);
|
|
spanInfo.dstSkipPixels += start;
|
|
__glInitUnpacker(gc, &spanInfo);
|
|
__glInitPacker(gc, &spanInfo);
|
|
(*gc->procs.copyImage)(gc, &spanInfo, GL_TRUE);
|
|
|
|
// Don't update the optimized palette unless it would actually
|
|
// get used
|
|
if (tex->level[0].internalFormat == GL_COLOR_INDEX8_EXT ||
|
|
tex->level[0].internalFormat == GL_COLOR_INDEX16_EXT)
|
|
{
|
|
__GLtextureObject *pto;
|
|
|
|
pto = __glLookUpTextureObject(gc, target);
|
|
__glGenUpdateTexturePalette(gc, tex, pto->loadKey, start, count);
|
|
}
|
|
}
|
|
|
|
void APIPRIVATE __glim_GetColorTableEXT(GLenum target, GLenum format,
|
|
GLenum type, GLvoid *data)
|
|
{
|
|
__GLtexture *tex;
|
|
GLint level;
|
|
__GLpixelSpanInfo spanInfo;
|
|
GLenum baseFormat;
|
|
|
|
__GL_SETUP_NOT_IN_BEGIN_VALIDATE();
|
|
|
|
if (!__glCheckColorTableArgs(gc, format, type))
|
|
{
|
|
return;
|
|
}
|
|
|
|
tex = __glLookUpTexture(gc, target);
|
|
if (tex == NULL ||
|
|
target == GL_PROXY_TEXTURE_1D ||
|
|
target == GL_PROXY_TEXTURE_2D)
|
|
{
|
|
__glSetError(GL_INVALID_ENUM);
|
|
return;
|
|
}
|
|
|
|
ASSERTOPENGL(tex->paletteTotalData != NULL,
|
|
"GetColorTable with no palette data\n");
|
|
|
|
// Copy BGRA data into user buffer
|
|
spanInfo.srcImage = tex->paletteTotalData;
|
|
spanInfo.srcFormat = GL_BGRA_EXT;
|
|
spanInfo.srcType = GL_UNSIGNED_BYTE;
|
|
spanInfo.srcAlignment = 4;
|
|
__glInitImagePack(gc, &spanInfo, tex->paletteTotalSize, 1,
|
|
format, type, data);
|
|
__glInitUnpacker(gc, &spanInfo);
|
|
__glInitPacker(gc, &spanInfo);
|
|
(*gc->procs.copyImage)(gc, &spanInfo, GL_TRUE);
|
|
}
|
|
|
|
void APIPRIVATE __glim_GetColorTableParameterivEXT(GLenum target,
|
|
GLenum pname,
|
|
GLint *params)
|
|
{
|
|
__GLtexture *tex;
|
|
|
|
__GL_SETUP_NOT_IN_BEGIN();
|
|
|
|
tex = __glLookUpTexture(gc, target);
|
|
if (tex == NULL)
|
|
{
|
|
__glSetError(GL_INVALID_ENUM);
|
|
return;
|
|
}
|
|
|
|
switch(pname)
|
|
{
|
|
case GL_COLOR_TABLE_FORMAT_EXT:
|
|
*params = tex->paletteRequestedFormat;
|
|
break;
|
|
case GL_COLOR_TABLE_WIDTH_EXT:
|
|
*params = tex->paletteTotalSize;
|
|
break;
|
|
case GL_COLOR_TABLE_RED_SIZE_EXT:
|
|
case GL_COLOR_TABLE_GREEN_SIZE_EXT:
|
|
case GL_COLOR_TABLE_BLUE_SIZE_EXT:
|
|
case GL_COLOR_TABLE_ALPHA_SIZE_EXT:
|
|
*params = 8;
|
|
break;
|
|
#ifdef GL_EXT_flat_paletted_lighting
|
|
case GL_COLOR_TABLE_SUBDIVISION_EXT:
|
|
*params = tex->paletteSize;
|
|
break;
|
|
#endif
|
|
|
|
default:
|
|
__glSetError(GL_INVALID_ENUM);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void APIPRIVATE __glim_GetColorTableParameterfvEXT(GLenum target,
|
|
GLenum pname,
|
|
GLfloat *params)
|
|
{
|
|
__GLtexture *tex;
|
|
|
|
__GL_SETUP_NOT_IN_BEGIN();
|
|
|
|
tex = __glLookUpTexture(gc, target);
|
|
if (tex == NULL)
|
|
{
|
|
__glSetError(GL_INVALID_ENUM);
|
|
return;
|
|
}
|
|
|
|
switch(pname)
|
|
{
|
|
case GL_COLOR_TABLE_FORMAT_EXT:
|
|
*params = (GLfloat)tex->paletteRequestedFormat;
|
|
break;
|
|
case GL_COLOR_TABLE_WIDTH_EXT:
|
|
*params = (GLfloat)tex->paletteTotalSize;
|
|
break;
|
|
case GL_COLOR_TABLE_RED_SIZE_EXT:
|
|
case GL_COLOR_TABLE_GREEN_SIZE_EXT:
|
|
case GL_COLOR_TABLE_BLUE_SIZE_EXT:
|
|
case GL_COLOR_TABLE_ALPHA_SIZE_EXT:
|
|
*params = (GLfloat)8;
|
|
break;
|
|
#ifdef GL_EXT_flat_paletted_lighting
|
|
case GL_COLOR_TABLE_SUBDIVISION_EXT:
|
|
*params = (GLfloat)tex->paletteSize;
|
|
break;
|
|
#endif
|
|
|
|
default:
|
|
__glSetError(GL_INVALID_ENUM);
|
|
return;
|
|
}
|
|
}
|
|
#endif // GL_EXT_paletted_texture
|
|
|
|
#ifdef GL_EXT_flat_paletted_lighting
|
|
void APIPRIVATE __glim_ColorTableParameterivEXT(GLenum target,
|
|
GLenum pname,
|
|
const GLint *params)
|
|
{
|
|
__GLtexture *tex;
|
|
GLint ival;
|
|
|
|
__GL_SETUP_NOT_IN_BEGIN();
|
|
|
|
tex = __glLookUpTexture(gc, target);
|
|
if (tex == NULL)
|
|
{
|
|
__glSetError(GL_INVALID_ENUM);
|
|
return;
|
|
}
|
|
|
|
switch(pname)
|
|
{
|
|
case GL_COLOR_TABLE_SUBDIVISION_EXT:
|
|
ival = *params;
|
|
|
|
// Value must be an integer power of two between one and the total
|
|
// palette size
|
|
if ((ival & (ival-1)) != 0 ||
|
|
ival < 1 ||
|
|
ival > tex->paletteTotalSize)
|
|
{
|
|
__glSetError(GL_INVALID_VALUE);
|
|
return;
|
|
}
|
|
|
|
__glSetPaletteSubdivision(tex, ival);
|
|
break;
|
|
|
|
default:
|
|
__glSetError(GL_INVALID_ENUM);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void APIPRIVATE __glim_ColorTableParameterfvEXT(GLenum target,
|
|
GLenum pname,
|
|
const GLfloat *params)
|
|
{
|
|
__GLtexture *tex;
|
|
GLfloat fval;
|
|
GLint ival;
|
|
|
|
__GL_SETUP_NOT_IN_BEGIN();
|
|
|
|
tex = __glLookUpTexture(gc, target);
|
|
if (tex == NULL)
|
|
{
|
|
__glSetError(GL_INVALID_ENUM);
|
|
return;
|
|
}
|
|
|
|
switch(pname)
|
|
{
|
|
case GL_COLOR_TABLE_SUBDIVISION_EXT:
|
|
fval = *params;
|
|
ival = (int)fval;
|
|
|
|
// Value must be an integer power of two between one and the total
|
|
// palette size
|
|
if (fval != (GLfloat)ival ||
|
|
(ival & (ival-1)) != 0 ||
|
|
ival < 1 ||
|
|
ival > tex->paletteTotalSize)
|
|
{
|
|
__glSetError(GL_INVALID_VALUE);
|
|
return;
|
|
}
|
|
|
|
__glSetPaletteSubdivision(tex, ival);
|
|
break;
|
|
|
|
default:
|
|
__glSetError(GL_INVALID_ENUM);
|
|
return;
|
|
}
|
|
}
|
|
#endif // GL_EXT_flat_paletted_lighting
|