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

📄 cn3d_glcanvas.cpp

📁 ncbi源码
💻 CPP
字号:
/* * =========================================================================== * PRODUCTION $Log: cn3d_glcanvas.cpp,v $ * PRODUCTION Revision 1000.2  2004/06/01 18:28:15  gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.5 * PRODUCTION * =========================================================================== *//*  $Id: cn3d_glcanvas.cpp,v 1000.2 2004/06/01 18:28:15 gouriano Exp $* ===========================================================================**                            PUBLIC DOMAIN NOTICE*               National Center for Biotechnology Information**  This software/database is a "United States Government Work" under the*  terms of the United States Copyright Act.  It was written as part of*  the author's official duties as a United States Government employee and*  thus cannot be copyrighted.  This software/database is freely available*  to the public for use. The National Library of Medicine and the U.S.*  Government have not placed any restriction on its use or reproduction.**  Although all reasonable efforts have been taken to ensure the accuracy*  and reliability of the software and data, the NLM and the U.S.*  Government do not and cannot warrant the performance or results that*  may be obtained by using this software or data. The NLM and the U.S.*  Government disclaim all warranties, express or implied, including*  warranties of performance, merchantability or fitness for any particular*  purpose.**  Please cite the author in any work or product based on this material.** ===========================================================================** Authors:  Paul Thiessen** File Description:*      OpenGL canvas object** ===========================================================================*/#ifdef _MSC_VER#pragma warning(disable:4018)   // disable signed/unsigned mismatch warning in MSVC#endif#include <ncbi_pch.hpp>#include <corelib/ncbistd.hpp>#include <memory>#include <wx/fontutil.h>#include <wx/image.h>#include "cn3d_glcanvas.hpp"#include "opengl_renderer.hpp"#include "cn3d_tools.hpp"#include "structure_set.hpp"USING_NCBI_SCOPE;USING_SCOPE(objects);BEGIN_SCOPE(Cn3D)BEGIN_EVENT_TABLE(Cn3DGLCanvas, wxGLCanvas)    EVT_SIZE                (Cn3DGLCanvas::OnSize)    EVT_PAINT               (Cn3DGLCanvas::OnPaint)    EVT_MOUSE_EVENTS        (Cn3DGLCanvas::OnMouseEvent)    EVT_ERASE_BACKGROUND    (Cn3DGLCanvas::OnEraseBackground)END_EVENT_TABLE()Cn3DGLCanvas::Cn3DGLCanvas(wxWindow *parent, int *attribList) :    wxGLCanvas(parent, -1, wxPoint(0, 0), wxDefaultSize, wxSUNKEN_BORDER, "Cn3DGLCanvas", attribList),    structureSet(NULL), suspended(false){    renderer = new OpenGLRenderer(this);}Cn3DGLCanvas::~Cn3DGLCanvas(void){    if (structureSet) delete structureSet;    delete renderer;}void Cn3DGLCanvas::SuspendRendering(bool suspend){    suspended = suspend;    if (!suspend) {        wxSizeEvent resize(GetSize());        OnSize(resize);    }}void Cn3DGLCanvas::SetGLFontFromRegistry(double fontScale){    // get font info from registry, and create wxFont    string nativeFont;    if (!RegistryGetString(REG_OPENGL_FONT_SECTION, REG_FONT_NATIVE_FONT_INFO, &nativeFont))    {        ERRORMSG("Cn3DGLCanvas::SetGLFontFromRegistry() - error getting font info from registry");        return;    }    // create new font - assignment uses object reference to copy    wxNativeFontInfo fontInfo;    if (!fontInfo.FromString(nativeFont.c_str())) {        ERRORMSG("Cn3DGLCanvas::SetGLFontFromRegistry() - can't set wxNativeFontInfo fron native font string");        return;    }#if wxCHECK_VERSION(2,3,4)    if (fontScale != 1.0 && fontScale > 0.0)        fontInfo.SetPointSize(fontScale * fontInfo.GetPointSize());#endif    auto_ptr<wxFont> newFont(wxFont::New(fontInfo));    if (!newFont.get() || !newFont->Ok()) {        ERRORMSG("Cn3DGLCanvas::SetGLFontFromRegistry() - can't get wxFont from wxNativeFontInfo");        return;    }    font = *newFont;    // copy font    // set up font display lists in dc and renderer    if (!memoryDC.Ok()) {        wxBitmap tinyBitmap(1, 1, -1);        memoryBitmap = tinyBitmap; // copies by reference        memoryDC.SelectObject(memoryBitmap);    }    memoryDC.SetFont(font);    renderer->SetGLFont(0, 256, renderer->FONT_BASE);}#define MYMAX(a, b) (((a) >= (b)) ? (a) : (b))bool Cn3DGLCanvas::MeasureText(const string& text, int *width, int *height, int *centerX, int *centerY){    wxCoord w, h;    memoryDC.GetTextExtent(text.c_str(), &w, &h);    *width = (int) w;    *height = (int) h;    // GetTextExtent measures text+background when a character is drawn, but for OpenGL, we need    // to measure actual character pixels more precisely: render characters into memory bitmap,    // then find the minimal rect that contains actual character pixels, not text background    if (memoryBitmap.GetWidth() < w || memoryBitmap.GetHeight() < h) {        wxBitmap biggerBitmap(MYMAX(memoryBitmap.GetWidth(), w), MYMAX(memoryBitmap.GetHeight(), h), -1);        memoryBitmap = biggerBitmap; // copies by reference        memoryDC.SelectObject(memoryBitmap);    }    memoryDC.SetBackground(*wxBLUE_BRUSH);    memoryDC.SetBackgroundMode(wxSOLID);    memoryDC.SetTextBackground(*wxGREEN);    memoryDC.SetTextForeground(*wxRED);    memoryDC.BeginDrawing();    memoryDC.Clear();    memoryDC.DrawText(text.c_str(), 0, 0);    memoryDC.EndDrawing();    // then convert bitmap to image so that we can read individual pixels (ugh...)    wxImage image(memoryBitmap.ConvertToImage());//    wxInitAllImageHandlers();//    image.SaveFile("text.png", wxBITMAP_TYPE_PNG); // for testing    // now find extent of actual (red) text pixels; wx coords put (0,0) at upper left    int x, y, top = image.GetHeight(), left = image.GetWidth(), bottom = -1, right = -1;    for (x=0; x<image.GetWidth(); ++x) {        for (y=0; y<image.GetHeight(); ++y) {            if (image.GetRed(x, y) >= 128) { // character pixel here                if (y < top) top = y;                if (x < left) left = x;                if (y > bottom) bottom = y;                if (x > right) right = x;            }        }    }    if (bottom < 0 || right < 0) {        WARNINGMSG("Cn3DGLCanvas::MeasureText() - no character pixels found!");        *centerX = *centerY = 0;        return false;    }//    TESTMSG("top: " << top << ", left: " << left << ", bottom: " << bottom << ", right: " << right);    // set center{X,Y} to center of drawn glyph relative to bottom left    *centerX = (int) (((double) (right - left)) / 2 + 0.5);    *centerY = (int) (((double) (bottom - top)) / 2 + 0.5);    return true;}void Cn3DGLCanvas::OnPaint(wxPaintEvent& event){    // This is a dummy, to avoid an endless succession of paint messages.    // OnPaint handlers must always create a wxPaintDC.    wxPaintDC dc(this);    if (!GetContext() || !renderer || suspended) return;    SetCurrent();    renderer->Display();    SwapBuffers();}void Cn3DGLCanvas::OnSize(wxSizeEvent& event){    if (suspended || !GetContext()) return;    SetCurrent();    // this is necessary to update the context on some platforms    wxGLCanvas::OnSize(event);    // set GL viewport (not called by wxGLCanvas::OnSize on all platforms...)    int w, h;    GetClientSize(&w, &h);    glViewport(0, 0, (GLint) w, (GLint) h);    renderer->NewView();}void Cn3DGLCanvas::OnMouseEvent(wxMouseEvent& event){    static bool dragging = false;    static long last_x, last_y;    if (!GetContext() || !renderer || suspended) return;    SetCurrent();// in wxGTK >= 2.3.2, this causes a system crash on some Solaris machines...#if !defined(__WXGTK__)    // keep mouse focus while holding down button    if (event.LeftDown()) CaptureMouse();    if (event.LeftUp()) ReleaseMouse();#endif    if (event.LeftIsDown()) {        if (!dragging) {            dragging = true;        } else {            OpenGLRenderer::eViewAdjust action;            if (event.ShiftDown())                action = OpenGLRenderer::eXYTranslateHV;    // shift-drag = translate#ifdef __WXMAC__            else if (event.MetaDown())      // control key + mouse doesn't work on Mac?#else            else if (event.ControlDown())#endif                action = OpenGLRenderer::eZoomH;            // ctrl-drag = zoom            else                action = OpenGLRenderer::eXYRotateHV;       // normal rotate            renderer->ChangeView(action, event.GetX() - last_x, event.GetY() - last_y);            Refresh(false);        }        last_x = event.GetX();        last_y = event.GetY();    } else {        dragging = false;    }    if (event.LeftDClick()) {   // double-click = select, +ctrl = set center        unsigned int name;        if (structureSet && renderer->GetSelected(event.GetX(), event.GetY(), &name))            structureSet->SelectedAtom(name,#ifdef __WXMAC__                event.MetaDown()      // control key + mouse doesn't work on Mac?#else                event.ControlDown()#endif            );    }}void Cn3DGLCanvas::OnEraseBackground(wxEraseEvent& event){    // Do nothing, to avoid flashing.}END_SCOPE(Cn3D)/** ---------------------------------------------------------------------------* $Log: cn3d_glcanvas.cpp,v $* Revision 1000.2  2004/06/01 18:28:15  gouriano* PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.5** Revision 1.5  2004/05/21 21:41:39  gorelenk* Added PCH ncbi_pch.hpp** Revision 1.4  2004/03/15 18:23:01  thiessen* prefer prefix vs. postfix ++/-- operators** Revision 1.3  2004/02/19 17:04:50  thiessen* remove cn3d/ from include paths; add pragma to disable annoying msvc warning** Revision 1.2  2003/03/14 19:22:59  thiessen* add CommandProcessor to handle file-message commands; fixes for GCC 2.9** Revision 1.1  2003/03/13 14:26:18  thiessen* add file_messaging module; split cn3d_main_wxwin into cn3d_app, cn3d_glcanvas, structure_window, cn3d_tools**/

⌨️ 快捷键说明

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