Introduced new gluScaleImage function that uses a PixelStorageModes structure to pass in details on image packing,

rather than relying upon glGet's to get the values.
This commit is contained in:
Robert Osfield 2010-10-07 10:51:22 +00:00
parent 021484440c
commit 12e6a23451
6 changed files with 152 additions and 134 deletions

View File

@ -30,46 +30,6 @@
const std::string FILE_IDENTIFER("osgphotoalbum photo archive");
class MyGraphicsContext {
public:
MyGraphicsContext()
{
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
traits->x = 0;
traits->y = 0;
traits->width = 1;
traits->height = 1;
traits->windowDecoration = false;
traits->doubleBuffer = false;
traits->sharedContext = 0;
traits->pbuffer = true;
_gc = osg::GraphicsContext::createGraphicsContext(traits.get());
if (!_gc)
{
osg::notify(osg::NOTICE)<<"Failed to create pbuffer, failing back to normal graphics window."<<std::endl;
traits->pbuffer = false;
_gc = osg::GraphicsContext::createGraphicsContext(traits.get());
}
if (_gc.valid())
{
_gc->realize();
_gc->makeCurrent();
std::cout<<"Realized window"<<std::endl;
}
}
bool valid() const { return _gc.valid() && _gc->isRealized(); }
private:
osg::ref_ptr<osg::GraphicsContext> _gc;
};
PhotoArchive::PhotoArchive(const std::string& filename)
{
readPhotoIndex(filename);
@ -206,9 +166,6 @@ void PhotoArchive::buildArchive(const std::string& filename, const FileNameList&
std::cout<<"Building photo archive containing "<<photoIndex.size()<<" pictures"<<std::endl;
// create a graphics context so we can do data operations
MyGraphicsContext context;
// open up the archive for writing to
osgDB::ofstream out(filename.c_str(), std::ios::out | std::ios::binary);
@ -258,10 +215,11 @@ void PhotoArchive::buildArchive(const std::string& filename, const FileNameList&
return;
}
glPixelStorei(GL_PACK_ALIGNMENT,image->getPacking());
glPixelStorei(GL_UNPACK_ALIGNMENT,image->getPacking());
PixelStorageModes psm;
psm.pack_alignment = image->getPacking();
psm.unpack_alignment = image->getPacking();
GLint status = gluScaleImage(image->getPixelFormat(),
GLint status = gluScaleImage(&psm, image->getPixelFormat(),
image->s(),
image->t(),
image->getDataType(),
@ -324,10 +282,11 @@ void PhotoArchive::buildArchive(const std::string& filename, const FileNameList&
return;
}
glPixelStorei(GL_PACK_ALIGNMENT,image->getPacking());
glPixelStorei(GL_UNPACK_ALIGNMENT,image->getPacking());
PixelStorageModes psm;
psm.pack_alignment = image->getPacking();
psm.unpack_alignment = image->getPacking();
GLint status = gluScaleImage(image->getPixelFormat(),
GLint status = gluScaleImage(&psm, image->getPixelFormat(),
image->s(),
image->t(),
image->getDataType(),

View File

@ -16,8 +16,50 @@
#include <osg/GL>
extern OSG_EXPORT GLint gluScaleImage (GLenum format, GLsizei wIn, GLsizei hIn, GLenum typeIn, const void *dataIn, GLsizei wOut, GLsizei hOut, GLenum typeOut, GLvoid* dataOut);
/* Pixel storage modes, used by gluScaleImage */
struct OSG_EXPORT PixelStorageModes
{
// sets defaults as per glGet docs in OpenGL red book
PixelStorageModes();
// use glGet's to retrieve all the current settings
void retrieveStoreModes();
// use glGet's to retrieve all the current 3D settings
void retrieveStoreModes3D();
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;
} ;
extern OSG_EXPORT const GLubyte * gluErrorString (GLenum error);
/** OSG specific gluScaleImage function that allows you to pass in the PixelStoreModes, which
* enables the code to avoid glGet's that are associated with the conventional gluScaleImage function.
* Avoiding glGet's allows this gluScaleImage function to be called at any time, from any thread, there
* is no need to have a graphics context current.*/
extern OSG_EXPORT GLint gluScaleImage (PixelStorageModes* psm, GLenum format, GLsizei wIn, GLsizei hIn, GLenum typeIn, const void *dataIn, GLsizei wOut, GLsizei hOut, GLenum typeOut, GLvoid* dataOut);
/** Traditional GLU gluScaleImage function that sets up the PixelStoreModes automatically by doing glGets.;
* The use of glGet's means that you can only call this function from a thread with a valid graphics context.
* The use of glGet's will also result in lower performance due to the round trip to the OpenGL driver.*/
extern OSG_EXPORT GLint gluScaleImage (GLenum format, GLsizei wIn, GLsizei hIn, GLenum typeIn, const void *dataIn, GLsizei wOut, GLsizei hOut, GLenum typeOut, GLvoid* dataOut);
extern OSG_EXPORT GLint gluBuild1DMipmapLevels (GLenum target, GLint internalFormat, GLsizei width, GLenum format, GLenum type, GLint level, GLint base, GLint max, const void *data);
extern OSG_EXPORT GLint gluBuild1DMipmaps (GLenum target, GLint internalFormat, GLsizei width, GLenum format, GLenum type, const void *data);
extern OSG_EXPORT GLint gluBuild2DMipmapLevels (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint level, GLint base, GLint max, const void *data);

View File

@ -172,14 +172,10 @@ class OSG_EXPORT Image : public BufferData
virtual void readImageFromCurrentTexture(unsigned int contextID, bool copyMipMapsIfAvailable, GLenum type = GL_UNSIGNED_BYTE);
/** Scale image to specified size.
* \warning The method uses gluScaleImage() and thus needs a valid rendering context.
*/
/** Scale image to specified size. */
void scaleImage(int s,int t,int r) { scaleImage(s,t,r, getDataType()); }
/** Scale image to specified size and with specified data type.
* \warning The method uses gluScaleImage() and thus needs a valid rendering context.
*/
/** Scale image to specified size and with specified data type. */
virtual void scaleImage(int s,int t,int r, GLenum newDataType);
/** Copy a source Image into a subpart of this Image at specified position.

View File

@ -936,10 +936,11 @@ void Image::scaleImage(int s,int t,int r, GLenum newDataType)
return;
}
glPixelStorei(GL_PACK_ALIGNMENT,_packing);
glPixelStorei(GL_UNPACK_ALIGNMENT,_packing);
PixelStorageModes psm;
psm.pack_alignment = _packing;
psm.unpack_alignment = _packing;
GLint status = gluScaleImage(_pixelFormat,
GLint status = gluScaleImage(&psm, _pixelFormat,
_s,
_t,
_dataType,
@ -1000,12 +1001,12 @@ void Image::copySubImage(int s_offset, int t_offset, int r_offset, const osg::Im
void* data_destination = data(s_offset,t_offset,r_offset);
glPixelStorei(GL_PACK_ALIGNMENT,source->getPacking());
glPixelStorei(GL_PACK_ROW_LENGTH,_s);
PixelStorageModes psm;
psm.pack_alignment = _packing;
psm.pack_row_length = _packing;
psm.unpack_alignment = _packing;
glPixelStorei(GL_UNPACK_ALIGNMENT,_packing);
GLint status = gluScaleImage(_pixelFormat,
GLint status = gluScaleImage(&psm, _pixelFormat,
source->s(),
source->t(),
source->getDataType(),

View File

@ -1651,12 +1651,16 @@ void Texture::applyTexImage2D_load(State& state, GLenum target, const Image* ima
if (!image->getFileName().empty()) { OSG_NOTICE << "Scaling image '"<<image->getFileName()<<"' from ("<<image->s()<<","<<image->t()<<") to ("<<inwidth<<","<<inheight<<")"<<std::endl; }
else { OSG_NOTICE << "Scaling image from ("<<image->s()<<","<<image->t()<<") to ("<<inwidth<<","<<inheight<<")"<<std::endl; }
PixelStorageModes psm;
psm.pack_alignment = image->getPacking();
psm.unpack_alignment = image->getPacking();
// rescale the image to the correct size.
glPixelStorei(GL_PACK_ALIGNMENT,image->getPacking());
gluScaleImage(image->getPixelFormat(),
gluScaleImage(&psm, image->getPixelFormat(),
image->s(),image->t(),image->getDataType(),image->data(),
inwidth,inheight,image->getDataType(),
dataPtr);
}
bool mipmappingRequired = _min_filter != LINEAR && _min_filter != NEAREST;
@ -1890,8 +1894,11 @@ void Texture::applyTexImage2D_subload(State& state, GLenum target, const Image*
else { OSG_NOTICE << "Scaling image from ("<<image->s()<<","<<image->t()<<") to ("<<inwidth<<","<<inheight<<")"<<std::endl; }
// rescale the image to the correct size.
glPixelStorei(GL_PACK_ALIGNMENT,image->getPacking());
gluScaleImage(image->getPixelFormat(),
PixelStorageModes psm;
psm.pack_alignment = image->getPacking();
psm.unpack_alignment = image->getPacking();
gluScaleImage(&psm, image->getPixelFormat(),
image->s(),image->t(),image->getDataType(),image->data(),
inwidth,inheight,image->getDataType(),
dataPtr);

View File

@ -48,6 +48,7 @@
#include <string.h>
#include <limits.h> /* UINT_MAX */
#include <math.h>
#include <osg/Notify>
typedef union {
unsigned char ub[4];
@ -59,27 +60,6 @@ typedef union {
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,
@ -258,42 +238,64 @@ static void emptyImage3D(const PixelStorageModes *,
static void scaleInternal3D(GLint, GLint, GLint, GLint, const GLushort *,
GLint, GLint, GLint, GLushort *);
static void retrieveStoreModes(PixelStorageModes *psm)
PixelStorageModes::PixelStorageModes()
{
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);
// Default Settings set from values specified in glGet docs in the OpenGL red book.
pack_alignment = 4;
pack_row_length = 0;
pack_skip_rows = 0;
pack_skip_pixels = 0;
pack_lsb_first = GL_FALSE;
pack_swap_bytes = GL_FALSE;
pack_skip_images = 0;
pack_image_height = 0;
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);
unpack_alignment = 4;
unpack_row_length = 0;
unpack_skip_rows = 0;
unpack_skip_pixels = 0;
unpack_lsb_first = GL_FALSE;
unpack_swap_bytes = GL_FALSE;
unpack_skip_images = 0;
unpack_image_height = 0;
}
static void retrieveStoreModes3D(PixelStorageModes *psm)
void PixelStorageModes::retrieveStoreModes()
{
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_UNPACK_ALIGNMENT, &unpack_alignment);
glGetIntegerv(GL_UNPACK_ROW_LENGTH, &unpack_row_length);
glGetIntegerv(GL_UNPACK_SKIP_ROWS, &unpack_skip_rows);
glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &unpack_skip_pixels);
glGetIntegerv(GL_UNPACK_LSB_FIRST, &unpack_lsb_first);
glGetIntegerv(GL_UNPACK_SWAP_BYTES, &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);
glGetIntegerv(GL_PACK_SKIP_IMAGES, &psm->pack_skip_images);
glGetIntegerv(GL_PACK_IMAGE_HEIGHT, &psm->pack_image_height);
glGetIntegerv(GL_PACK_ALIGNMENT, &pack_alignment);
glGetIntegerv(GL_PACK_ROW_LENGTH, &pack_row_length);
glGetIntegerv(GL_PACK_SKIP_ROWS, &pack_skip_rows);
glGetIntegerv(GL_PACK_SKIP_PIXELS, &pack_skip_pixels);
glGetIntegerv(GL_PACK_LSB_FIRST, &pack_lsb_first);
glGetIntegerv(GL_PACK_SWAP_BYTES, &pack_swap_bytes);
}
void PixelStorageModes::retrieveStoreModes3D()
{
glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpack_alignment);
glGetIntegerv(GL_UNPACK_ROW_LENGTH, &unpack_row_length);
glGetIntegerv(GL_UNPACK_SKIP_ROWS, &unpack_skip_rows);
glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &unpack_skip_pixels);
glGetIntegerv(GL_UNPACK_LSB_FIRST, &unpack_lsb_first);
glGetIntegerv(GL_UNPACK_SWAP_BYTES, &unpack_swap_bytes);
glGetIntegerv(GL_UNPACK_SKIP_IMAGES, &unpack_skip_images);
glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT, &unpack_image_height);
glGetIntegerv(GL_PACK_ALIGNMENT, &pack_alignment);
glGetIntegerv(GL_PACK_ROW_LENGTH, &pack_row_length);
glGetIntegerv(GL_PACK_SKIP_ROWS, &pack_skip_rows);
glGetIntegerv(GL_PACK_SKIP_PIXELS, &pack_skip_pixels);
glGetIntegerv(GL_PACK_LSB_FIRST, &pack_lsb_first);
glGetIntegerv(GL_PACK_SWAP_BYTES, &pack_swap_bytes);
glGetIntegerv(GL_PACK_SKIP_IMAGES, &pack_skip_images);
glGetIntegerv(GL_PACK_IMAGE_HEIGHT, &pack_image_height);
}
static int computeLog(GLuint value)
@ -3507,7 +3509,7 @@ noProxyTextures:
} /* closestFit() */
GLint GLAPIENTRY
gluScaleImage(GLenum format, GLsizei widthin, GLsizei heightin,
gluScaleImage(PixelStorageModes* psm, GLenum format, GLsizei widthin, GLsizei heightin,
GLenum typein, const void *datain,
GLsizei widthout, GLsizei heightout, GLenum typeout,
void *dataout)
@ -3515,8 +3517,6 @@ gluScaleImage(GLenum format, GLsizei widthin, GLsizei heightin,
int components;
GLushort *beforeImage;
GLushort *afterImage;
PixelStorageModes psm;
if (widthin == 0 || heightin == 0 || widthout == 0 || heightout == 0) {
return 0;
}
@ -3542,13 +3542,12 @@ gluScaleImage(GLenum format, GLsizei widthin, GLsizei heightin,
return GLU_OUT_OF_MEMORY;
}
retrieveStoreModes(&psm);
fill_image(&psm,widthin, heightin, format, typein, is_index(format),
fill_image(psm,widthin, heightin, format, typein, is_index(format),
datain, beforeImage);
components = elements_per_group(format, 0);
scale_internal(components, widthin, heightin, beforeImage,
widthout, heightout, afterImage);
empty_image(&psm,widthout, heightout, format, typeout,
empty_image(psm,widthout, heightout, format, typeout,
is_index(format), afterImage, dataout);
free((GLbyte *) beforeImage);
free((GLbyte *) afterImage);
@ -3556,6 +3555,20 @@ gluScaleImage(GLenum format, GLsizei widthin, GLsizei heightin,
return 0;
}
GLint GLAPIENTRY
gluScaleImage(GLenum format, GLsizei widthin, GLsizei heightin,
GLenum typein, const void *datain,
GLsizei widthout, GLsizei heightout, GLenum typeout,
void *dataout)
{
PixelStorageModes psm;
psm.retrieveStoreModes();
return gluScaleImage(&psm, format, widthin, heightin,
typein, datain,
widthout, heightout, typeout,
dataout);
}
int gluBuild1DMipmapLevelsCore(GLenum target, GLint internalFormat,
GLsizei width,
GLsizei widthPowerOf2,
@ -3583,7 +3596,7 @@ int gluBuild1DMipmapLevelsCore(GLenum target, GLint internalFormat,
levels+= userLevel;
retrieveStoreModes(&psm);
psm.retrieveStoreModes();
newImage = (GLushort *)
malloc(image_size(width, 1, format, GL_UNSIGNED_SHORT));
newImage_width = width;
@ -3720,7 +3733,7 @@ static int bitmapBuild2DMipmaps(GLenum target, GLint internalFormat,
GLint cmpts;
PixelStorageModes psm;
retrieveStoreModes(&psm);
psm.retrieveStoreModes();
#if 0
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
@ -3850,7 +3863,7 @@ static int gluBuild2DMipmapLevelsCore(GLenum target, GLint internalFormat,
levels+= userLevel;
retrieveStoreModes(&psm);
psm.retrieveStoreModes();
myswap_bytes = psm.unpack_swap_bytes;
cmpts = elements_per_group(format,type);
if (psm.unpack_row_length > 0) {
@ -7410,7 +7423,7 @@ int gluScaleImage3D(GLenum format,
free(afterImage);
return GLU_OUT_OF_MEMORY;
}
retrieveStoreModes3D(&psm);
psm.retrieveStoreModes3D();
fillImage3D(&psm,widthIn,heightIn,depthIn,format,typeIn, is_index(format),
dataIn, beforeImage);
@ -7778,7 +7791,7 @@ static int gluBuild3DMipmapLevelsCore(GLenum target, GLint internalFormat,
levels+= userLevel;
retrieveStoreModes3D(&psm);
psm.retrieveStoreModes3D();
myswapBytes = psm.unpack_swap_bytes;
cmpts = elements_per_group(format,type);
if (psm.unpack_row_length > 0) {