Skip to content

Commit

Permalink
Merge pull request underdoeg#34 from pivotal/master
Browse files Browse the repository at this point in the history
ofxFensterCanvas
  • Loading branch information
underdoeg committed Nov 27, 2011
2 parents d71dc90 + 5253ee0 commit c6fb2d4
Show file tree
Hide file tree
Showing 12 changed files with 1,159 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ example/ofxFensterExample.xcodeproj/phwhitfield.pbxuser
example/ofxFensterExample.xcodeproj/phwhitfield.mode1v3
exampleMultipleGraphicCards/ofxFensterExample.xcodeproj/phwhitfield.pbxuser
exampleMultipleGraphicCards/ofxFensterExample.xcodeproj/phwhitfield.mode1v3
xcuserdata

*/phwhitfield.*
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ SCREENS
======================
![Screen shot](/underdoeg/ofxFenster/raw/master/docs/screenshot.png)

ACKNOWLEDGEMENTS
======================
Thanks to Pivotal Labs (http://pivotallabs.com).

LICENCE
======================
ofxFenster has an MIT Licence http://en.wikipedia.org/wiki/MIT_License

GHOST is GPL licenced. The modified source code can be found here: https://github.com/underdoeg/ghost
GHOST is GPL licenced. The modified source code can be found here: https://github.com/underdoeg/ghost
8 changes: 8 additions & 0 deletions exampleCanvas/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
*~
bin/*
!bin/data/
bin/libs/
include/
obj/
*.layout
build
9 changes: 9 additions & 0 deletions exampleCanvas/Project.xcconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//THE PATH TO THE ROOT OF OUR OF PATH RELATIVE TO THIS PROJECT.
//THIS NEEDS TO BE DEFINED BEFORE CoreOF.xcconfig IS INCLUDED
OF_PATH = ../../..

//THIS HAS ALL THE HEADER AND LIBS FOR OF CORE
#include "../../../libs/openFrameworksCompiled/project/osx/CoreOF.xcconfig"

OTHER_LDFLAGS = $(OF_CORE_LIBS)
HEADER_SEARCH_PATHS = $(OF_CORE_HEADERS)
753 changes: 753 additions & 0 deletions exampleCanvas/exampleCanvas.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions exampleCanvas/openFrameworks-Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>com.yourcompany.openFrameworks</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
</dict>
</plist>
15 changes: 15 additions & 0 deletions exampleCanvas/src/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include "ofMain.h"
#include "testApp.h"
#include "ofxFensterManager.h"
#include "ofAppGlutWindow.h"

//========================================================================
int main( ){
ofSetupOpenGL(ofxFensterManager::get(), 400, 400, OF_WINDOW); // <-------- setup the GL context

// this kicks off the running of my app
// can be OF_WINDOW or OF_FULLSCREEN
// pass in width and height too:
ofRunFensterApp(new testApp());
}

103 changes: 103 additions & 0 deletions exampleCanvas/src/testApp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#include "testApp.h"


//--------------------------------------------------------------
void testApp::setup() {
ofSetLogLevel(OF_LOG_VERBOSE);

// setup a canvas comprised of three columns in two rows, with the
// resolutions automatically detected from the displays.
//canvas.setup(this, 3, 2);
// or, if you want to force the resolutions of the screens:
//canvas.setup(this, 2, 1, 640, 480);
// and, if you want to force the resolutions of the screens, and put them
// all on one display (eg. for testing):
ofxDisplay * display = ofxDisplayManager::get()->getDisplays().front();
canvas.setup(this, 2, 1, 640, 480, display);

// set the backgrounds of all the screens
list<Screen *>::iterator sit;
for(sit = canvas.screens.begin(); sit != canvas.screens.end(); sit++){
(*sit)->window->setBackgroundColor(0, 255, 0);
}
}


//--------------------------------------------------------------
void testApp::update() {
}

//--------------------------------------------------------------
void testApp::draw() {
canvas.setupPerspectiveForActiveScreen();

ofPushStyle();
{
ofSetColor(255, 255, 255);
ofNoFill();
float radius = 20;

ofCircle(0, 0, radius);
ofCircle(canvas.getWidth(), 0, radius);
ofCircle(canvas.getWidth(), canvas.getHeight(), radius);
ofCircle(0, canvas.getHeight(), radius);
ofCircle(canvas.getWidth() / 2.0, canvas.getHeight() / 2.0, radius);

Screen * screen = canvas.getActiveScreen();
string index = ofToString(screen->index.x) + ", " + ofToString(screen->index.y);
float x = (canvas.getWidth() / (canvas.columns * 2)) * (screen->index.x * 2 + 1);
float y = (canvas.getHeight() / (canvas.rows * 2)) * (screen->index.y * 2 + 1);
ofDrawBitmapString(index, ofPoint(x, y));
}
ofPopStyle();
}

//--------------------------------------------------------------
void testApp::keyPressed(int key, ofxFenster* win) {

}

//--------------------------------------------------------------
void testApp::keyReleased(int key, ofxFenster* win) {
}

void testApp::mouseMoved(int x, int y, ofxFenster* win) {
}

//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y ) {

}

//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button) {

}

//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button) {

}

//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button) {

}

//--------------------------------------------------------------
void testApp::windowResized(int w, int h) {

}

//--------------------------------------------------------------
void testApp::gotMessage(ofMessage msg) {

}

//--------------------------------------------------------------
void testApp::dragEvent(ofDragInfo dragInfo) {

}

void testApp::mouseMovedEvent(ofMouseEventArgs &args) {
}
27 changes: 27 additions & 0 deletions exampleCanvas/src/testApp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#pragma once

#include "ofMain.h"
#include "ofxFensterManager.h"
#include "ofxFensterCanvas.h"

class testApp : public ofxFensterListener {

public:
void setup();
void update();
void draw();

void keyPressed (int key, ofxFenster* win);
void keyReleased(int key, ofxFenster* win);
void mouseMoved(int x, int y );
void mouseMoved(int x, int y, ofxFenster* win);
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);
void mouseMovedEvent(ofMouseEventArgs &args);

ofxFensterCanvas canvas;
};
166 changes: 166 additions & 0 deletions src/ofxFensterCanvas.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
#include "ofxFensterCanvas.h"

ofxFensterCanvas::ofxFensterCanvas(){
rect.x = 0;
rect.y = 0;
rect.width = 0;
rect.height = 0;
}

void ofxFensterCanvas::setScreenIndices(Screen * screen, int index){
screen->index.x = index % columns;
screen->index.y = floor(index / columns);
}

void ofxFensterCanvas::setup(ofxFensterListener * listener, int _columns, int _rows){
setup(listener, _columns, _rows, 0, 0);
}

void ofxFensterCanvas::setup(ofxFensterListener * listener, int _columns, int _rows, int width, int height){
setup(listener, _columns, _rows, width, height, NULL);
}

void ofxFensterCanvas::setup(ofxFensterListener * listener, int _columns, int _rows, int width, int height, ofxDisplay * display){
columns = _columns, rows = _rows;

ofxFenster * bootstrapWin = ofxFensterManager::get()->getActiveWindow();

if(display){
setupScreensOnDisplay(listener, display, width, height);
} else {
autoSetupScreensOnDisplays(listener, width, height);
}

ofxFensterManager::get()->deleteFenster(bootstrapWin);

verifyAndLogScreenSetup();
}

void ofxFensterCanvas::autoSetupScreensOnDisplays(ofxFensterListener * listener, int width, int height){
ofxDisplayList displays = ofxDisplayManager::get()->getDisplays();
ofLogNotice() << "Found" << displays.size() << "displays";

ofxDisplayList::iterator dit;
for(dit = displays.begin(); dit < displays.end(); dit++){
Screen * screen = setupScreenOnDisplay(listener, *dit, width, height);
}
}

void ofxFensterCanvas::setupScreensOnDisplay(ofxFensterListener * listener, ofxDisplay * display, int width, int height){
for(int i = 0; i < columns * rows; i++){
Screen * screen = setupScreenOnDisplay(listener, display, width, height);
}
}

Screen * ofxFensterCanvas::setupScreenOnDisplay(ofxFensterListener * listener, ofxDisplay * display, int width, int height){
Screen * screen = new Screen();

screen->display = display;
ofxFensterManager::get()->setActiveDisplay(screen->display);

int w, h;
if(width > 0 && height > 0){
w = width, h = height;
} else {
w = screen->display->width, h = screen->display->height;
}

screen->window = ofxFensterManager::get()->createFenster(0, 0, w, h, OF_WINDOW);
screen->window->addListener(listener);

// Insert the new screen into screens in the correct position
list<Screen *>::iterator sit;
for(sit = screens.begin(); sit != screens.end(); sit++){
if((*sit)->display->x > screen->display->x) {
setScreenIndices(*sit, std::distance(screens.begin(), sit) + 1);
break;
}
}
setScreenIndices(screen, std::distance(screens.begin(), sit));

setWidth(getWidth() + (screen->window->getWidth() / rows));
setHeight(getHeight() + (screen->window->getHeight() / columns));

screens.insert(sit, screen);
return screen;
}

void ofxFensterCanvas::verifyAndLogScreenSetup(){
if(columns * rows != screens.size()){
ofLogError() << "Expected" << columns * rows << "screens, but found" << screens.size();
ofExit();
}

list<Screen *>::iterator sit;
for(sit = screens.begin(); sit != screens.end(); sit++){
// it's tacky to iterate again just for logging, but this is the only
// way to ensure the log is accurate due to the sorting in the first
// iteration (above).
ofLogNotice() << "Set up display" << (*sit)->display->id << ": at" << (*sit)->index.x << "," << (*sit)->index.y << ", display" << (*sit)->display->width << "x" << (*sit)->display->height << ", window" << (*sit)->window->getWidth() << "x" << (*sit)->window->getHeight();
}
}

Screen * ofxFensterCanvas::getActiveScreen(){
ofxFenster * win = ofxFensterManager::get()->getActiveWindow();
Screen * screen;

list<Screen *>::iterator sit;
for(sit = screens.begin(); sit != screens.end(); sit++){
if((*sit)->window == win){
screen = *sit;
break;
}
}

return screen;
}

void ofxFensterCanvas::setupPerspectiveForActiveScreen(){
Screen * screen = getActiveScreen();
ofPoint size = screen->window->getWindowSize();

float halfFovTan = tanf(PI * 60 / 360.0);
float baseDist = (getHeight() / 2) / halfFovTan;
float near = baseDist / 10.f;
float far = baseDist * 10.f;
float aspect = (float) getWidth() / getHeight();

float wholeMaxY = near * halfFovTan;
float wholeMaxX = aspect * wholeMaxY;

float width = (wholeMaxX / columns) * 2;
float height = (wholeMaxY / rows) * 2;
float minX = -wholeMaxX + (width * screen->index.x);
float minY = -wholeMaxY + (height * ((rows - 1) - screen->index.y));
float maxX = minX + width;
float maxY = minY + height;

//ofLogNotice() << getWidth() << getHeight() << wholeMaxX << wholeMaxY;
//ofLogNotice() << screen->index.x << screen->index.y << minX << minY << maxX << maxY;

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(minX, maxX, minY, maxY, near / rows, far / rows);

glMatrixMode(GL_MODELVIEW);
// FIXME: this doesn't work when the screens are different sizes
int originalWidth = getWidth() / columns;
int originalHeight = getHeight() / rows;
glTranslatef(-(getWidth() - originalWidth) / 2, -(getHeight() - originalHeight) / 2, 0);
}

int ofxFensterCanvas::getWidth(){
return rect.width;
}
int ofxFensterCanvas::getHeight(){
return rect.height;
}
void ofxFensterCanvas::setWidth(int w){
rect.width = w;
}
void ofxFensterCanvas::setHeight(int h){
rect.height = h;
}
ofPoint ofxFensterCanvas::getCanvasPosition(){
return ofPoint(rect.x, rect.y);
}
Loading

0 comments on commit c6fb2d4

Please sign in to comment.