state_teximage.c revision cbfc08f1668b06543c25f6280149198ea948d739
/* Copyright (c) 2001, Stanford University
* All rights reserved
*
* See the file LICENSE.txt for information on redistributing this software.
*/
#include "state.h"
#include "state/cr_statetypes.h"
#include "state/cr_texture.h"
#include "cr_pixeldata.h"
#include "cr_string.h"
#include "cr_mem.h"
#include "cr_version.h"
#include "state_internals.h"
static int
{
int bits = 0;
if (value & 0x1)
bits++;
}
return bits;
}
/**
* Return 1 if the target is a proxy target, 0 otherwise.
*/
static GLboolean
{
return (target == GL_PROXY_TEXTURE_1D ||
target == GL_PROXY_TEXTURE_2D ||
target == GL_PROXY_TEXTURE_3D ||
}
/**
* Test if a texture width, height or depth is legal.
* It must be true that 0 <= size <= max.
* Furthermore, if the ARB_texture_non_power_of_two extension isn't
* present, size must also be a power of two.
*/
static GLboolean
{
return GL_FALSE;
if (!g->extensions.ARB_texture_non_power_of_two) {
/* check for power of two */
return GL_FALSE;
}
return GL_TRUE;
}
/**
* Return the max legal texture level parameter for the given target.
*/
static GLint
{
CRTextureState *t = &(g->texture);
switch (target) {
case GL_TEXTURE_1D:
case GL_PROXY_TEXTURE_1D:
case GL_TEXTURE_2D:
case GL_PROXY_TEXTURE_2D:
return t->maxLevel;
case GL_TEXTURE_3D:
case GL_PROXY_TEXTURE_3D:
return t->max3DLevel;
return t->maxCubeMapLevel;
case GL_TEXTURE_RECTANGLE_NV:
return t->maxRectLevel;
default:
return 0;
}
}
/**
* If GL_GENERATE_MIPMAP_SGIS is true and we modify the base level texture
* image we have to finish the mipmap.
* remaining image levels. The image data doesn't matter here - the back-
* end OpenGL library will fill those in.
*/
static void
{
if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
}
else {
}
{
if (width > 1)
width /= 2;
if (height > 1)
height /= 2;
if (depth > 1)
depth /= 2;
#ifdef CR_ARB_texture_compression
#endif
break;
}
/* Set this flag so when we do the state diff, we enable GENERATE_MIPMAP
* prior to calling diff.TexImage().
*/
}
/**
* Given a texture target and level, return pointers to the corresponding
* texture object and texture image level.
*/
void
{
CRTextureState *t = &(g->texture);
switch (texTarget) {
case GL_TEXTURE_1D:
return;
case GL_PROXY_TEXTURE_1D:
return;
case GL_TEXTURE_2D:
return;
case GL_PROXY_TEXTURE_2D:
return;
case GL_TEXTURE_3D:
return;
case GL_PROXY_TEXTURE_3D:
return;
default:
/* fall-through */
;
}
#ifdef CR_NV_texture_rectangle
if (g->extensions.NV_texture_rectangle) {
switch (texTarget) {
return;
case GL_TEXTURE_RECTANGLE_NV:
return;
default:
/* fall-through */
;
}
}
#endif
#ifdef CR_ARB_texture_cube_map
if (g->extensions.ARB_texture_cube_map) {
switch (texTarget) {
*obj = &(t->proxyCubeMap);
return;
case GL_TEXTURE_CUBE_MAP_ARB:
return;
return;
return;
return;
return;
return;
return;
default:
/* fall-through */
;
}
}
#endif
}
/**
* Do parameter error checking for glTexImagexD functions.
* We'll call crStateError if we detect any errors, unless it's a proxy target.
* Return GL_TRUE if any errors, GL_FALSE if no errors.
*/
static GLboolean
{
CRContext *g = GetCurrentContext();
if (g->current.inBeginEnd)
{
return GL_TRUE;
}
/*
* Test target
*/
switch (target)
{
case GL_TEXTURE_1D:
case GL_PROXY_TEXTURE_1D:
if (dims != 1) {
"glTexImage(invalid target=0x%x)", target);
return GL_TRUE;
}
break;
case GL_TEXTURE_2D:
case GL_PROXY_TEXTURE_2D:
if (dims != 2) {
"glTexImage(invalid target=0x%x)", target);
return GL_TRUE;
}
break;
case GL_TEXTURE_3D:
case GL_PROXY_TEXTURE_3D:
if (dims != 3) {
"glTexImage(invalid target=0x%x)", target);
return GL_TRUE;
}
break;
#ifdef CR_NV_texture_rectangle
case GL_TEXTURE_RECTANGLE_NV:
"glTexImage2D(invalid target=0x%x)", target);
return GL_TRUE;
}
break;
#endif
#ifdef CR_ARB_texture_cube_map
"glTexImage2D(invalid target=0x%x)", target);
return GL_TRUE;
}
break;
#endif
default:
return GL_TRUE;
}
/*
* Test level
*/
if (!IsProxyTarget(target))
return GL_TRUE;
}
/*
* Test border
*/
if (!IsProxyTarget(target))
return GL_TRUE;
}
if ((target == GL_PROXY_TEXTURE_RECTANGLE_NV ||
if (!IsProxyTarget(target))
"glTexImage2D(border=%d)", border);
return GL_TRUE;
}
/*
* Test width, height, depth
*/
if (!IsProxyTarget(target))
"glTexImage1D(width=%d)", width);
return GL_TRUE;
}
}
if (!IsProxyTarget(target))
return GL_TRUE;
}
}
if (!IsProxyTarget(target))
"glTexImage3D(width=%d, height=%d, depth=%d)",
return GL_TRUE;
}
}
else if (target == GL_PROXY_TEXTURE_RECTANGLE_NV ||
if (!IsProxyTarget(target))
return GL_TRUE;
}
}
else {
/* cube map */
if (!IsProxyTarget(target))
return GL_TRUE;
}
}
/* OK, no errors */
return GL_FALSE;
}
/**
* Do error check for glTexSubImage() functions.
* We'll call crStateError if we detect any errors.
* Return GL_TRUE if any errors, GL_FALSE if no errors.
*/
static GLboolean
{
CRContext *g = GetCurrentContext();
if (g->current.inBeginEnd) {
return GL_TRUE;
}
if (dims == 1) {
if (target != GL_TEXTURE_1D) {
"glTexSubImage1D(target=0x%x)", target);
return GL_TRUE;
}
}
else if (dims == 2) {
if (target != GL_TEXTURE_2D &&
"glTexSubImage2D(target=0x%x)", target);
return GL_TRUE;
}
}
else if (dims == 3) {
if (target != GL_TEXTURE_3D) {
"glTexSubImage3D(target=0x%x)", target);
return GL_TRUE;
}
}
/* test level */
return GL_TRUE;
}
"glTexSubImage%uD(target or level)", dims);
return GL_TRUE;
}
"glTexSubImage%uD(xoffset=%d + width=%d > %d)",
return GL_TRUE;
}
"glTexSubImage%uD(yoffset=%d + height=%d > %d)",
return GL_TRUE;
}
return GL_TRUE;
}
/* OK, no errors */
return GL_FALSE;
}
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRTextureState *t = &(g->texture);
CRClientState *c = &(g->client);
FLUSH();
if (IsProxyTarget(target)) {
/* clear all state, but don't generate error */
}
else {
/* error was already recorded */
}
return;
}
if (IsProxyTarget(target))
else
{
/* this is not a proxy texture target so alloc storage */
{
"glTexImage1D out of memory");
return;
}
if (pixels)
}
if (width)
else
tl->bytesPerPixel = 0;
#ifdef CR_SGIS_generate_mipmap
}
else {
}
#endif
/* XXX may need to do some fine-tuning here for proxy textures */
}
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRTextureState *t = &(g->texture);
CRClientState *c = &(g->client);
FLUSH();
/* NOTE: we skip parameter error checking if this is a distributed
* texture! The user better provide correct parameters!!!
*/
if (!is_distrib
if (IsProxyTarget(target)) {
/* clear all state, but don't generate error */
}
else {
/* error was already recorded */
}
return;
}
/* compute size of image buffer */
if (is_distrib) {
}
else if (IsProxyTarget(target)) {
}
else {
}
/* allocate the image buffer and fill it */
{
/* this is not a proxy texture target so alloc storage */
{
"glTexImage2D out of memory");
return;
}
if (pixels)
{
if (is_distrib)
{
}
else
{
}
}
}
{
if (is_distrib)
else
}
else
tl->bytesPerPixel = 0;
#ifdef CR_SGIS_generate_mipmap
}
else {
}
#endif
/* XXX may need to do some fine-tuning here for proxy textures */
}
#if defined( CR_OPENGL_VERSION_1_2 ) || defined( GL_EXT_texture3D )
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRTextureState *t = &(g->texture);
CRClientState *c = &(g->client);
FLUSH();
if (IsProxyTarget(target)) {
/* clear all state, but don't generate error */
}
else {
/* error was already recorded */
}
return;
}
if (IsProxyTarget(target))
else
{
/* this is not a proxy texture target so alloc storage */
{
"glTexImage3D out of memory");
return;
}
if (pixels)
}
#ifdef CR_SGIS_generate_mipmap
}
else {
}
#endif
/* XXX may need to do some fine-tuning here for proxy textures */
}
#endif /* CR_OPENGL_VERSION_1_2 || GL_EXT_texture3D */
#ifdef GL_EXT_texture3D
void STATE_APIENTRY
{
}
#endif /* GL_EXT_texture3D */
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRTextureState *t = &(g->texture);
CRClientState *c = &(g->client);
FLUSH();
return; /* GL error state already set */
}
#ifdef CR_SGIS_generate_mipmap
}
else {
}
#endif
}
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRClientState *c = &(g->client);
int i;
FLUSH();
return; /* GL error state already set */
}
subimg =
/* Copy the data into the texture */
for (i = 0; i < height; i++)
{
}
#ifdef CR_SGIS_generate_mipmap
}
else {
}
#endif
}
#if defined( CR_OPENGL_VERSION_1_2 )
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRTextureState *t = &(g->texture);
CRClientState *c = &(g->client);
int i;
FLUSH();
return; /* GL error state already set */
}
subimg =
(GLubyte *)
/* Copy the data into the texture */
for (i = 0; i < depth; i++)
{
}
#ifdef CR_SGIS_generate_mipmap
}
else {
}
#endif
}
#endif /* CR_OPENGL_VERSION_1_2 || GL_EXT_texture3D */
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRTextureState *t = &(g->texture);
FLUSH();
if (IsProxyTarget(target)) {
/* clear all state, but don't generate error */
}
else {
/* error was already recorded */
}
return;
}
if (IsProxyTarget(target))
else
{
/* this is not a proxy texture target so alloc storage */
{
"glTexImage1D out of memory");
return;
}
if (data)
}
#ifdef CR_SGIS_generate_mipmap
}
else {
}
#endif
}
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRTextureState *t = &(g->texture);
FLUSH();
if (IsProxyTarget(target)) {
/* clear all state, but don't generate error */
}
else {
/* error was already recorded */
}
return;
}
if (IsProxyTarget(target))
else
{
/* this is not a proxy texture target so alloc storage */
{
"glTexImage2D out of memory");
return;
}
if (data)
}
#ifdef CR_SGIS_generate_mipmap
}
else {
}
#endif
/* XXX may need to do some fine-tuning here for proxy textures */
}
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRTextureState *t = &(g->texture);
FLUSH();
if (IsProxyTarget(target)) {
/* clear all state, but don't generate error */
}
else {
/* error was already recorded */
}
return;
}
if (IsProxyTarget(target))
else
{
/* this is not a proxy texture target so alloc storage */
{
"glCompressedTexImage3D out of memory");
return;
}
if (data)
}
#ifdef CR_SGIS_generate_mipmap
}
else {
}
#endif
/* XXX may need to do some fine-tuning here for proxy textures */
}
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRTextureState *t = &(g->texture);
FLUSH();
return; /* GL error state already set */
}
/* just memcpy */
}
else {
/* XXX this depends on the exact compression method */
}
#ifdef CR_SGIS_generate_mipmap
}
else {
}
#endif
}
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRTextureState *t = &(g->texture);
FLUSH();
return; /* GL error state already set */
}
/* just memcpy */
}
else {
/* XXX this depends on the exact compression method */
}
#ifdef CR_SGIS_generate_mipmap
}
else {
}
#endif
}
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRTextureState *t = &(g->texture);
FLUSH();
return; /* GL error state already set */
}
/* just memcpy */
}
else {
/* XXX this depends on the exact compression method */
}
#ifdef CR_SGIS_generate_mipmap
}
else {
}
#endif
}
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
if (g->current.inBeginEnd)
{
return;
}
"glGetCompressedTexImage(invalid target or level)");
return;
}
if (!tl->compressed) {
"glGetCompressedTexImage(not a compressed texture)");
return;
}
}
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRClientState *c = &(g->client);
if (g->current.inBeginEnd)
{
return;
}
"glGetTexImage(invalid target or level)");
return;
}
if (tl->compressed) {
crWarning("glGetTexImage cannot decompress a compressed texture!");
return;
}
switch (format)
{
case GL_RED:
case GL_GREEN:
case GL_BLUE:
case GL_ALPHA:
case GL_RGB:
case GL_RGBA:
case GL_LUMINANCE:
case GL_LUMINANCE_ALPHA:
break;
default:
"glGetTexImage called with bogus format: %d", format);
return;
}
switch (type)
{
case GL_UNSIGNED_BYTE:
case GL_BYTE:
case GL_UNSIGNED_SHORT:
case GL_SHORT:
case GL_UNSIGNED_INT:
case GL_INT:
case GL_FLOAT:
break;
default:
"glGetTexImage called with bogus type: %d", type);
return;
}
#ifdef CR_OPENGL_VERSION_1_2
if (target == GL_TEXTURE_3D)
{
}
else
#endif
{
}
}