#include <string>
#include <vector>
#include <ctype.h>
#include "GL/Program.h"
#include "GL/TextView.h"
#include "GL/TreeView.h"
#include "GL/Context.h"
#include "GL/Math.h"
#include "GL/Font.h"
#include "GL/Nodes.h"
#include "GL/Menu.h"
#include "GL/Shaders.h"
#include "GL/Cubes.h"
#include "GL/ImmediateMode.h"
#include "GL/PythonTests.h"
#include "GL/LineDrawing.h"
#include "GL/Objects.h"
BEGIN_NAMESPACE
Menu mainMenu;
std::vector<NodePanel*> panels;
std::vector<Connection> connections;
TextView *view = 0;
TreeView<Object> *tree = 0;
bool editingConnection = false;
NodePanel* editingConnectionPanel = 0;
int editingConnectionType = 0; // 0 -> input type, 1 -> output type
int editingConnectionSlotIndex = 0;
GLuint texture;
float g_zoomFactor = 1.0;
float g_xOff = 0.0;
float g_yOff = 0.0;
int mouseX, mouseY, mouseButtons;
const char* menuItems[] =
{
"___File___", "New...",
"Open...",
"Open Recent...",
"Revert",
"Recover Last Session",
"Recover Auto Save...",
"**********",
"Save",
"Save As...",
"Save Copy...",
"**********",
"Quit",
"___Edit___", "Undo",
"Redo",
"**********",
"Cut",
"Copy",
"Paste",
"**********",
"Select All",
"___View___", "Full Screen",
"Log",
"___Help___", "View Help",
"About"
};
void AppMouseUpdate(int a_mouseX, int a_mouseY, int a_buttons, MouseButtons a_mouseButtons, MouseState a_mouseState)
{
mouseX = int((a_mouseX / g_zoomFactor) - g_xOff);
mouseY = int((a_mouseY / g_zoomFactor) - g_yOff);
mouseButtons = a_buttons;
for (unsigned i = 0; i < panels.size(); ++i) {
if ( panels[i]->highlighted ) {
panels[i]->x = mouseX - panels[i]->xDragStart;
panels[i]->y = mouseY - panels[i]->yDragStart;
}
if (a_mouseButtons == MB_Left && a_mouseState == MS_Up ) {
panels[i]->highlighted = false;
}
int x, y, w, h;
panels[i]->GetTitleBarArea(x, y, w, h);
if (mouseX >= x && mouseX < (x+w) && mouseY >= y && mouseY < (y+h)) {
// over titlebar
if (a_mouseButtons == MB_Left && a_mouseState == MS_Down ) {
panels[i]->xDragStart = mouseX - x;
panels[i]->yDragStart = mouseY - y;
panels[i]->highlighted = true;
}
}
for (unsigned s = 0; s < panels[i]->m_inputs.size(); ++s) {
panels[i]->GetInputSlotPosition(s, x, y);
if (((mouseX - x)*(mouseX - x)+(mouseY - y)*(mouseY - y)) < 10*10) {
// over input slot
if (a_mouseButtons == MB_Left && a_mouseState == MS_Up ) {
if (editingConnectionPanel != panels[i] && editingConnection && editingConnectionType ) {
bool foundExistingConnection = false;
for (unsigned c = 0; c < connections.size(); ++c) {
if (connections[c].inputPanel == panels[i] && s == connections[c].input) {
connections[c].outputPanel = editingConnectionPanel;
connections[c].output = editingConnectionSlotIndex;
foundExistingConnection = true;
break;
}
}
if (!foundExistingConnection) {
Connection con(editingConnectionPanel, editingConnectionSlotIndex, panels[i], s);
connections.push_back(con);
}
}
editingConnection = false;
break;
}
if (a_mouseButtons == MB_Left && a_mouseState == MS_Down ) {
editingConnection = true;
editingConnectionPanel = panels[i];
editingConnectionType = 0;
editingConnectionSlotIndex = s;
for (unsigned c = 0; c < connections.size(); ++c) {
if (connections[c].inputPanel == panels[i] && s == connections[c].input) {
editingConnectionPanel = connections[c].outputPanel;
editingConnectionType = 1;
editingConnectionSlotIndex = connections[c].output;
// remove it
connections[c] = connections.back();
connections.pop_back();
break;
}
}
break;
}
}
}
for (unsigned s = 0; s < panels[i]->m_outputs.size(); ++s) {
panels[i]->GetOutputSlotPosition(s, x, y);
if (((mouseX - x)*(mouseX - x)+(mouseY - y)*(mouseY - y)) < 10*10) {
// over output slot
if (a_mouseButtons == MB_Left && a_mouseState == MS_Up ) {
if (editingConnectionPanel != panels[i] && editingConnection && !editingConnectionType ) {
Connection con(panels[i], s, editingConnectionPanel, editingConnectionSlotIndex);
connections.push_back(con);
}
editingConnection = false;
break;
}
if (a_mouseButtons == MB_Left && a_mouseState == MS_Down ) {
editingConnection = true;
editingConnectionPanel = panels[i];
editingConnectionType = 1;
editingConnectionSlotIndex = s;
break;
}
}
}
}
if (a_mouseButtons == MB_Left && a_mouseState == MS_Up ) {
editingConnection = false;
}
}
void AppPaint(CUTE::CUTE_PaintTarget a_target)
{
glClearColor(0.25, 0.25, 0.25, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_POLYGON_SMOOTH);
/*
glEnable(GL_POINT_SMOOTH);
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
*/
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glLineWidth(0.75);
//glShadeModel(GL_FLAT);
//glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, (a_target.m_width-1.0f)/g_zoomFactor, (a_target.m_height-1.0f)/g_zoomFactor, 0, -1, 1);
glTranslatef((0.5f/g_zoomFactor-0.5f)*a_target.m_width, (0.5f/g_zoomFactor-0.5f)*a_target.m_height, 0.0f);
g_xOff = (0.5f/g_zoomFactor-0.5f)*a_target.m_width;
g_yOff = (0.5f/g_zoomFactor-0.5f)*a_target.m_height;
//glTranslatef(-1.0, 1.0, 0.0);
//glScalef(2.0 * g_zoomFactor / a_target.m_width, -2.0 * g_zoomFactor / a_target.m_height, 1.0f);
// Draw grid
for (int i = 0; i < a_target.m_width; i += 25)
glDrawLine((float)i, 0, (float)i, (float)a_target.m_height, 0x20000000);
for (int j = 0; j < a_target.m_height; j += 25)
glDrawLine(0, (float)j, (float)a_target.m_width, (float)j, 0x20000000);
// Draws the target buffer
//glDrawTarget(0.0, 0.0, a_target);
// Draws test shapes
/*
glDrawLine(10, 10, a_target.m_width - 10, a_target.m_height - 10, 0x00ff00);
glDrawCurvedLine(10, 10, a_target.m_width - 10, a_target.m_height - 10, 0x00ffff);
glDrawCurvedLine(a_target.m_width - 10, 10, 10, a_target.m_height - 10, 0x00ffff);
glDrawRect(100, 100, a_target.m_width - 100, a_target.m_height - 100, 0x00ff00);
glDrawCircle(150, 150, a_target.m_height - 150, 0x00ff00);
//glPixelZoom(g_zoomFactor, g_zoomFactor);
glDrawText(30, 50, "Hello World", 0xff000000, 0xffffffff, 15);
glDrawFillRect(x, y, x+w, y+h, 0x808080);
*/
for (unsigned i = 0; i < connections.size(); ++i)
connections[i].draw();
glCheckErrors();
if (editingConnection)
{
int x, y;
if (editingConnectionType) {
editingConnectionPanel->GetOutputSlotPosition(editingConnectionSlotIndex, x, y);
glDrawStyledCurvedLine((float)x, (float)y, (float)mouseX, (float)mouseY, g_zoomFactor, true);
} else {
editingConnectionPanel->GetInputSlotPosition(editingConnectionSlotIndex, x, y);
glDrawStyledCurvedLine((float)mouseX, (float)mouseY, (float)x, (float)y, g_zoomFactor, true);
}
}
glCheckErrors();
for (unsigned i = 0; i < panels.size(); ++i)
panels[i]->draw();
glCheckErrors();
mainMenu.x = 0;
mainMenu.y = 20;
mainMenu.w = a_target.m_width;
mainMenu.draw();
view->text = "Blah blah blah the quick brown fox jumps over the lazy dog. Blah blah break\nthe quick brown tab\t fox jumps over the lazy dog. Blah blah blah the quick brown fox jumps over the lazy dog. Blahblahthequickbrownfoxjumpsoverthelazydog. Blahblahthequickbrownfoxjumpsoverthelazydog. Blahblahthequickbrownfoxjumpsoverthelazydog.";
//view->draw();
tree->draw();
DrawShaderObjects();
DrawCubes();
// LineDrawingTests();
glCheckErrors();
SwapBuffers(wglGetCurrentDC());
}
void AppInit(HWND a_hwnd, CUTE::CUTE_PaintTarget a_target)
{
// Create the GL context
glWMCreate(a_hwnd);
glCheckErrors();
glLoadExtensions();
glInitFont();
glClearColor(0.0, 0.0, 0.0, 0.0);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
int w = a_target.m_strideBytes/4;
int h = nextPowerOfTwo(a_target.m_height);
glGenTextures(1, &texture);
glCheckErrors();
glBindTexture(GL_TEXTURE_2D, texture);
glCheckErrors();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // GL_LINEAR_MIPMAP_LINEAR); // Linear Filtering
glCheckErrors();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtering
glCheckErrors();
glTexImage2D(GL_TEXTURE_2D, 0, 3, w, h, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, a_target.m_pixels);
glCheckErrors();
SetupObjects();
SetupCubes();
view->x = a_target.m_width * 3 / 4;
view->w = a_target.m_width / 4;
view->y = a_target.m_height / 4;
view->h = a_target.m_height * 3 / 4;
tree->x = a_target.m_width * 3 / 4;
tree->w = a_target.m_width / 4;
tree->y = a_target.m_height / 4;
tree->h = a_target.m_height * 3 / 4;
}
void AppDestroy(HWND a_hwnd)
{
glDeleteTextures(1, &texture);
glCleanupFont();
CleanupObjects();
// Destroy the GL context
glWMDestroy(a_hwnd);
//ReleaseDC(a_hwnd, m_data->m_handle);
//if (m_data->m_glContext)
//wglDeleteContext(m_data->m_glContext);
}
void AppWheelUpdate(int a_wheel)
{
if (a_wheel > 0)
g_zoomFactor *= 1.3f;
else
g_zoomFactor *= 0.7f;
g_zoomFactor = (g_zoomFactor >= 10.0f) ? 10.0f : g_zoomFactor;
}
void AppContruct()
{
// PythonTests();
NodePanel *panelA = new NodePanel(110, 110, 150, 200, "Dot Product");
NodePanel *panelB = new NodePanel(410, 200, 150, 200, "Multiply");
NodePanel *panelC = new NodePanel(610, 200, 150, 200, "Random");
panelA->addInput("Vector");
panelA->addInput("Vector");
panelA->addOutput("Scalar");
panelB->addInput("Value");
panelB->addInput("Scalar");
panelB->addOutput("Value");
panelB->addOutput("Vector");
panelC->addInput("Seed");
panelC->addInput("Range");
panelC->addOutput("Value");
panelC->addOutput("Randomness");
panels.push_back(panelA);
panels.push_back(panelB);
panels.push_back(panelC);
/*
Connection connection(*panelA, 0, *panelB, 1);
connections.push_back(connection);
*/
mainMenu.initFromStringList(menuItems, ARRAY_SIZE(menuItems));
tree = new TreeView<Object>(g_objectTree, 700, 200, 200, 600, "Object Explorer");
view = new TextView(700, 200, 200, 600, "Text View");
}
END_NAMESPACE