⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cn3d_png.cpp

📁 ncbi源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        // sets callback that's called by PNG after each written row        png_set_write_status_fn(png_ptr, write_row_callback);        // set various PNG parameters        png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);        png_set_IHDR(png_ptr, info_ptr, outputWidth, outputHeight,            8, PNG_COLOR_TYPE_RGB,            interlaced ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE,            PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);        png_write_info(png_ptr, info_ptr);        // set up camera so that it's the same view as it is in the window        glCanvas->renderer->Init();        glViewport(0, 0, outputWidth, outputHeight);        glCanvas->renderer->NewView();        // Redraw the model into the new off-screen context, then use glReadPixels        // to retrieve pixel data. It's much easier to use glReadPixels rather than        // trying to read directly from the off-screen buffer, since GL can do all        // the potentially tricky work of translating from whatever pixel format        // the buffer uses into "regular" RGB byte triples. If fonts need scaling,        // have to reconstruct lists regardless of whether display lists are shared.        if (!shareDisplayLists || outputHeight != glCanvas->GetClientSize().GetHeight()) {            glCanvas->SetGLFontFromRegistry(((double) outputHeight) / glCanvas->GetClientSize().GetHeight());            glCanvas->renderer->Construct();        }        glPixelStorei(GL_PACK_ALIGNMENT, 1);        // Write image row by row to avoid having to allocate another full image's        // worth of memory. Do multiple passes for interlacing, if necessary. Note        // that PNG's rows are stored top down, while GL's are bottom up.        if (interlaced) {            // need to draw only once            glCanvas->renderer->Display();            int pass, r;            nRows = -outputHeight; // signal to monitor that we're interlacing            if (png_set_interlace_handling(png_ptr) != 7) throw "confused by unkown PNG interlace scheme";            for (pass = 1; pass <= 7; ++pass) {                for (int i = outputHeight - 1; i >= 0; --i) {                    r = outputHeight - i - 1;                    // when interlacing, only certain rows are actually read                    // during certain passes - avoid unncessary reads                    if (                        ((pass == 1 || pass == 2) && (r % 8 == 0)) ||                        ((pass == 3) && ((r - 4) % 8 == 0)) ||                        ((pass == 4) && (r % 4 == 0)) ||                        ((pass == 5) && ((r - 2) % 4 == 0)) ||                        ((pass == 6) && (r % 2 == 0)) ||                        ((pass == 7) && ((r - 1) % 2 == 0))                    )                        glReadPixels(0, i, outputWidth, 1, GL_RGB, GL_UNSIGNED_BYTE, rowStorage);                    // ... but still have to call this for each row in each pass */                    png_write_row(png_ptr, rowStorage);                }            }        }        // not interlaced, but possibly chunked        else {            int bufferRow, bufferRowStart;            nRows = outputHeight;            for (int chunk = nChunks - 1; chunk >= 0; --chunk) {                // set viewport for this chunk and redraw                if (nChunks > 1) {                    TRACEMSG("drawing chunk #" << (chunk + 1));                    glViewport(0, -chunk*bufferHeight, outputWidth, outputHeight);                }                glCanvas->renderer->Display();                // only draw "visible" part of top chunk                if (chunk == nChunks - 1)                    bufferRowStart = outputHeight - 1 - bufferHeight * (nChunks - 1);                else                    bufferRowStart = bufferHeight - 1;                // dump chunk to PNG file                for (bufferRow = bufferRowStart; bufferRow >= 0; --bufferRow) {                    glReadPixels(0, bufferRow, outputWidth, 1, GL_RGB, GL_UNSIGNED_BYTE, rowStorage);                    png_write_row(png_ptr, rowStorage);                }            }        }        // finish up PNG write        png_write_end(png_ptr, info_ptr);        success = true;        // general cleanup        if (out) fclose(out);        if (rowStorage) delete rowStorage;        if (png_ptr) {            if (info_ptr)                png_destroy_write_struct(&png_ptr, &info_ptr);            else                png_destroy_write_struct(&png_ptr, NULL);        }        if (progressMeter) {            progressMeter->Close(true);            progressMeter->Destroy();            progressMeter = NULL;        }    // platform-specific cleanup, restore context#if defined(__WXMSW__)        if (current_hdc && current_hglrc) wglMakeCurrent(current_hdc, current_hglrc);        if (hglrc) wglDeleteContext(hglrc);        if (hbm) DeleteObject(hbm);        if (hdc) DeleteDC(hdc);#elif defined(__WXGTK__)        gotAnXError = false;        if (glCtx) {            glXMakeCurrent(display, currentXdrw, currentCtx);            glXDestroyContext(display, glCtx);        }        if (glxPixmap) glXDestroyGLXPixmap(display, glxPixmap);        if (xPixmap) XFreePixmap(display, xPixmap);        if (localVI && visinfo) XFree(visinfo);        if (gotAnXError) WARNINGMSG("Got an X error destroying GLXPixmap context");        XSetErrorHandler(currentXErrHandler);#elif defined(__WXMAC__)        aglSetCurrentContext(currentCtx);        if (ctx) aglDestroyContext(ctx);        if (fmt) aglDestroyPixelFormat(fmt);        if (base) delete[] base;        glCanvas->renderer->RecreateQuadric();	// Macs have context-sensitive quadrics...#endif    } catch (const char *err) {        ERRORMSG("Error creating PNG: " << err);    } catch (exception& e) {        ERRORMSG("Uncaught exception while creating PNG: " << e.what());    }    // reset font after "regular" context restore    glCanvas->SuspendRendering(false);    if (outputHeight != glCanvas->GetClientSize().GetHeight()) {        glCanvas->SetCurrent();        glCanvas->SetGLFontFromRegistry(1.0);        if (shareDisplayLists)            GlobalMessenger()->PostRedrawAllStructures();    }    glCanvas->Refresh(false);    return success;}END_SCOPE(Cn3D)////////////////////////////////////////////////////////////////////////////////////////////////// The following is taken unmodified from wxDesigner's C++ code from png_dialog.wdr////////////////////////////////////////////////////////////////////////////////////////////////wxSizer *SetupPNGOptionsDialog( wxPanel *parent, bool call_fit, bool set_sizer ){    wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );    wxStaticBox *item2 = new wxStaticBox( parent, -1, "Output Settings" );    wxStaticBoxSizer *item1 = new wxStaticBoxSizer( item2, wxVERTICAL );    wxFlexGridSizer *item3 = new wxFlexGridSizer( 1, 0, 0, 0 );    item3->AddGrowableCol( 1 );    wxStaticText *item4 = new wxStaticText( parent, ID_TEXT, "File name:", wxDefaultPosition, wxDefaultSize, 0 );    item3->Add( item4, 0, wxALIGN_CENTRE|wxALL, 5 );    item3->Add( 20, 20, 0, wxALIGN_CENTRE|wxALL, 5 );    wxButton *item5 = new wxButton( parent, ID_B_BROWSE, "Browse", wxDefaultPosition, wxDefaultSize, 0 );    item3->Add( item5, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT|wxTOP, 5 );    item1->Add( item3, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );    wxTextCtrl *item6 = new wxTextCtrl( parent, ID_T_NAME, "", wxDefaultPosition, wxDefaultSize, 0 );    item1->Add( item6, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 );    wxFlexGridSizer *item7 = new wxFlexGridSizer( 2, 0, 0, 0 );    item7->AddGrowableCol( 1 );    item7->AddGrowableRow( 1 );    wxStaticText *item8 = new wxStaticText( parent, ID_TEXT, "Width:", wxDefaultPosition, wxDefaultSize, 0 );    item7->Add( item8, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );    item7->Add( 20, 20, 0, wxALIGN_CENTRE|wxALL, 5 );    wxStaticText *item9 = new wxStaticText( parent, ID_TEXT, "Height:", wxDefaultPosition, wxDefaultSize, 0 );    item7->Add( item9, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );    wxTextCtrl *item10 = new wxTextCtrl( parent, ID_T_WIDTH, "", wxDefaultPosition, wxDefaultSize, 0 );    item7->Add( item10, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT|wxBOTTOM, 5 );    wxStaticText *item11 = new wxStaticText( parent, ID_TEXT, "x", wxDefaultPosition, wxDefaultSize, 0 );    item7->Add( item11, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT|wxBOTTOM, 5 );    wxTextCtrl *item12 = new wxTextCtrl( parent, ID_T_HEIGHT, "", wxDefaultPosition, wxDefaultSize, 0 );    item7->Add( item12, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT|wxBOTTOM, 5 );    item1->Add( item7, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );    wxBoxSizer *item13 = new wxBoxSizer( wxHORIZONTAL );    wxCheckBox *item14 = new wxCheckBox( parent, ID_C_ASPECT, "Maintain original aspect ratio", wxDefaultPosition, wxDefaultSize, 0 );    item14->SetValue( TRUE );    item13->Add( item14, 0, wxALIGN_CENTRE|wxALL, 5 );    item13->Add( 20, 20, 0, wxALIGN_CENTRE|wxALL, 5 );    wxCheckBox *item15 = new wxCheckBox( parent, ID_C_INTERLACE, "Interlaced", wxDefaultPosition, wxDefaultSize, 0 );    item15->SetValue( TRUE );    item13->Add( item15, 0, wxALIGN_CENTRE|wxALL, 5 );    item1->Add( item13, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT|wxTOP, 5 );    item0->Add( item1, 0, wxALIGN_CENTRE|wxALL, 5 );    wxBoxSizer *item16 = new wxBoxSizer( wxHORIZONTAL );    wxButton *item17 = new wxButton( parent, ID_B_OK, "OK", wxDefaultPosition, wxDefaultSize, 0 );    item17->SetDefault();    item16->Add( item17, 0, wxALIGN_CENTRE|wxALL, 5 );    item16->Add( 20, 20, 0, wxALIGN_CENTRE|wxALL, 5 );    wxButton *item18 = new wxButton( parent, ID_B_CANCEL, "Cancel", wxDefaultPosition, wxDefaultSize, 0 );    item16->Add( item18, 0, wxALIGN_CENTRE|wxALL, 5 );    item0->Add( item16, 0, wxALIGN_CENTRE|wxALL, 5 );    if (set_sizer)    {        parent->SetAutoLayout( TRUE );        parent->SetSizer( item0 );        if (call_fit)        {            item0->Fit( parent );            item0->SetSizeHints( parent );        }    }    return item0;}/** ---------------------------------------------------------------------------* $Log: cn3d_png.cpp,v $* Revision 1000.3  2004/06/01 18:28:18  gouriano* PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.21** Revision 1.21  2004/05/21 21:41:39  gorelenk* Added PCH ncbi_pch.hpp** Revision 1.20  2004/03/15 17:30:06  thiessen* prefer prefix vs. postfix ++/-- operators** Revision 1.19  2004/02/19 17:04:50  thiessen* remove cn3d/ from include paths; add pragma to disable annoying msvc warning** Revision 1.18  2003/12/04 15:49:39  thiessen* fix stereo and PNG export problems on Mac** Revision 1.17  2003/11/15 16:08:35  thiessen* add stereo** Revision 1.16  2003/03/13 14:26:18  thiessen* add file_messaging module; split cn3d_main_wxwin into cn3d_app, cn3d_glcanvas, structure_window, cn3d_tools** Revision 1.15  2003/02/03 19:20:03  thiessen* format changes: move CVS Log to bottom of file, remove std:: from .cpp files, and use new diagnostic macros** Revision 1.14  2002/10/21 15:11:29  thiessen* don't share lists in wxGTK build** Revision 1.13  2002/10/18 20:33:54  thiessen* workaround for linux/Mesa bug** Revision 1.12  2002/10/18 15:42:59  thiessen* work around png header issue for linux** Revision 1.11  2002/10/11 17:21:39  thiessen* initial Mac OSX build** Revision 1.10  2002/08/15 22:13:14  thiessen* update for wx2.3.2+ only; add structure pick dialog; fix MultitextDialog bug** Revision 1.9  2002/04/21 12:21:21  thiessen* minor fixes for AIX** Revision 1.8  2001/10/25 17:16:43  thiessen* add PNG output to Mac version** Revision 1.7  2001/10/25 14:19:44  thiessen* move png.h to top** Revision 1.6  2001/10/25 00:06:29  thiessen* fix concurrent rendering problem in wxMSW PNG output** Revision 1.5  2001/10/24 22:02:02  thiessen* fix wxGTK concurrent rendering problem** Revision 1.4  2001/10/24 17:07:30  thiessen* add PNG output for wxGTK** Revision 1.3  2001/10/24 11:25:20  thiessen* fix wxString problem** Revision 1.2  2001/10/23 20:10:23  thiessen* fix scaling of fonts in high-res PNG output** Revision 1.1  2001/10/23 13:53:38  thiessen* add PNG export**/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -