📄 mipmap.c
字号:
/*
** License Applicability. Except to the extent portions of this file are
** made subject to an alternative license as permitted in the SGI Free
** Software License B, Version 1.1 (the "License"), the contents of this
** file are subject only to the provisions of the License. You may not use
** this file except in compliance with the License. You may obtain a copy
** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
**
** http://oss.sgi.com/projects/FreeB
**
** Note that, as provided in the License, the Software is distributed on an
** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
**
** Original Code. The Original Code is: OpenGL Sample Implementation,
** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
** Copyright in any portions created by third parties is as indicated
** elsewhere herein. All Rights Reserved.
**
** Additional Notice Provisions: The application programming interfaces
** established by SGI in conjunction with the Original Code are The
** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
** Window System(R) (Version 1.3), released October 19, 1998. This software
** was created using the OpenGL(R) version 1.2.1 Sample Implementation
** published by SGI, but has not been independently verified as being
** compliant with the OpenGL(R) version 1.2.1 Specification.
**
*/
#include "gluos.h"
#include <assert.h>
#include <GL/gl.h>
#include <GL/glext.h>
#include <GL/glu.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h> /* UINT_MAX */
#include <math.h>
#include "gluint.h"
typedef union {
unsigned char ub[4];
unsigned short us[2];
unsigned int ui;
char b[4];
short s[2];
int i;
float f;
} Type_Widget;
/* Pixel storage modes */
typedef struct {
GLint pack_alignment;
GLint pack_row_length;
GLint pack_skip_rows;
GLint pack_skip_pixels;
GLint pack_lsb_first;
GLint pack_swap_bytes;
GLint pack_skip_images;
GLint pack_image_height;
GLint unpack_alignment;
GLint unpack_row_length;
GLint unpack_skip_rows;
GLint unpack_skip_pixels;
GLint unpack_lsb_first;
GLint unpack_swap_bytes;
GLint unpack_skip_images;
GLint unpack_image_height;
} PixelStorageModes;
static int gluBuild1DMipmapLevelsCore(GLenum, GLint,
GLsizei,
GLsizei,
GLenum, GLenum, GLint, GLint, GLint,
const void *);
static int gluBuild2DMipmapLevelsCore(GLenum, GLint,
GLsizei, GLsizei,
GLsizei, GLsizei,
GLenum, GLenum, GLint, GLint, GLint,
const void *);
static int gluBuild3DMipmapLevelsCore(GLenum, GLint,
GLsizei, GLsizei, GLsizei,
GLsizei, GLsizei, GLsizei,
GLenum, GLenum, GLint, GLint, GLint,
const void *);
/*
* internal function declarations
*/
static GLfloat bytes_per_element(GLenum type);
static GLint elements_per_group(GLenum format, GLenum type);
static GLint is_index(GLenum format);
static GLint image_size(GLint width, GLint height, GLenum format, GLenum type);
static void fill_image(const PixelStorageModes *,
GLint width, GLint height, GLenum format,
GLenum type, GLboolean index_format,
const void *userdata, GLushort *newimage);
static void empty_image(const PixelStorageModes *,
GLint width, GLint height, GLenum format,
GLenum type, GLboolean index_format,
const GLushort *oldimage, void *userdata);
static void scale_internal(GLint components, GLint widthin, GLint heightin,
const GLushort *datain,
GLint widthout, GLint heightout,
GLushort *dataout);
static void scale_internal_ubyte(GLint components, GLint widthin,
GLint heightin, const GLubyte *datain,
GLint widthout, GLint heightout,
GLubyte *dataout, GLint element_size,
GLint ysize, GLint group_size);
static void scale_internal_byte(GLint components, GLint widthin,
GLint heightin, const GLbyte *datain,
GLint widthout, GLint heightout,
GLbyte *dataout, GLint element_size,
GLint ysize, GLint group_size);
static void scale_internal_ushort(GLint components, GLint widthin,
GLint heightin, const GLushort *datain,
GLint widthout, GLint heightout,
GLushort *dataout, GLint element_size,
GLint ysize, GLint group_size,
GLint myswap_bytes);
static void scale_internal_short(GLint components, GLint widthin,
GLint heightin, const GLshort *datain,
GLint widthout, GLint heightout,
GLshort *dataout, GLint element_size,
GLint ysize, GLint group_size,
GLint myswap_bytes);
static void scale_internal_uint(GLint components, GLint widthin,
GLint heightin, const GLuint *datain,
GLint widthout, GLint heightout,
GLuint *dataout, GLint element_size,
GLint ysize, GLint group_size,
GLint myswap_bytes);
static void scale_internal_int(GLint components, GLint widthin,
GLint heightin, const GLint *datain,
GLint widthout, GLint heightout,
GLint *dataout, GLint element_size,
GLint ysize, GLint group_size,
GLint myswap_bytes);
static void scale_internal_float(GLint components, GLint widthin,
GLint heightin, const GLfloat *datain,
GLint widthout, GLint heightout,
GLfloat *dataout, GLint element_size,
GLint ysize, GLint group_size,
GLint myswap_bytes);
static int checkMipmapArgs(GLenum, GLenum, GLenum);
static GLboolean legalFormat(GLenum);
static GLboolean legalType(GLenum);
static GLboolean isTypePackedPixel(GLenum);
static GLboolean isLegalFormatForPackedPixelType(GLenum, GLenum);
static GLboolean isLegalLevels(GLint, GLint, GLint, GLint);
static void closestFit(GLenum, GLint, GLint, GLint, GLenum, GLenum,
GLint *, GLint *);
/* all extract/shove routines must return double to handle unsigned ints */
static GLdouble extractUbyte(int, const void *);
static void shoveUbyte(GLdouble, int, void *);
static GLdouble extractSbyte(int, const void *);
static void shoveSbyte(GLdouble, int, void *);
static GLdouble extractUshort(int, const void *);
static void shoveUshort(GLdouble, int, void *);
static GLdouble extractSshort(int, const void *);
static void shoveSshort(GLdouble, int, void *);
static GLdouble extractUint(int, const void *);
static void shoveUint(GLdouble, int, void *);
static GLdouble extractSint(int, const void *);
static void shoveSint(GLdouble, int, void *);
static GLdouble extractFloat(int, const void *);
static void shoveFloat(GLdouble, int, void *);
static void halveImageSlice(int, GLdouble (*)(int, const void *),
void (*)(GLdouble, int, void *),
GLint, GLint, GLint,
const void *, void *,
GLint, GLint, GLint, GLint, GLint);
static void halveImage3D(int, GLdouble (*)(int, const void *),
void (*)(GLdouble, int, void *),
GLint, GLint, GLint,
const void *, void *,
GLint, GLint, GLint, GLint, GLint);
/* packedpixel type scale routines */
static void extract332(int,const void *, GLfloat []);
static void shove332(const GLfloat [],int ,void *);
static void extract233rev(int,const void *, GLfloat []);
static void shove233rev(const GLfloat [],int ,void *);
static void extract565(int,const void *, GLfloat []);
static void shove565(const GLfloat [],int ,void *);
static void extract565rev(int,const void *, GLfloat []);
static void shove565rev(const GLfloat [],int ,void *);
static void extract4444(int,const void *, GLfloat []);
static void shove4444(const GLfloat [],int ,void *);
static void extract4444rev(int,const void *, GLfloat []);
static void shove4444rev(const GLfloat [],int ,void *);
static void extract5551(int,const void *, GLfloat []);
static void shove5551(const GLfloat [],int ,void *);
static void extract1555rev(int,const void *, GLfloat []);
static void shove1555rev(const GLfloat [],int ,void *);
static void extract8888(int,const void *, GLfloat []);
static void shove8888(const GLfloat [],int ,void *);
static void extract8888rev(int,const void *, GLfloat []);
static void shove8888rev(const GLfloat [],int ,void *);
static void extract1010102(int,const void *, GLfloat []);
static void shove1010102(const GLfloat [],int ,void *);
static void extract2101010rev(int,const void *, GLfloat []);
static void shove2101010rev(const GLfloat [],int ,void *);
static void scaleInternalPackedPixel(int,
void (*)(int, const void *,GLfloat []),
void (*)(const GLfloat [],int, void *),
GLint,GLint, const void *,
GLint,GLint,void *,GLint,GLint,GLint);
static void halveImagePackedPixel(int,
void (*)(int, const void *,GLfloat []),
void (*)(const GLfloat [],int, void *),
GLint, GLint, const void *,
void *, GLint, GLint, GLint);
static void halve1DimagePackedPixel(int,
void (*)(int, const void *,GLfloat []),
void (*)(const GLfloat [],int, void *),
GLint, GLint, const void *,
void *, GLint, GLint, GLint);
static void halve1Dimage_ubyte(GLint, GLuint, GLuint,const GLubyte *,
GLubyte *, GLint, GLint, GLint);
static void halve1Dimage_byte(GLint, GLuint, GLuint,const GLbyte *, GLbyte *,
GLint, GLint, GLint);
static void halve1Dimage_ushort(GLint, GLuint, GLuint, const GLushort *,
GLushort *, GLint, GLint, GLint, GLint);
static void halve1Dimage_short(GLint, GLuint, GLuint,const GLshort *, GLshort *,
GLint, GLint, GLint, GLint);
static void halve1Dimage_uint(GLint, GLuint, GLuint, const GLuint *, GLuint *,
GLint, GLint, GLint, GLint);
static void halve1Dimage_int(GLint, GLuint, GLuint, const GLint *, GLint *,
GLint, GLint, GLint, GLint);
static void halve1Dimage_float(GLint, GLuint, GLuint, const GLfloat *, GLfloat *,
GLint, GLint, GLint, GLint);
static GLint imageSize3D(GLint, GLint, GLint, GLenum,GLenum);
static void fillImage3D(const PixelStorageModes *, GLint, GLint, GLint,GLenum,
GLenum, GLboolean, const void *, GLushort *);
static void emptyImage3D(const PixelStorageModes *,
GLint, GLint, GLint, GLenum,
GLenum, GLboolean,
const GLushort *, void *);
static void scaleInternal3D(GLint, GLint, GLint, GLint, const GLushort *,
GLint, GLint, GLint, GLushort *);
static void retrieveStoreModes(PixelStorageModes *psm)
{
glGetIntegerv(GL_UNPACK_ALIGNMENT, &psm->unpack_alignment);
glGetIntegerv(GL_UNPACK_ROW_LENGTH, &psm->unpack_row_length);
glGetIntegerv(GL_UNPACK_SKIP_ROWS, &psm->unpack_skip_rows);
glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &psm->unpack_skip_pixels);
glGetIntegerv(GL_UNPACK_LSB_FIRST, &psm->unpack_lsb_first);
glGetIntegerv(GL_UNPACK_SWAP_BYTES, &psm->unpack_swap_bytes);
glGetIntegerv(GL_PACK_ALIGNMENT, &psm->pack_alignment);
glGetIntegerv(GL_PACK_ROW_LENGTH, &psm->pack_row_length);
glGetIntegerv(GL_PACK_SKIP_ROWS, &psm->pack_skip_rows);
glGetIntegerv(GL_PACK_SKIP_PIXELS, &psm->pack_skip_pixels);
glGetIntegerv(GL_PACK_LSB_FIRST, &psm->pack_lsb_first);
glGetIntegerv(GL_PACK_SWAP_BYTES, &psm->pack_swap_bytes);
}
static void retrieveStoreModes3D(PixelStorageModes *psm)
{
glGetIntegerv(GL_UNPACK_ALIGNMENT, &psm->unpack_alignment);
glGetIntegerv(GL_UNPACK_ROW_LENGTH, &psm->unpack_row_length);
glGetIntegerv(GL_UNPACK_SKIP_ROWS, &psm->unpack_skip_rows);
glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &psm->unpack_skip_pixels);
glGetIntegerv(GL_UNPACK_LSB_FIRST, &psm->unpack_lsb_first);
glGetIntegerv(GL_UNPACK_SWAP_BYTES, &psm->unpack_swap_bytes);
glGetIntegerv(GL_UNPACK_SKIP_IMAGES, &psm->unpack_skip_images);
glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT, &psm->unpack_image_height);
glGetIntegerv(GL_PACK_ALIGNMENT, &psm->pack_alignment);
glGetIntegerv(GL_PACK_ROW_LENGTH, &psm->pack_row_length);
glGetIntegerv(GL_PACK_SKIP_ROWS, &psm->pack_skip_rows);
glGetIntegerv(GL_PACK_SKIP_PIXELS, &psm->pack_skip_pixels);
glGetIntegerv(GL_PACK_LSB_FIRST, &psm->pack_lsb_first);
glGetIntegerv(GL_PACK_SWAP_BYTES, &psm->pack_swap_bytes);
glGetIntegerv(GL_PACK_SKIP_IMAGES, &psm->pack_skip_images);
glGetIntegerv(GL_PACK_IMAGE_HEIGHT, &psm->pack_image_height);
}
static int computeLog(GLuint value)
{
int i;
i = 0;
/* Error! */
if (value == 0) return -1;
for (;;) {
if (value & 1) {
/* Error ! */
if (value != 1) return -1;
return i;
}
value = value >> 1;
i++;
}
}
/*
** Compute the nearest power of 2 number. This algorithm is a little
** strange, but it works quite well.
*/
static int nearestPower(GLuint value)
{
int i;
i = 1;
/* Error! */
if (value == 0) return -1;
for (;;) {
if (value == 1) {
return i;
} else if (value == 3) {
return i*4;
}
value = value >> 1;
i *= 2;
}
}
#define __GLU_SWAP_2_BYTES(s)\
(GLushort)(((GLushort)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
#define __GLU_SWAP_4_BYTES(s)\
(GLuint)(((GLuint)((const GLubyte*)(s))[3])<<24 | \
((GLuint)((const GLubyte*)(s))[2])<<16 | \
((GLuint)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
static void halveImage(GLint components, GLuint width, GLuint height,
const GLushort *datain, GLushort *dataout)
{
int i, j, k;
int newwidth, newheight;
int delta;
GLushort *s;
const GLushort *t;
newwidth = width / 2;
newheight = height / 2;
delta = width * components;
s = dataout;
t = datain;
/* Piece o' cake! */
for (i = 0; i < newheight; i++) {
for (j = 0; j < newwidth; j++) {
for (k = 0; k < components; k++) {
s[0] = (t[0] + t[components] + t[delta] +
t[delta+components] + 2) / 4;
s++; t++;
}
t += components;
}
t += delta;
}
}
static void halveImage_ubyte(GLint components, GLuint width, GLuint height,
const GLubyte *datain, GLubyte *dataout,
GLint element_size, GLint ysize, GLint group_size)
{
int i, j, k;
int newwidth, newheight;
GLubyte *s;
const char *t;
/* handle case where there is only 1 column/row */
if (width == 1 || height == 1) {
assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
halve1Dimage_ubyte(components,width,height,datain,dataout,
element_size,ysize,group_size);
return;
}
newwidth = width / 2;
newheight = height / 2;
s = dataout;
t = (const char *)datain;
/* Piece o' cake! */
for (i = 0; i < newheight; i++) {
for (j = 0; j < newwidth; j++) {
for (k = 0; k < components; k++) {
s[0] = (*(const GLubyte*)t +
*(const GLubyte*)(t+group_size) +
*(const GLubyte*)(t+ysize) +
*(const GLubyte*)(t+ysize+group_size) + 2) / 4;
s++; t += element_size;
}
t += group_size;
}
t += ysize;
}
}
/* */
static void halve1Dimage_ubyte(GLint components, GLuint width, GLuint height,
const GLubyte *dataIn, GLubyte *dataOut,
GLint element_size, GLint ysize,
GLint group_size)
{
GLint halfWidth= width / 2;
GLint halfHeight= height / 2;
const char *src= (const char *) dataIn;
GLubyte *dest= dataOut;
int jj;
assert(width == 1 || height == 1); /* must be 1D */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -