Hi,
On Mon, 2011-12-12 at 16:45 +0800, Gerrit Voß wrote:
> Hi,
>
> On Thu, 2011-12-08 at 10:47 +0100, "Christoph Fünfzig" wrote:
> > Hi all,
> >
> > >
> > Attached is an example program using two windows:
> > a GLUT window and a WIN32 window (created with WIN32 API directly; sorry
> > Windows only ;) ).
> > The only place where aspects are assigned is the thread start
> > thread->runFunction(::ThreadProc, // thread function
> > 1, // aspect id
> > NULL); // thread argument
> >
> > I am totally unsure if it is correct like that? I would really appreciate
> > if someone
> > who used it before could have a look ..
>
> I'm looking into it, from a first look (windows version still building),
> I saw a two main things
>
> you do not apply the changes from the app aspect to aspect 1 and your
> window in the second thread still uses the aspect 0 tree.
>
> I'll try to update you example so that the main steps are in there.
ok, attached a basic version that renders with the two windows. The main
change is syncing from aspect 0 to aspect 1 between barriers and the
use of the aspect 1 pointer for the second window.
kind regards
gerrit
#include "OSGGLUT.h"
#include "OSGConfig.h"
#include "OSGSimpleGeometry.h"
#include "OSGGLUTWindow.h"
#include "OSGSimpleSceneManager.h"
#include "OSGSceneFileHandler.h"
#include <OSGImageFileHandler.h>
#include <OSGMatrixUtility.h>
#include <OSGNameAttachment.h>
#include <OSGSceneFileHandler.h>
#include <OSGShaderProgram.h>
#include <OSGShaderProgramChunk.h>
#include <OSGSimpleGeometry.h>
#include <OSGSimpleSceneManager.h>
#include <OSGSkinnedGeometry.h>
#include <OSGSkyBackground.h>
#include <OSGTextureObjChunk.h>
#include <OSGNavigationManager.h>
#include "OSGDrawable.h"
#include "OSGSimpleStatisticsForeground.h"
#include "OSGStatElemTypes.h"
#include "OSGStatCollector.h"
#include "OSGRenderAction.h"
#include "OSGTextureObjChunk.h"
#include "OSGMaterialChunk.h"
#include "OSGSimpleSHLChunk.h"
#include "OSGSolidBackground.h"
#include "OSGPerspectiveCamera.h"
#include "OSGProjectionCameraDecorator.h"
#include "OSGSimpleGeometry.h"
OSG::Real32 skySize = 5.0f;
unsigned win_width = 500;
unsigned win_height = 500;
OSG::SimpleSceneManager* mgr = NULL;
OSG::RenderAction* ract = NULL;
bool show = true;
bool bGLFinish = false;
// WIN32 data for win2
HDC hDC; // Private GDI Device Context
HWND hWnd; // Holds Our Window Handle
HGLRC hRC;
HINSTANCE hInstance; // Holds The Instance Of The Application
// windows
unsigned winId = 0;
OSG::GLUTWindowRecPtr win;
OSG::WIN32WindowUnrecPtr win2;
OSG::Thread *pAppThread = NULL;
OSG::ThreadRefPtr pDrawThread = NULL;
OSG::BarrierRefPtr pSyncBarrier = NULL;
// GLUT redraw the window
void display(void)
{
OSG::commitChanges();
pSyncBarrier->enter(2);
pSyncBarrier->enter(2);
OSG::Thread::getCurrent()->getChangeList()->clear();
//glutSetWindow(winId);
mgr->redraw();
}
// GLUT react to size changes
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
mgr->resize(w,h);
//glutPostRedisplay();
}
// GLUT react to mouse button presses
void mouse(int button, int state, int x, int y)
{
if (state) {
mgr->mouseButtonRelease(button, x, y);
} else {
mgr->mouseButtonPress(button, x, y);
}
glutPostRedisplay();
}
// GLUT react to mouse motions with pressed buttons
void motion(int x, int y)
{
mgr->mouseMove(x, y);
glutPostRedisplay();
}
// GLUT react to keys
void keyboard(unsigned char k, int, int)
{
switch(k) {
case 27:
{
delete mgr;
win = NULL;
OSG::osgExit();
exit(0);
}
// Output help about the controls
// - If you add an option, please add it here too.
case '?':
case '/':
case 'h':
{
std::cerr << "\nControls:"
<< "v: Toggle drawing of volumes.\n"
<< "z: Toggle zwrite on rendering action.\n"
<< "r: switch to render action.\n"
<< "t: switch to traversal action.\n"
<< "n: toggle state sorting on action.\n"
<< "m: set keygen to 0.\n"
<< "s: set keygen for shaders.\n"
<< "g: toggle using gl finish.\n"
<< "x: toggle stat mode.\n"
<< std::endl;
}
break;
case 'v':
{
mgr->getRenderAction()->setVolumeDrawing(
!mgr->getRenderAction()->getVolumeDrawing());
std::cerr << "Volume Drawing: "
<< (mgr->getRenderAction()->getVolumeDrawing() ?
"on":"off")
<< std::endl;
}
break;
case 'm':
ract->setKeyGen(0);
break;
case 's':
{
OSG::UInt32 uiSId =
OSG::SimpleSHLChunk ::getStaticClassId() & 0x000003FF;
OSG::UInt32 uiTId =
OSG::TextureBaseChunk::getStaticClassId() & 0x000003FF;
OSG::UInt32 uiMId =
OSG::MaterialChunk ::getStaticClassId() & 0x000003FF;
OSG::UInt32 uiKeyGen = (uiSId) | (uiTId << 10) | (uiMId << 20);
ract->setKeyGen(uiKeyGen);
}
break;
case 'g':
bGLFinish = !bGLFinish;
ract->setUseGLFinish(bGLFinish);
//act->setUseGLFinish(bGLFinish);
std::cerr << "Set use gl finish to: " << bGLFinish << std::endl;
break;
}
}
// change the geometry created with makePlaneGeo into quad with center origin in plane given by (dirx, diry)
// edge length is 2*size
void changePlaneGeo (OSG::GeometryUnrecPtr geo,
OSG::Real32 size,
OSG::Pnt3f origin,
OSG::Vec3f dirx,
OSG::Vec3f diry)
{
//geo->removeFromProperties (OSG::Geometry::PositionsIndex);
//geo->removeFromProperties (OSG::Geometry::NormalsIndex);
OSG::GeoPnt3fPropertyUnrecPtr pnts = OSG::GeoPnt3fProperty ::create();
OSG::GeoVec3fPropertyUnrecPtr norms = OSG::GeoVec3fProperty ::create();
geo->setPositions(pnts);
geo->setNormals (norms);
OSG::GeoPnt3fProperty::StoredFieldType *p = pnts ->editFieldPtr();
OSG::GeoVec3fProperty::StoredFieldType *n = norms->editFieldPtr();
p->push_back(origin - size*dirx - size*diry);
p->push_back(origin - size*dirx + size*diry);
p->push_back(origin + size*dirx - size*diry);
p->push_back(origin + size*dirx + size*diry);
OSG::Vec3f normal = dirx.cross(diry);
n->push_back(normal);
n->push_back(normal);
n->push_back(normal);
n->push_back(normal);
}
// load sky-box imitation; uses skyFront.jpg/skyBack.jpg/skyLeft.jpg/skyRight.jpg/skyTop.jpg/skyBottom.jpg
OSG::NodeUnrecPtr loadBackground (void)
{
OSG::ImageUnrecPtr imgFront = OSG::ImageFileHandler::the()->read("skyFront.jpg");
OSG::TextureObjChunkUnrecPtr texFront = OSG::TextureObjChunk::create();
texFront->setImage(imgFront);
OSG::ImageUnrecPtr imgBack = OSG::ImageFileHandler::the()->read("skyBack.jpg");
OSG::TextureObjChunkUnrecPtr texBack = OSG::TextureObjChunk::create();
texBack->setImage(imgBack);
OSG::ImageUnrecPtr imgLeft = OSG::ImageFileHandler::the()->read("skyLeft.jpg");
OSG::TextureObjChunkUnrecPtr texLeft = OSG::TextureObjChunk::create();
texLeft->setImage(imgLeft);
OSG::ImageUnrecPtr imgRight = OSG::ImageFileHandler::the()->read("skyRight.jpg");
OSG::TextureObjChunkUnrecPtr texRight = OSG::TextureObjChunk::create();
texRight->setImage(imgRight);
OSG::ImageUnrecPtr imgTop = OSG::ImageFileHandler::the()->read("skyTop.jpg");
OSG::TextureObjChunkUnrecPtr texTop = OSG::TextureObjChunk::create();
texTop->setImage(imgTop);
OSG::ImageUnrecPtr imgBottom = OSG::ImageFileHandler::the()->read("skyBottom.jpg");
OSG::TextureObjChunkUnrecPtr texBottom = OSG::TextureObjChunk::create();
texBottom->setImage(imgBottom);
// create box geometry
//OSG::GroupUnrecPtr sky = OSG::makeCoredNode<OSG::Group>();
OSG::GeometryUnrecPtr left = OSG::makePlaneGeo(2.0f*skySize,
2.0f*skySize,
1, 1);
OSG::GeometryUnrecPtr right = OSG::makePlaneGeo(2.0f*skySize,
2.0f*skySize,
1, 1);
OSG::GeometryUnrecPtr front = OSG::makePlaneGeo(2.0f*skySize,
2.0f*skySize,
1, 1);
OSG::GeometryUnrecPtr back = OSG::makePlaneGeo(2.0f*skySize,
2.0f*skySize,
1, 1);
OSG::GeometryUnrecPtr top = OSG::makePlaneGeo(2.0f*skySize,
2.0f*skySize,
1, 1);
OSG::GeometryUnrecPtr bottom = OSG::makePlaneGeo(2.0f*skySize,
2.0f*skySize,
1, 1);
changePlaneGeo(left, skySize,
OSG::Pnt3f(+skySize, 0.0f, 0.0f),
OSG::Vec3f(0.0f, -1.0f, 0.0f), OSG::Vec3f(0.0f, 0.0f, 1.0f));
changePlaneGeo(right, skySize,
OSG::Pnt3f(-skySize, 0.0f, 0.0f),
OSG::Vec3f(0.0f, 1.0f, 0.0f), OSG::Vec3f(0.0f, 0.0f, 1.0f));
changePlaneGeo(front, skySize,
OSG::Pnt3f(0.0f, +skySize, 0.0f),
OSG::Vec3f(1.0f, 0.0f, 0.0f), OSG::Vec3f(0.0f, 0.0f, 1.0f));
changePlaneGeo(back, skySize,
OSG::Pnt3f(0.0f, -skySize, 0.0f),
OSG::Vec3f(-1.0f, 0.0f, 0.0f), OSG::Vec3f(0.0f, 0.0f, 1.0f));
changePlaneGeo(top, skySize,
OSG::Pnt3f(0.0f, 0.0f, +skySize),
OSG::Vec3f( 1.0f, 0.0f, 0.0f), OSG::Vec3f(0.0f, -1.0f, 0.0f));
changePlaneGeo(bottom, skySize,
OSG::Pnt3f(0.0f, 0.0f, -skySize),
OSG::Vec3f(-1.0f, 0.0f, 0.0f), OSG::Vec3f(0.0f, -1.0f, 0.0f));
OSG::FieldContainerUnrecPtr mat = OSG::getDefaultMaterial()->shallowCopy();
OSG::ChunkMaterial* leftChunk = dynamic_cast<OSG::ChunkMaterial*>(mat.get());
left->setMaterial(leftChunk);
leftChunk->addChunk(texLeft);
mat = OSG::getDefaultMaterial()->shallowCopy();
OSG::ChunkMaterial* rightChunk = dynamic_cast<OSG::ChunkMaterial*>(mat.get());
right->setMaterial(rightChunk);
rightChunk->addChunk(texRight);
mat = OSG::getDefaultMaterial()->shallowCopy();
OSG::ChunkMaterial* frontChunk = dynamic_cast<OSG::ChunkMaterial*>(mat.get());
front->setMaterial(frontChunk);
frontChunk->addChunk(texFront);
mat = OSG::getDefaultMaterial()->shallowCopy();
OSG::ChunkMaterial* backChunk = dynamic_cast<OSG::ChunkMaterial*>(mat.get());
back->setMaterial(backChunk);
backChunk->addChunk(texBack);
mat = OSG::getDefaultMaterial()->shallowCopy();
OSG::ChunkMaterial* topChunk = dynamic_cast<OSG::ChunkMaterial*>(mat.get());
top->setMaterial(topChunk);
topChunk->addChunk(texTop);
mat = OSG::getDefaultMaterial()->shallowCopy();
OSG::ChunkMaterial* bottomChunk = dynamic_cast<OSG::ChunkMaterial*>(mat.get());
bottom->setMaterial(bottomChunk);
bottomChunk->addChunk(texBottom);
OSG::NodeUnrecPtr sky = OSG::makeCoredNode<OSG::Group>();
sky->addChild(makeNodeFor(left));
sky->addChild(makeNodeFor(right));
sky->addChild(makeNodeFor(front));
sky->addChild(makeNodeFor(back));
sky->addChild(makeNodeFor(top));
sky->addChild(makeNodeFor(bottom));
return sky;
}
void makeCurrent (int w)
{
if (w < 0) {
wglMakeCurrent(NULL, NULL);
return;
}
// make window w>0 current
if (!wglMakeCurrent(hDC, hRC)) {
FWARNING(("TiledSupport::makeCurrent: Can't Activate GL Context for window!\n"));
}
//FWARNING(("current DC=%p, current RC=%p\n", wglGetCurrentDC(), wglGetCurrentContext()));
}
void swapBuffers (int w)
{
if (w < 0) {
return;
}
if (!SwapBuffers(hDC)) {
FWARNING(("TiledSupport::swapBuffers: Can't swap buffers for window!\n"));
}
}
void killGLWindow (int w)
{
FWARNING(("TiledSupport::killGLWindow\n"));
if (!wglMakeCurrent(NULL,NULL)) { // Are We Able To Release The DC And RC Contexts?
FWARNING(("TiledSupport::killGLWindow: Release Of DC And RC Failed!\n"));
}
if (hRC) { // Do We Have A Rendering Context?
if (!wglDeleteContext(hRC)) { // Are We Able To Delete The RC?
FWARNING(("TiledSupport::killGLWindow: Release Rendering Context Failed!\n"));
}
hRC = NULL; // Set RC To NULL
}
if (hDC) {
if (!ReleaseDC(hWnd, hDC)) { // Are We Able To Release The DC
FWARNING(("TiledSupport::killGLWindow: Release Device Context Failed!\n"));
}
hDC = NULL; // Set DC To NULL
}
if (hWnd) {
if (!DestroyWindow(hWnd)) { // Are We Able To Destroy The Window?
FWARNING(("TiledSupport::killGLWindow: Could Not Release hWnd!"));
}
hWnd = NULL; // Set hWnd To NULL
}
}
// function executed within the thread
void ThreadProc (void* )
{
std::cout << "enter ThreadProc" << std::endl;
pSyncBarrier->enter(2);
pAppThread->getChangeList()->applyNoClear();
pSyncBarrier->enter(2);
OSG::commitChanges();
OSG::WIN32Window *pLocalWin =
OSG::convertToCurrentAspect<OSG::WIN32Window *>(win2.get());
makeCurrent(0);
while (true) {
pSyncBarrier->enter(2);
pAppThread->getChangeList()->applyNoClear();
pSyncBarrier->enter(2);
OSG::commitChanges();
pLocalWin->render(ract);
// swapBuffers(0);
}
}
// create OpenGL window
bool createWindow ()
{
if (hInstance == NULL) { // register window class
hInstance = GetModuleHandle(NULL); // Grab An Instance For Our Window
WNDCLASS wc; // Windows Class Structure
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Size, And Own DC For Window.
wc.lpfnWndProc = (WNDPROC)DefWindowProc; // WndProc Handles Messages
wc.cbClsExtra = 0; // No Extra Window Data
wc.cbWndExtra = 0; // No Extra Window Data
wc.hInstance = hInstance; // Set The Instance
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load The Default Icon
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load The Arrow Pointer
wc.hbrBackground = NULL; // No Background Required For GL
wc.lpszMenuName = NULL; // We Don't Want A Menu
wc.lpszClassName = "OpenSG Tile"; // Set The Class Name
if (!RegisterClass(&wc)) { // Attempt To Register The Window Class
FWARNING(("TiledSupport::createWindows: Failed To Register The Window Class!\n"));
return false;
}
}
RECT mClientRect;
mClientRect.left = 10;
mClientRect.top = 10;
mClientRect.right = mClientRect.left + win_width;
mClientRect.bottom = mClientRect.top + win_height;
DWORD dwStyle = WS_OVERLAPPEDWINDOW; // Windows Style
DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended Style
//AdjustWindowRectEx(&mClientRect, dwStyle, FALSE, dwExStyle); // Adjust WindowRect To True Size Including Decorations
GLuint PixelFormat; // Holds The Results After Searching For A Match
// open one window
FWARNING(("TiledSupport::createWindows: open window\n"));
// Create The Window
hWnd = CreateWindowEx(dwExStyle, // Extended Style For The Window
"OpenSG Tile", // Class Name
"Tiles", // Window Title
dwStyle | // Defined Window Style
WS_CLIPSIBLINGS | // Required Window Style
WS_CLIPCHILDREN, // Required Window Style
mClientRect.left,
mClientRect.top, // Window Position
win_width, // Calculate Window Width
win_height, // Calculate Window Height
NULL, // No Parent Window
NULL, // No Menu
hInstance, // Instance
NULL);
if (!hWnd) { // Pass this-Pointer To WM_CREATE
killGLWindow(0); // Reset The Display
FWARNING(("TiledSupport::createWindows: Window Creation Error!\n"));
return false;
}
ShowWindow(hWnd, SW_SHOW); // Show The Window
//SetForegroundWindow(hWnd); // Slightly Higher Priority
//ResizeGLScene(width, height); // Set Up Our Perspective GL Screen
hDC = GetDC(hWnd);
if (hDC == 0) { // Did We Get A Device Context?
killGLWindow(0); // Reset The Display
FWARNING(("TiledSupport::createWindows: Can't Create A GL Device Context!\n"));
return false;
}
static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
1, // version number
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
PFD_DOUBLEBUFFER, // double buffered
PFD_TYPE_RGBA, // RGBA type
24, // 24-bit color depth
0, 0, 0, 0, 0, 0, // color bits ignored
0, // no alpha buffer
0, // shift bit ignored
0, // no accumulation buffer
0, 0, 0, 0, // accum bits ignored
32, // 32-bit z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
};
PixelFormat = ChoosePixelFormat(hDC, (const PIXELFORMATDESCRIPTOR*)&pfd);
if (PixelFormat == 0) {
// Did Windows Find A Matching Pixel Format?
killGLWindow(0); // Reset The Display
FWARNING(("TiledSupport::createWindows: Can't Find A Suitable PixelFormat!\n"));
return false;
}
if (!SetPixelFormat(hDC, PixelFormat, (const PIXELFORMATDESCRIPTOR*)&pfd)) {
// Are We Able To Set The Pixel Format?
killGLWindow(0); // Reset The Display
FWARNING(("TiledSupport::createWindows: Can't Set The PixelFormat!\n"));
return false;
}
ShowWindow(hWnd, SW_SHOW); // Show The Window
hRC = wglCreateContext(hDC);
if (hRC == 0) {
// Are We Able To Get A Rendering Context?
killGLWindow(0); // Reset The Display
FWARNING(("TiledSupport::createWindows: Can't Create A GL Rendering Context!\n"));
return false;
}
makeCurrent(0);
}
int main(int argc, char **argv)
{
OSG::ChangeList::setReadWriteDefault(true);
OSG::osgInit(argc,argv);
// GLUT init
glutInit (&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize (500, 500);
winId = glutCreateWindow("OpenSG");
glutReshapeFunc (NULL);
glutDisplayFunc (display);
glutIdleFunc (display);
glutMouseFunc (mouse);
glutMotionFunc (motion);
glutKeyboardFunc(keyboard);
win = OSG::GLUTWindow::create();
win->setGlutId(winId);
win->init();
win->resize(500, 500);
// create OSG objects
createWindow();
// create OSG objects
win2 = OSG::WIN32Window::create();
win2->editSFHwnd() ->setValue(hWnd);
win2->editSFHdc() ->setValue(hDC);
win2->editSFHglrc()->setValue(hRC);
ract = OSG::RenderAction::create();
ract->setVolumeDrawing(true);
win2->init();
// very important for the size of viewports
win2->resize(win_width, win_height);
// very important: a context can only be current on one thread
makeCurrent(-1);
// create the scene
OSG::NodeUnrecPtr scene = OSG::makeCoredNode<OSG::Group>();
#if 1
std::cout << "load background" << std::endl;
OSG::NodeRecPtr box = loadBackground();
scene->addChild(box);
std::cout << "done." << std::endl;
#endif
scene->addChild(OSG::makeTorus(1.0f, 2.0f, 5, 5));
// create the SimpleSceneManager helper
mgr = new OSG::SimpleSceneManager;
// create the window and initial camera/viewport
mgr->setWindow(win );
// tell the manager what to manage
mgr->setRoot (scene);
// create shared OSG elements
OSG::SolidBackgroundRecPtr bg = OSG::SolidBackground::create();
bg->setColor(OSG::Color3f(0.5f, 0.0f, 0.0f));
OSG::CameraUnrecPtr cam = mgr->getCamera();
OSG::NodeUnrecPtr root = mgr->getInternalRoot();
OSG::ViewportRecPtr np = OSG::Viewport::create();
np->setCamera (cam);
np->setRoot (root);
np->setSize (0, 0, 1, 1);
np->setBackground(bg);
//np->addForeground(fg);
win2->addPort(np);
OSG::Thread::getCurrentChangeList()->commitChanges();
// show the whole scene
mgr->showAll();
pAppThread = static_cast<OSG::Thread *>(OSG::Thread::getCurrent());
// instead start a new thread which runs the loop
pDrawThread = OSG::Thread::get("render", 0);
pSyncBarrier = OSG::Barrier::get("sync", 0);
#if 1
pDrawThread->runFunction(::ThreadProc, // thread function
1, // aspect id
NULL); // thread argument
#endif
pSyncBarrier->enter(2);
pSyncBarrier->enter(2);
OSG::Thread::getCurrentChangeList()->clear();
// GLUT main loop
glutMainLoop ();
return 0;
}
------------------------------------------------------------------------------
Learn Windows Azure Live! Tuesday, Dec 13, 2011
Microsoft is holding a special Learn Windows Azure training event for
developers. It will provide a great way to learn Windows Azure and what it
provides. You can attend the event by watching it streamed LIVE online.
Learn more at http://p.sf.net/sfu/ms-windowsazure
_______________________________________________
Opensg-users mailing list
Opensg-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensg-users