Commit 0e63486f authored by hybrid's avatar hybrid

Merged revisions 1309:1314 from 1.4 branch.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@1315 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 6a0d4ea7
...@@ -47,7 +47,39 @@ Changes in version 1.5 (... 2008) ...@@ -47,7 +47,39 @@ Changes in version 1.5 (... 2008)
- Finally added StarSonata patch with table element and TabControl additions. Table is based on MultiColor listbox by Acki, and has loads of changes by CuteAlien. - Finally added StarSonata patch with table element and TabControl additions. Table is based on MultiColor listbox by Acki, and has loads of changes by CuteAlien.
------------------------------------------- -------------------------------------------
Changes in version 1.4.1 (??? 2008) Changes in version 1.4.1 (??.4.2008)
- New JPG image writer version by Vitek.
- Texture matrix fixes, all methods should now work as expected.
- Some container methods now return the this pointer after member functions have been called on them, in order to allow call chains.
- Some new methods for SColorf access, for uniform API of all colors.
- bug fix for SMaterialLayer equality check. Did only check the TextureMatrix pointers, instead of the matrices.
- New getMesh method for the SceneManager, which takes an IReadFile instead of a filename.
- Support for flags _WIN32 and _WIN64 in addition to WIN32 and WIN64 added, this simplifies usage of Irrlicht headers under MSVC.
- Fixed a crash in GUIMeshViewer
- new string method findLastChar by Halifax
- GUIEditBox got the 1 pixel shift after click fixed.
- Some debug visualization has been fixed for skinned meshes
- Undef PI symbol before declaring core::PI to avoid compilation problems
- SAnimatedMesh now properly returns properties of Meshes[0] if those exist, such that it should be usable in place of an SMesh again.
- Fixed 2d initialisation in opengl and d3d9 driver. This should fix problems with render states mixing up and distrubing, e.g. skin effects.
- Avoid a crash when passing setSkin the current skin
- Fixed current frame calculation for non-looped animations. Bug reported by greenya.
- Fixed bug in CBillboardSceneNode::setColor, reported by rogerborg - Fixed bug in CBillboardSceneNode::setColor, reported by rogerborg
...@@ -82,7 +114,7 @@ Changes in version 1.4.1 (??? 2008) ...@@ -82,7 +114,7 @@ Changes in version 1.4.1 (??? 2008)
- Function setbit was renamed to setbit_cond to avoid name clashes. - Function setbit was renamed to setbit_cond to avoid name clashes.
- Fixed .x animations with multiple references to the same joint from different meshes. - Fixed .x animations with multiple references to the same joint from different meshes. Fixed texture path problems.
- Support for Milkshape 1.8 files, also with multiple weights per joint. - Support for Milkshape 1.8 files, also with multiple weights per joint.
......
This diff is collapsed.
...@@ -154,7 +154,7 @@ namespace video ...@@ -154,7 +154,7 @@ namespace video
if (different) if (different)
return true; return true;
else else
different |= (TextureMatrix != b.TextureMatrix); different |= (TextureMatrix != b.TextureMatrix) && TextureMatrix && b.TextureMatrix && (*TextureMatrix != *(b.TextureMatrix));
return different; return different;
} }
......
This diff is collapsed.
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#include "CColorConverter.h" #include "CColorConverter.h"
#include "IWriteFile.h" #include "IWriteFile.h"
#include "CImage.h" #include "CImage.h"
#include "CColorConverter.h"
#include "irrString.h" #include "irrString.h"
#ifdef _IRR_COMPILE_WITH_LIBJPEG_ #ifdef _IRR_COMPILE_WITH_LIBJPEG_
...@@ -23,7 +22,6 @@ extern "C" ...@@ -23,7 +22,6 @@ extern "C"
#include "jpeglib/jpeglib.h" #include "jpeglib/jpeglib.h"
#include "jpeglib/jerror.h" #include "jpeglib/jerror.h"
#endif #endif
#include <setjmp.h>
} }
...@@ -32,118 +30,156 @@ namespace irr ...@@ -32,118 +30,156 @@ namespace irr
namespace video namespace video
{ {
// The writer uses a 4k buffer and flushes to disk each time it's filled
#define OUTPUT_BUF_SIZE 4096
typedef struct typedef struct
{ {
struct jpeg_destination_mgr pub; /* public fields */ struct jpeg_destination_mgr pub;/* public fields */
JOCTET * buffer; /* image buffer */ io::IWriteFile* file; /* target file */
u32 buffer_size; /* image buffer size */ JOCTET buffer[OUTPUT_BUF_SIZE]; /* image buffer */
} mem_destination_mgr; } mem_destination_mgr;
typedef mem_destination_mgr * mem_dest_ptr; typedef mem_destination_mgr * mem_dest_ptr;
void init_destination (j_compress_ptr cinfo)
// init
static void jpeg_init_destination(j_compress_ptr cinfo)
{ {
mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
/* image buffer must be allocated before mem_dest routines are called. */
if(dest->buffer == NULL) {
//fprintf(stderr, "jmem_dest: init_destination: buffer not allocated\n");
}
dest->pub.next_output_byte = dest->buffer; dest->pub.next_output_byte = dest->buffer;
dest->pub.free_in_buffer = dest->buffer_size; dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
} }
boolean empty_output_buffer (j_compress_ptr cinfo) // flush to disk and reset buffer
static boolean jpeg_empty_output_buffer(j_compress_ptr cinfo)
{ {
/*
mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
*/
// empty_output_buffer: buffer should not ever be full\n"); // for now just exit upon file error
return FALSE; if (dest->file->write(dest->buffer, OUTPUT_BUF_SIZE) != OUTPUT_BUF_SIZE)
ERREXIT (cinfo, JERR_FILE_WRITE);
dest->pub.next_output_byte = dest->buffer;
dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
return TRUE;
} }
void term_destination (j_compress_ptr cinfo) static void jpeg_term_destination(j_compress_ptr cinfo)
{ {
mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
size_t datacount = dest->buffer_size - dest->pub.free_in_buffer; const s32 datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
// for now just exit upon file error
if (dest->file->write(dest->buffer, datacount) != datacount)
ERREXIT (cinfo, JERR_FILE_WRITE);
} }
void jpeg_memory_dest (j_compress_ptr cinfo, u8 *jfif_buffer,
s32 buf_size) // set up buffer data
static void jpeg_file_dest(j_compress_ptr cinfo, io::IWriteFile* file)
{ {
mem_dest_ptr dest; if (cinfo->dest == NULL)
{ /* first time for this JPEG object? */
if(jfif_buffer == NULL) { cinfo->dest = (struct jpeg_destination_mgr *)
//fprintf(stderr, "jpeg_memory_dest: memory buffer needs to be allocated\n"); (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo,
//ERREXIT(cinfo, JERR_BUFFER_SIZE); JPOOL_PERMANENT,
return; sizeof(mem_destination_mgr));
} }
if (cinfo->dest == NULL) { /* first time for this JPEG object? */ mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; /* for casting */
cinfo->dest = (struct jpeg_destination_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, /* Initialize method pointers */
(size_t) sizeof(mem_destination_mgr)); dest->pub.init_destination = jpeg_init_destination;
} dest->pub.empty_output_buffer = jpeg_empty_output_buffer;
dest->pub.term_destination = jpeg_term_destination;
dest = (mem_dest_ptr) cinfo->dest; /* for casting */
/* Initialize private member */
/* Initialize method pointers */ dest->file = file;
dest->pub.init_destination = init_destination;
dest->pub.empty_output_buffer = empty_output_buffer;
dest->pub.term_destination = term_destination;
/* Initialize private member */
dest->buffer = (JOCTET*)jfif_buffer;
dest->buffer_size = buf_size;
} }
/* write_JPEG_memory: store JPEG compressed image into memory. /* write_JPEG_memory: store JPEG compressed image into memory.
*/ */
void write_JPEG_memory (void *img_buf, s32 width, s32 height, u32 bpp, u32 pitch, static bool writeJPEGFile(io::IWriteFile* file, IImage* image, u32 quality)
u8 *jpeg_buffer, u32 jpeg_buffer_size,
s32 quality, u32 *jpeg_comp_size)
{ {
struct jpeg_compress_struct cinfo; void (*format)(const void*, s32, void*) = 0;
struct jpeg_error_mgr jerr; switch( image->getColorFormat () )
{
case ECF_R8G8B8:
format = CColorConverter::convert_R8G8B8toR8G8B8;
break;
case ECF_A8R8G8B8:
format = CColorConverter::convert_A8R8G8B8toR8G8B8;
break;
case ECF_A1R5G5B5:
format = CColorConverter::convert_A1R5G5B5toB8G8R8;
break;
case ECF_R5G6B5:
format = CColorConverter::convert_R5G6B5toR8G8B8;
break;
}
/* More stuff */ // couldn't find a color converter
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ if ( 0 == format )
return false;
const core::dimension2di dim = image->getDimension();
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr); cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo); jpeg_create_compress(&cinfo);
jpeg_memory_dest(&cinfo, jpeg_buffer, jpeg_buffer_size); jpeg_file_dest(&cinfo, file);
cinfo.image_width = width; cinfo.image_width = dim.Width;
cinfo.image_height = height; cinfo.image_height = dim.Height;
cinfo.input_components = bpp; cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB; cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cinfo); jpeg_set_defaults(&cinfo);
if ( 0 == quality )
quality = 75;
jpeg_set_quality(&cinfo, quality, TRUE); jpeg_set_quality(&cinfo, quality, TRUE);
jpeg_start_compress(&cinfo, TRUE); jpeg_start_compress(&cinfo, TRUE);
while (cinfo.next_scanline < cinfo.image_height) u8 * dest = new u8[dim.Width*3];
if (dest)
{ {
row_pointer[0] = (u8*) img_buf + (cinfo.next_scanline * pitch ); const u32 pitch = image->getPitch();
jpeg_write_scanlines(&cinfo, row_pointer, 1); JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
} row_pointer[0] = dest;
/* Step 6: Finish compression */ u8* src = (u8*)image->lock();
jpeg_finish_compress(&cinfo);
{ while (cinfo.next_scanline < cinfo.image_height)
mem_dest_ptr dest = (mem_dest_ptr) cinfo.dest; {
*jpeg_comp_size = dest->buffer_size - dest->pub.free_in_buffer; // convert next line
format( src, dim.Width, dest );
src += pitch;
jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
image->unlock();
delete [] dest;
/* Step 6: Finish compression */
jpeg_finish_compress(&cinfo);
} }
/* Step 7: Destroy */
jpeg_destroy_compress(&cinfo); jpeg_destroy_compress(&cinfo);
return (dest != 0);
} }
} // namespace video } // namespace video
} // namespace irr } // namespace irr
...@@ -169,63 +205,17 @@ CImageWriterJPG::CImageWriterJPG() ...@@ -169,63 +205,17 @@ CImageWriterJPG::CImageWriterJPG()
bool CImageWriterJPG::isAWriteableFileExtension(const c8* fileName) const bool CImageWriterJPG::isAWriteableFileExtension(const c8* fileName) const
{ {
return strstr(fileName, ".jpg") != 0 || strstr(fileName, ".jpeg") != 0; const char* dot = strrchr (fileName, '.');
return dot && (!strcmp (dot, ".jpg") || !strcmp (dot, ".jpeg"));
} }
bool CImageWriterJPG::writeImage(io::IWriteFile *file, IImage *input,u32 quality) const bool CImageWriterJPG::writeImage(io::IWriteFile *file, IImage *image, u32 quality) const
{ {
#ifndef _IRR_COMPILE_WITH_LIBJPEG_ #ifndef _IRR_COMPILE_WITH_LIBJPEG_
return false; return false;
#else #else
return writeJPEGFile(file, image, quality);
core::dimension2di dim = input->getDimension();
IImage * image = new CImage(ECF_R8G8B8, dim );
void (*format)(const void*, s32, void*) = 0;
switch( input->getColorFormat () )
{
case ECF_R8G8B8: format = CColorConverter::convert_R8G8B8toR8G8B8; break;
case ECF_A8R8G8B8: format = CColorConverter::convert_A8R8G8B8toR8G8B8; break;
case ECF_A1R5G5B5: format = CColorConverter::convert_A1R5G5B5toB8G8R8; break;
case ECF_R5G6B5: format = CColorConverter::convert_R5G6B5toR8G8B8; break;
}
// couldn't find a color converter
if ( 0 == format )
return false;
s32 y;
void *src = input->lock();
void *dst = image->lock();
for ( y = 0; y!= dim.Height; ++y )
{
format( src, dim.Width, dst );
src = (void*) ( (u8*) src + input->getPitch () );
dst = (void*) ( (u8*) dst + image->getPitch () );
}
input->unlock ();
image->unlock ();
// temp buffer
u32 destSize = image->getImageDataSizeInBytes ();
u8 * dest = new u8 [ destSize ];
if ( 0 == quality )
quality = 75;
write_JPEG_memory ( image->lock (), dim.Width, dim.Height,
image->getBytesPerPixel(), image->getPitch(),
dest, destSize,
quality,
&destSize);
file->write ( dest, destSize );
image->drop ();
delete [] dest;
return true;
#endif #endif
} }
......
...@@ -78,7 +78,7 @@ bool CImageWriterPNG::writeImage(io::IWriteFile* file, IImage* image,u32 param) ...@@ -78,7 +78,7 @@ bool CImageWriterPNG::writeImage(io::IWriteFile* file, IImage* image,u32 param)
NULL, (png_error_ptr)png_cpexcept_error, NULL); NULL, (png_error_ptr)png_cpexcept_error, NULL);
if (!png_ptr) if (!png_ptr)
{ {
os::Printer::log("LOAD PNG: Internal PNG create write struct failure\n", file->getFileName(), ELL_ERROR); os::Printer::log("PNGWriter: Internal PNG create write struct failure\n", file->getFileName(), ELL_ERROR);
return false; return false;
} }
...@@ -86,7 +86,7 @@ bool CImageWriterPNG::writeImage(io::IWriteFile* file, IImage* image,u32 param) ...@@ -86,7 +86,7 @@ bool CImageWriterPNG::writeImage(io::IWriteFile* file, IImage* image,u32 param)
png_infop info_ptr = png_create_info_struct(png_ptr); png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) if (!info_ptr)
{ {
os::Printer::log("LOAD PNG: Internal PNG create info struct failure\n", file->getFileName(), ELL_ERROR); os::Printer::log("PNGWriter: Internal PNG create info struct failure\n", file->getFileName(), ELL_ERROR);
png_destroy_write_struct(&png_ptr, NULL); png_destroy_write_struct(&png_ptr, NULL);
return false; return false;
} }
...@@ -132,7 +132,7 @@ bool CImageWriterPNG::writeImage(io::IWriteFile* file, IImage* image,u32 param) ...@@ -132,7 +132,7 @@ bool CImageWriterPNG::writeImage(io::IWriteFile* file, IImage* image,u32 param)
u8* tmpImage = new u8[image->getDimension().Height*lineWidth]; u8* tmpImage = new u8[image->getDimension().Height*lineWidth];
if (!tmpImage) if (!tmpImage)
{ {
os::Printer::log("LOAD PNG: Internal PNG create image failure\n", file->getFileName(), ELL_ERROR); os::Printer::log("PNGWriter: Internal PNG create image failure\n", file->getFileName(), ELL_ERROR);
png_destroy_write_struct(&png_ptr, &info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr);
return false; return false;
} }
...@@ -161,7 +161,7 @@ bool CImageWriterPNG::writeImage(io::IWriteFile* file, IImage* image,u32 param) ...@@ -161,7 +161,7 @@ bool CImageWriterPNG::writeImage(io::IWriteFile* file, IImage* image,u32 param)
u8** RowPointers = new png_bytep[image->getDimension().Height]; u8** RowPointers = new png_bytep[image->getDimension().Height];
if (!RowPointers) if (!RowPointers)
{ {
os::Printer::log("LOAD PNG: Internal PNG create row pointers failure\n", file->getFileName(), ELL_ERROR); os::Printer::log("PNGWriter: Internal PNG create row pointers failure\n", file->getFileName(), ELL_ERROR);
png_destroy_write_struct(&png_ptr, &info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr);
delete [] tmpImage; delete [] tmpImage;
return false; return false;
......
...@@ -2272,7 +2272,7 @@ void COpenGLDriver::setFog(SColor c, bool linearFog, f32 start, ...@@ -2272,7 +2272,7 @@ void COpenGLDriver::setFog(SColor c, bool linearFog, f32 start,
{ {
CNullDriver::setFog(c, linearFog, start, end, density, pixelFog, rangeFog); CNullDriver::setFog(c, linearFog, start, end, density, pixelFog, rangeFog);
glFogf(GL_FOG_MODE, linearFog ? GL_LINEAR : GL_EXP); glFogf(GL_FOG_MODE, GLfloat(linearFog ? GL_LINEAR : GL_EXP));
#ifdef GL_EXT_fog_coord #ifdef GL_EXT_fog_coord
if (FeatureAvailable[IRR_EXT_fog_coord]) if (FeatureAvailable[IRR_EXT_fog_coord])
glFogi(GL_FOG_COORDINATE_SOURCE, GL_FRAGMENT_DEPTH); glFogi(GL_FOG_COORDINATE_SOURCE, GL_FRAGMENT_DEPTH);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment