Newer
Older
invertedlogic / InvertedLogic / iLFramework / toolkit / src / GL / Program.cpp
@John Ryland John Ryland on 10 Nov 2019 10 KB rename
#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