diff --git a/source/g3d_viewer/main.cpp b/source/g3d_viewer/main.cpp index 6feae457..37887c32 100644 --- a/source/g3d_viewer/main.cpp +++ b/source/g3d_viewer/main.cpp @@ -66,7 +66,7 @@ MainWindow::MainWindow(const string &modelPath) speed= 0.025f; - int args[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER }; // to prevent flicker + int args[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_MIN_ALPHA, 8 }; // to prevent flicker glCanvas = new GlCanvas(this, args); //getGlPlatformExtensions(); @@ -82,6 +82,7 @@ MainWindow::MainWindow(const string &modelPath) menuFile->Append(miFileLoadProjectileParticleXML, wxT("Load P&rojectile Particle XML"), wxT("Press ctrl before menu for keeping current projectile particles")); menuFile->Append(miFileLoadSplashParticleXML, wxT("Load &Splash Particle XML"), wxT("Press ctrl before menu for keeping current splash particles")); menuFile->Append(miFileClearAll, wxT("&Clear All")); + menuFile->AppendCheckItem(miFileToggleScreenshotTransparent, wxT("&Transparent Screenshots")); menuFile->Append(miFileSaveScreenshot, wxT("Sa&ve a Screenshot")); menuFile->AppendSeparator(); menuFile->Append(wxID_EXIT); @@ -104,7 +105,7 @@ MainWindow::MainWindow(const string &modelPath) //custom color menuCustomColor= new wxMenu(); - menuCustomColor->AppendCheckItem(miChangeBackgroundColor, wxT("Change Background Color")); + menuCustomColor->Append(miChangeBackgroundColor, wxT("Change Background Color")); menuCustomColor->AppendCheckItem(miColorRed, wxT("&Red\t0")); menuCustomColor->AppendCheckItem(miColorBlue, wxT("&Blue\t1")); menuCustomColor->AppendCheckItem(miColorGreen, wxT("&Green\t2")); @@ -277,36 +278,6 @@ void MainWindow::onMouseMove(wxMouseEvent &event){ } } -void MainWindow::OnChangeColor(wxCommandEvent &event) { - try { - //wxColour color = colorPicker->GetColour(); - wxColourData data; - data.SetChooseFull(true); - for (int i = 0; i < 16; i++) - { - wxColour colour(i*16, i*16, i*16); - data.SetCustomColour(i, colour); - } - - wxColourDialog dialog(this, &data); - if (dialog.ShowModal() == wxID_OK) - { - wxColourData retData = dialog.GetColourData(); - wxColour col = retData.GetColour(); - - renderer->setBackgroundColor(col.Red()/255.0f, col.Green()/255.0f, col.Blue()/255.0f, col.Alpha()/255.0f); - //wxBrush brush(col, wxSOLID); - //myWindow->SetBackground(brush); - //myWindow->Clear(); - //myWindow->Refresh(); - } - } - catch(std::runtime_error e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} - void MainWindow::onMenuFileLoad(wxCommandEvent &event){ try { string fileName; @@ -398,6 +369,45 @@ void MainWindow::onMenuFileLoadSplashParticleXML(wxCommandEvent &event){ } // is it possible to join loadParticle(), loadProjectileParticle() and loadSplashParticle() to one method? +void MainWindow::OnChangeColor(wxCommandEvent &event) { + try { + //wxColour color = colorPicker->GetColour(); + wxColourData data; + data.SetChooseFull(true); + for (int i = 0; i < 16; i++) + { + wxColour colour(i*16, i*16, i*16); + data.SetCustomColour(i, colour); + } + + wxColourDialog dialog(this, &data); + if (dialog.ShowModal() == wxID_OK) + { + wxColourData retData = dialog.GetColourData(); + wxColour col = retData.GetColour(); + + //renderer->setBackgroundColor(col.Red()/255.0f, col.Green()/255.0f, col.Blue()/255.0f, col.Alpha()/255.0f); + renderer->setBackgroundColor(col.Red()/255.0f, col.Green()/255.0f, col.Blue()/255.0f); + //renderer->setBackgroundColor(0.0f, 0.0f, 0.0f, 0.0f); + } + } + catch(std::runtime_error e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } +} + +void MainWindow::onMenumFileToggleScreenshotTransparent(wxCommandEvent &event) { + try { + float alpha = (event.IsChecked() == true ? 0.0f : 1.0f); + renderer->setAlphaColor(alpha); + } + catch(std::runtime_error e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } +} + void MainWindow::onMenuFileSaveScreenshot(wxCommandEvent &event) { try { string path = "screens/"; @@ -1129,6 +1139,7 @@ BEGIN_EVENT_TABLE(MainWindow, wxFrame) EVT_MENU(miFileLoadProjectileParticleXML, MainWindow::onMenuFileLoadProjectileParticleXML) EVT_MENU(miFileLoadSplashParticleXML, MainWindow::onMenuFileLoadSplashParticleXML) EVT_MENU(miFileClearAll, MainWindow::onMenuFileClearAll) + EVT_MENU(miFileToggleScreenshotTransparent, MainWindow::onMenumFileToggleScreenshotTransparent) EVT_MENU(miFileSaveScreenshot, MainWindow::onMenuFileSaveScreenshot) EVT_MENU(wxID_EXIT, MainWindow::onMenuFileExit) @@ -1175,6 +1186,7 @@ GlCanvas::GlCanvas(MainWindow * mainWindow): GlCanvas::GlCanvas(MainWindow * mainWindow, int *args) : wxGLCanvas(mainWindow, -1, wxDefaultPosition, wxDefaultSize, 0, wxT("GLCanvas"), args) { this->mainWindow = mainWindow; + // } // for the mousewheel diff --git a/source/g3d_viewer/main.h b/source/g3d_viewer/main.h index fc9d7574..33f00ee6 100644 --- a/source/g3d_viewer/main.h +++ b/source/g3d_viewer/main.h @@ -38,6 +38,7 @@ public: miFileLoadProjectileParticleXML, miFileLoadSplashParticleXML, miFileClearAll, + miFileToggleScreenshotTransparent, miFileSaveScreenshot, miModeWireframe, miModeNormals, @@ -114,6 +115,7 @@ public: void onMenuFileLoadProjectileParticleXML(wxCommandEvent &event); void onMenuFileLoadSplashParticleXML(wxCommandEvent &event); void onMenuFileClearAll(wxCommandEvent &event); + void onMenumFileToggleScreenshotTransparent(wxCommandEvent &event); void onMenuFileSaveScreenshot(wxCommandEvent &event); void onMenuFileExit(wxCommandEvent &event); void onMenuModeNormals(wxCommandEvent &event); diff --git a/source/g3d_viewer/renderer.cpp b/source/g3d_viewer/renderer.cpp index 4f6eaa02..b8a5e91e 100644 --- a/source/g3d_viewer/renderer.cpp +++ b/source/g3d_viewer/renderer.cpp @@ -2,6 +2,8 @@ #include "graphics_factory_gl.h" #include "graphics_interface.h" +#include +#include using namespace Shared::Graphics; using namespace Shared::Graphics::Gl; @@ -151,17 +153,6 @@ Model * Renderer::getNewModel() { return newModel; } -void Renderer::setBackgroundColor(float red, float green, float blue, float alpha) { - this->red = red; - this->green = green; - this->blue = blue; - this->alpha= alpha; - glClearColor(red, green, blue, alpha); //backgroundcolor constant 0.3 - //glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); - //glFlush(); - //SwapBuffers(); -} - void Renderer::init() { assertGl(); @@ -219,6 +210,13 @@ void Renderer::init() { customTextureMagenta->getPixmap()->setPixel(0, 0, Vec3f(1.f, 0.5f, 1.f)); glClearColor(red, green, blue, alpha); //backgroundcolor constant 0.3 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* once the GL context is valid : */ + GLint alpha_bits; + glGetIntegerv(GL_ALPHA_BITS, &alpha_bits); + //printf("#1 The framebuffer uses %d bit(s) per the alpha component\n", alpha_bits); + glEnable(GL_TEXTURE_2D); glFrontFace(GL_CW); glEnable(GL_CULL_FACE); @@ -248,7 +246,14 @@ void Renderer::reset(int w, int h, PlayerColor playerColor) { width=w; height=h; - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClearColor(red, green, blue, alpha); //backgroundcolor constant 0.3 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* once the GL context is valid : */ + GLint alpha_bits; + glGetIntegerv(GL_ALPHA_BITS, &alpha_bits); + //printf("#2 The framebuffer uses %d bit(s) per the alpha component\n", alpha_bits); + glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); @@ -434,14 +439,79 @@ void Renderer::end() { modelManager->end(); } +void Renderer::setBackgroundColor(float red, float green, float blue) { + this->red = red; + this->green = green; + this->blue = blue; + + glClearColor(red, green, blue, alpha); //backgroundcolor constant 0.3 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* once the GL context is valid : */ + GLint alpha_bits; + glGetIntegerv(GL_ALPHA_BITS, &alpha_bits); + //printf("#3 The framebuffer uses %d bit(s) per the alpha component\n", alpha_bits); +} + +void Renderer::setAlphaColor(float alpha) { + this->alpha= alpha; + + glClearColor(red, green, blue, alpha); //backgroundcolor constant 0.3 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* once the GL context is valid : */ + GLint alpha_bits; + glGetIntegerv(GL_ALPHA_BITS, &alpha_bits); + //printf("#3.1 The framebuffer uses %d bit(s) per the alpha component\n", alpha_bits); +} + void Renderer::saveScreen(const string &path) { - //const Metrics &sm= Metrics::getInstance(); + +/* + int x = 0; + int y = 0; + int w = width; + int h = height; + + // get data + std::auto_ptr imdata(new png_byte[w*h*4]); + std::auto_ptr imrow(new png_byte*[h]); + for(int i=0; igetW(), pixmapScreenShot->getH(), - GL_RGB, GL_UNSIGNED_BYTE, pixmapScreenShot->getPixels()); + glReadPixels(0, 0, pixmapScreenShot->getW(), pixmapScreenShot->getH(),GL_RGBA, GL_UNSIGNED_BYTE, pixmapScreenShot->getPixels()); pixmapScreenShot->save(path); delete pixmapScreenShot; diff --git a/source/g3d_viewer/renderer.h b/source/g3d_viewer/renderer.h index 1dc94dea..eeddf188 100644 --- a/source/g3d_viewer/renderer.h +++ b/source/g3d_viewer/renderer.h @@ -144,7 +144,8 @@ public: void end(); - void setBackgroundColor(float red, float green, float blue, float alpha); + void setBackgroundColor(float red, float green, float blue); + void setAlphaColor(float alpha); void saveScreen(const string &path); }; diff --git a/source/shared_lib/sources/graphics/pixmap.cpp b/source/shared_lib/sources/graphics/pixmap.cpp index 052685f6..2d26e7aa 100644 --- a/source/shared_lib/sources/graphics/pixmap.cpp +++ b/source/shared_lib/sources/graphics/pixmap.cpp @@ -23,6 +23,7 @@ #include "ImageReaders.h" #include #include +#include #include "leak_dumper.h" @@ -417,6 +418,28 @@ void PixmapIoPng::openWrite(const string &path, int w, int h, int components) { } void PixmapIoPng::write(uint8 *pixels) { + + // initialize stuff + std::auto_ptr imrow(new png_byte*[h]); + for(int i = 0; i < h; ++i) { + imrow.get()[i] = pixels+(h-1-i) * w * components; + } + + png_structp imgp = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0); + png_infop infop = png_create_info_struct(imgp); + png_init_io(imgp, file); + png_set_IHDR(imgp, infop, w, h, + 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + + // write file + png_write_info(imgp, infop); + png_write_image(imgp, imrow.get()); + png_write_end(imgp, NULL); + + + +/* // Allocate write & info structures png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if(!png_ptr) { @@ -435,7 +458,7 @@ void PixmapIoPng::write(uint8 *pixels) { // setjmp() must be called in every function that calls a PNG-writing // libpng function, unless an alternate error handler was installed-- // but compatible error handlers must either use longjmp() themselves - // (as in this program) or exit immediately, so here we go: */ + // (as in this program) or exit immediately, so here we go: if(setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); @@ -470,15 +493,16 @@ void PixmapIoPng::write(uint8 *pixels) { // color_type = PNG_COLOR_TYPE_GRAY; // color_type = PNG_COLOR_TYPE_GRAY_ALPHA; - color_type = PNG_COLOR_TYPE_RGB; - numChannels = 3; + color_type = PNG_COLOR_TYPE_RGBA; + numChannels = 4; // color_type = PNG_COLOR_TYPE_RGB_ALPHA; interlace_type = PNG_INTERLACE_NONE; // interlace_type = PNG_INTERLACE_ADAM7; int bit_depth = 8; - png_set_IHDR(png_ptr, info_ptr, this->w, this->h, bit_depth, + png_set_IHDR(png_ptr, info_ptr, this->w, this->h, + bit_depth, color_type, interlace_type, PNG_COMPRESSION_TYPE_BASE, @@ -488,12 +512,15 @@ void PixmapIoPng::write(uint8 *pixels) { // as to the correct gamma of the image. (we don't have a guess) // // png_set_gAMA(png_ptr, info_ptr, image_gamma); + //png_set_strip_alpha(png_ptr); // write all chunks up to (but not including) first IDAT png_write_info(png_ptr, info_ptr); - // set up the row pointers for the image so we can use png_write_image + //png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL ); + + // set up the row pointers for the image so we can use png_write_image png_bytep* row_pointers = new png_bytep[this->h]; if (row_pointers == 0) { png_destroy_write_struct(&png_ptr, &info_ptr); @@ -513,7 +540,7 @@ void PixmapIoPng::write(uint8 *pixels) { // since that's it, we also close out the end of the PNG file now--if we // had any text or time info to write after the IDATs, second argument - // would be info_ptr, but we optimize slightly by sending NULL pointer: */ + // would be info_ptr, but we optimize slightly by sending NULL pointer: png_write_end(png_ptr, info_ptr); @@ -524,7 +551,7 @@ void PixmapIoPng::write(uint8 *pixels) { png_destroy_write_struct(&png_ptr, &info_ptr); delete [] row_pointers; - //fclose(file); +*/ } // ===================================================== @@ -1068,7 +1095,7 @@ void Pixmap3D::loadSliceBmp(const string &path, int slice){ } void Pixmap3D::loadSliceTga(const string &path, int slice){ - this->path = path; + this->path = path; PixmapIoTga plt; plt.openRead(path);