| | 1368 | void View::setUpViewForWoWVxDisplay(unsigned int screenNum, unsigned char wow_content, unsigned char wow_factor, unsigned char wow_offset, float wow_disparity_Zd, float wow_disparity_vz, float wow_disparity_M, float wow_disparity_C) |
|---|
| | 1369 | { |
|---|
| | 1370 | osg::notify(osg::INFO)<<"View::setUpViewForWoWVxDisplay(...)"<<std::endl; |
|---|
| | 1371 | |
|---|
| | 1372 | osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface(); |
|---|
| | 1373 | if (!wsi) |
|---|
| | 1374 | { |
|---|
| | 1375 | osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."<<std::endl; |
|---|
| | 1376 | return; |
|---|
| | 1377 | } |
|---|
| | 1378 | |
|---|
| | 1379 | osg::GraphicsContext::ScreenIdentifier si; |
|---|
| | 1380 | si.readDISPLAY(); |
|---|
| | 1381 | |
|---|
| | 1382 | // displayNum has not been set so reset it to 0. |
|---|
| | 1383 | if (si.displayNum<0) si.displayNum = 0; |
|---|
| | 1384 | |
|---|
| | 1385 | si.screenNum = screenNum; |
|---|
| | 1386 | |
|---|
| | 1387 | unsigned int width, height; |
|---|
| | 1388 | wsi->getScreenResolution(si, width, height); |
|---|
| | 1389 | |
|---|
| | 1390 | osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits; |
|---|
| | 1391 | traits->hostName = si.hostName; |
|---|
| | 1392 | traits->displayNum = si.displayNum; |
|---|
| | 1393 | traits->screenNum = si.screenNum; |
|---|
| | 1394 | traits->x = 0; |
|---|
| | 1395 | traits->y = 0; |
|---|
| | 1396 | traits->width = width; |
|---|
| | 1397 | traits->height = height; |
|---|
| | 1398 | traits->windowDecoration = false; |
|---|
| | 1399 | traits->doubleBuffer = true; |
|---|
| | 1400 | traits->sharedContext = 0; |
|---|
| | 1401 | |
|---|
| | 1402 | |
|---|
| | 1403 | osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get()); |
|---|
| | 1404 | if (!gc) |
|---|
| | 1405 | { |
|---|
| | 1406 | osg::notify(osg::NOTICE)<<"GraphicsWindow has not been created successfully."<<std::endl; |
|---|
| | 1407 | return; |
|---|
| | 1408 | } |
|---|
| | 1409 | |
|---|
| | 1410 | int tex_width = width; |
|---|
| | 1411 | int tex_height = height; |
|---|
| | 1412 | |
|---|
| | 1413 | int camera_width = tex_width; |
|---|
| | 1414 | int camera_height = tex_height; |
|---|
| | 1415 | |
|---|
| | 1416 | osg::Texture2D* texture = new osg::Texture2D; |
|---|
| | 1417 | texture->setTextureSize(tex_width, tex_height); |
|---|
| | 1418 | texture->setInternalFormat(GL_RGB); |
|---|
| | 1419 | texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR); |
|---|
| | 1420 | texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR); |
|---|
| | 1421 | |
|---|
| | 1422 | osg::Texture2D* textureD = new osg::Texture2D; |
|---|
| | 1423 | textureD->setTextureSize(tex_width, tex_height); |
|---|
| | 1424 | textureD->setInternalFormat(GL_DEPTH_COMPONENT); |
|---|
| | 1425 | textureD->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR); |
|---|
| | 1426 | textureD->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR); |
|---|
| | 1427 | |
|---|
| | 1428 | #if 0 |
|---|
| | 1429 | osg::Camera::RenderTargetImplementation renderTargetImplementation = osg::Camera::SEPERATE_WINDOW; |
|---|
| | 1430 | GLenum buffer = GL_FRONT; |
|---|
| | 1431 | #else |
|---|
| | 1432 | osg::Camera::RenderTargetImplementation renderTargetImplementation = osg::Camera::FRAME_BUFFER_OBJECT; |
|---|
| | 1433 | GLenum buffer = GL_FRONT; |
|---|
| | 1434 | #endif |
|---|
| | 1435 | |
|---|
| | 1436 | // front face |
|---|
| | 1437 | { |
|---|
| | 1438 | osg::ref_ptr<osg::Camera> camera = new osg::Camera; |
|---|
| | 1439 | camera->setName("Front face camera"); |
|---|
| | 1440 | camera->setGraphicsContext(gc.get()); |
|---|
| | 1441 | camera->setViewport(new osg::Viewport(0,0,camera_width, camera_height)); |
|---|
| | 1442 | camera->setDrawBuffer(buffer); |
|---|
| | 1443 | camera->setReadBuffer(buffer); |
|---|
| | 1444 | camera->setAllowEventFocus(false); |
|---|
| | 1445 | // tell the camera to use OpenGL frame buffer object where supported. |
|---|
| | 1446 | camera->setRenderTargetImplementation(renderTargetImplementation); |
|---|
| | 1447 | |
|---|
| | 1448 | // attach the texture and use it as the color buffer. |
|---|
| | 1449 | camera->attach(osg::Camera::COLOR_BUFFER, texture); |
|---|
| | 1450 | camera->attach(osg::Camera::DEPTH_BUFFER, textureD); |
|---|
| | 1451 | |
|---|
| | 1452 | addSlave(camera.get(), osg::Matrixd(), osg::Matrixd()); |
|---|
| | 1453 | } |
|---|
| | 1454 | |
|---|
| | 1455 | // WoW display set up. |
|---|
| | 1456 | { |
|---|
| | 1457 | osg::Texture1D *textureHeader = new osg::Texture1D(); |
|---|
| | 1458 | // Set up the header |
|---|
| | 1459 | { |
|---|
| | 1460 | unsigned char header[]= {0xF1,wow_content,wow_factor,wow_offset,0x00,0x00,0x00,0x00,0x00,0x00}; |
|---|
| | 1461 | // Calc the CRC32 |
|---|
| | 1462 | { |
|---|
| | 1463 | unsigned long _register = 0; |
|---|
| | 1464 | for(int i = 0; i < 10; ++i) { |
|---|
| | 1465 | unsigned char mask = 0x80; |
|---|
| | 1466 | unsigned char byte = header[i]; |
|---|
| | 1467 | for (int j = 0; j < 8; ++j) |
|---|
| | 1468 | { |
|---|
| | 1469 | bool topBit = (_register & 0x80000000) != 0; |
|---|
| | 1470 | _register <<= 1; |
|---|
| | 1471 | _register ^= ((byte & mask) != 0? 0x1: 0x0); |
|---|
| | 1472 | if (topBit) |
|---|
| | 1473 | { |
|---|
| | 1474 | _register ^= 0x04c11db7; |
|---|
| | 1475 | } |
|---|
| | 1476 | mask >>= 1; |
|---|
| | 1477 | } |
|---|
| | 1478 | } |
|---|
| | 1479 | unsigned char *p = (unsigned char*) &_register; |
|---|
| | 1480 | for(size_t i = 0; i < 4; ++i) |
|---|
| | 1481 | { |
|---|
| | 1482 | header[i+6] = p[3-i]; |
|---|
| | 1483 | } |
|---|
| | 1484 | } |
|---|
| | 1485 | |
|---|
| | 1486 | osg::ref_ptr<osg::Image> imageheader = new osg::Image(); |
|---|
| | 1487 | imageheader->allocateImage(256,1,1,GL_LUMINANCE,GL_UNSIGNED_BYTE); |
|---|
| | 1488 | { |
|---|
| | 1489 | unsigned char *cheader = imageheader->data(); |
|---|
| | 1490 | for (int x=0; x<256; ++x){ |
|---|
| | 1491 | cheader[x] = 0; |
|---|
| | 1492 | } |
|---|
| | 1493 | for (int x=0; x<=9; ++x){ |
|---|
| | 1494 | for (int y=7; y>=0; --y){ |
|---|
| | 1495 | int i = 2*(7-y)+16*x; |
|---|
| | 1496 | cheader[i] = (((1<<(y))&(header[x])) << (7-(y))); |
|---|
| | 1497 | } |
|---|
| | 1498 | } |
|---|
| | 1499 | } |
|---|
| | 1500 | textureHeader->setImage(imageheader.get()); |
|---|
| | 1501 | } |
|---|
| | 1502 | |
|---|
| | 1503 | // Create the Screen Aligned Quad |
|---|
| | 1504 | osg::Geode* geode = new osg::Geode(); |
|---|
| | 1505 | { |
|---|
| | 1506 | osg::Geometry* geom = new osg::Geometry; |
|---|
| | 1507 | |
|---|
| | 1508 | osg::Vec3Array* vertices = new osg::Vec3Array; |
|---|
| | 1509 | vertices->push_back(osg::Vec3(0,height,0)); |
|---|
| | 1510 | vertices->push_back(osg::Vec3(0,0,0)); |
|---|
| | 1511 | vertices->push_back(osg::Vec3(width,0,0)); |
|---|
| | 1512 | vertices->push_back(osg::Vec3(width,height,0)); |
|---|
| | 1513 | geom->setVertexArray(vertices); |
|---|
| | 1514 | |
|---|
| | 1515 | osg::Vec2Array* tex = new osg::Vec2Array; |
|---|
| | 1516 | tex->push_back(osg::Vec2(0,1)); |
|---|
| | 1517 | tex->push_back(osg::Vec2(0,0)); |
|---|
| | 1518 | tex->push_back(osg::Vec2(1,0)); |
|---|
| | 1519 | tex->push_back(osg::Vec2(1,1)); |
|---|
| | 1520 | geom->setTexCoordArray(0,tex); |
|---|
| | 1521 | |
|---|
| | 1522 | geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,4)); |
|---|
| | 1523 | geode->addDrawable(geom); |
|---|
| | 1524 | |
|---|
| | 1525 | // new we need to add the textures to the quad, and setting up the shader. |
|---|
| | 1526 | osg::StateSet* stateset = geode->getOrCreateStateSet(); |
|---|
| | 1527 | stateset->setTextureAttributeAndModes(0, textureHeader,osg::StateAttribute::ON); |
|---|
| | 1528 | stateset->setTextureAttributeAndModes(1, texture,osg::StateAttribute::ON); |
|---|
| | 1529 | stateset->setTextureAttributeAndModes(2, textureD,osg::StateAttribute::ON); |
|---|
| | 1530 | stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF); |
|---|
| | 1531 | |
|---|
| | 1532 | osg::ref_ptr<osg::Program> programShader = new osg::Program(); |
|---|
| | 1533 | stateset->setAttribute(programShader.get(), osg::StateAttribute::ON); |
|---|
| | 1534 | stateset->addUniform( new osg::Uniform("wow_width", (int)width)); |
|---|
| | 1535 | stateset->addUniform( new osg::Uniform("wow_height", (int)height)); |
|---|
| | 1536 | stateset->addUniform( new osg::Uniform("wow_disparity_M", wow_disparity_M)); |
|---|
| | 1537 | stateset->addUniform( new osg::Uniform("wow_disparity_Zd", wow_disparity_Zd)); |
|---|
| | 1538 | stateset->addUniform( new osg::Uniform("wow_disparity_vz", wow_disparity_vz)); |
|---|
| | 1539 | stateset->addUniform( new osg::Uniform("wow_disparity_C", wow_disparity_C)); |
|---|
| | 1540 | |
|---|
| | 1541 | stateset->addUniform(new osg::Uniform("wow_header", 0)); |
|---|
| | 1542 | stateset->addUniform(new osg::Uniform("wow_tcolor", 1)); |
|---|
| | 1543 | stateset->addUniform(new osg::Uniform("wow_tdepth", 2)); |
|---|
| | 1544 | |
|---|
| | 1545 | osg::Shader *frag = new osg::Shader(osg::Shader::FRAGMENT); |
|---|
| | 1546 | frag->setShaderSource(" "\ |
|---|
| | 1547 | " uniform sampler1D wow_header; " \ |
|---|
| | 1548 | " uniform sampler2D wow_tcolor; " \ |
|---|
| | 1549 | " uniform sampler2D wow_tdepth; " \ |
|---|
| | 1550 | " " \ |
|---|
| | 1551 | " uniform int wow_width; " \ |
|---|
| | 1552 | " uniform int wow_height; " \ |
|---|
| | 1553 | " uniform float wow_disparity_M; " \ |
|---|
| | 1554 | " uniform float wow_disparity_Zd; " \ |
|---|
| | 1555 | " uniform float wow_disparity_vz; " \ |
|---|
| | 1556 | " uniform float wow_disparity_C; " \ |
|---|
| | 1557 | " " \ |
|---|
| | 1558 | " float disparity(float Z) " \ |
|---|
| | 1559 | " { " \ |
|---|
| | 1560 | " return (wow_disparity_M*(1.0-(wow_disparity_vz/(Z-wow_disparity_Zd+wow_disparity_vz))) " \ |
|---|
| | 1561 | " + wow_disparity_C) / 255.0; " \ |
|---|
| | 1562 | " } " \ |
|---|
| | 1563 | " " \ |
|---|
| | 1564 | " void main() " \ |
|---|
| | 1565 | " { " \ |
|---|
| | 1566 | " vec2 pos = (gl_FragCoord.xy / vec2(wow_width/2,wow_height) ); " \ |
|---|
| | 1567 | " if (gl_FragCoord.x > float(wow_width/2)) " \ |
|---|
| | 1568 | " { " \ |
|---|
| | 1569 | " gl_FragColor = vec4(disparity(( texture2D(wow_tdepth, pos - vec2(1,0))).z)); " \ |
|---|
| | 1570 | " } " \ |
|---|
| | 1571 | " else{ " \ |
|---|
| | 1572 | " gl_FragColor = texture2D(wow_tcolor, pos); " \ |
|---|
| | 1573 | " } " \ |
|---|
| | 1574 | " if ( (gl_FragCoord.y >= float(wow_height-1)) && (gl_FragCoord.x < 256.0) ) " \ |
|---|
| | 1575 | " { " \ |
|---|
| | 1576 | " float pos = gl_FragCoord.x/256.0; " \ |
|---|
| | 1577 | " float blue = texture1D(wow_header, pos).b; " \ |
|---|
| | 1578 | " if ( blue < 0.5) " \ |
|---|
| | 1579 | " gl_FragColor.b -=0.5; " \ |
|---|
| | 1580 | " else " \ |
|---|
| | 1581 | " gl_FragColor.b += 0.5; " \ |
|---|
| | 1582 | " } " \ |
|---|
| | 1583 | " } " ); |
|---|
| | 1584 | |
|---|
| | 1585 | programShader->addShader(frag); |
|---|
| | 1586 | } |
|---|
| | 1587 | |
|---|
| | 1588 | // Create the Camera |
|---|
| | 1589 | { |
|---|
| | 1590 | osg::ref_ptr<osg::Camera> camera = new osg::Camera; |
|---|
| | 1591 | camera->setGraphicsContext(gc.get()); |
|---|
| | 1592 | camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT ); |
|---|
| | 1593 | camera->setClearColor( osg::Vec4(0.0,0.0,0.0,1.0) ); |
|---|
| | 1594 | camera->setViewport(new osg::Viewport(0, 0, width, height)); |
|---|
| | 1595 | GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; |
|---|
| | 1596 | camera->setDrawBuffer(buffer); |
|---|
| | 1597 | camera->setReadBuffer(buffer); |
|---|
| | 1598 | camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); |
|---|
| | 1599 | camera->setAllowEventFocus(false); |
|---|
| | 1600 | camera->setInheritanceMask(camera->getInheritanceMask() & ~osg::CullSettings::CLEAR_COLOR & ~osg::CullSettings::COMPUTE_NEAR_FAR_MODE); |
|---|
| | 1601 | //camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR); |
|---|
| | 1602 | |
|---|
| | 1603 | camera->setProjectionMatrixAsOrtho2D(0,width,0,height); |
|---|
| | 1604 | camera->setViewMatrix(osg::Matrix::identity()); |
|---|
| | 1605 | |
|---|
| | 1606 | // add subgraph to render |
|---|
| | 1607 | camera->addChild(geode); |
|---|
| | 1608 | |
|---|
| | 1609 | camera->setName("WoWCamera"); |
|---|
| | 1610 | |
|---|
| | 1611 | addSlave(camera.get(), osg::Matrixd(), osg::Matrixd(), false); |
|---|
| | 1612 | } |
|---|
| | 1613 | } |
|---|
| | 1614 | } |
|---|
| | 1615 | |
|---|
| | 1616 | |
|---|