/* $Id$Revision: */
/* vim:set shiftwidth=4 ts=8: */
/*************************************************************************
* Copyright (c) 2011 AT&T Intellectual Property
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors: See CVS logs. Details at http://www.graphviz.org/
*************************************************************************/
#include "glexpose.h"
#include "draw.h"
#include "topviewfuncs.h"
#include "glutils.h"
#include "topfisheyeview.h"
#include "gui/toolboxcallbacks.h"
#include "arcball.h"
#include "hotkeymap.h"
#include "polytess.h"
GLuint texture[3];
static int Status=0; // Status Indicator
void LoadGLTextures() // Load Bitmaps And Convert To Textures
{
int imageWidth,imageHeight;
unsigned char *data = glCompLoadPng ("c:/graphviz-ms/bin/Data/Crate.png", &imageWidth, &imageHeight);
if (!data)
{
printf ("Data/Crate.bmp could not be located\n");
exit(-1);
}
// Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit
glGenTextures(3, &texture[0]); // Create Three Textures
// Create Nearest Filtered Texture
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, 3, imageWidth,imageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
// Create Linear Filtered Texture
glBindTexture(GL_TEXTURE_2D, texture[1]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, imageWidth,imageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
// Create MipMapped Texture
glBindTexture(GL_TEXTURE_2D, texture[2]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, imageWidth,imageHeight, GL_RGBA, GL_UNSIGNED_BYTE,data);
Status=1; // Set The Status To TRUE
}
#if UNUSED
void draw_cube_tex()
{
glRotatef(45,1,1,1);
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
if(!Status)
LoadGLTextures();
if(!Status)
return;
glBindTexture(GL_TEXTURE_2D,texture[1]);
glBegin(GL_QUADS);
// Front Face
glColor4f(1, 1, 1,1); // Color Blue
glNormal3f( 0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-100.0f, -100.0f, 100.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 100.0f, -100.0f, 100.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 100.0f, 100.0f, 100.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-100.0f, 100.0f, 100.0f);
// Back Face
glNormal3f( 0.0f, 0.0f,-1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-100.0f, -100.0f, -100.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-100.0f, 100.0f, -100.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 100.0f, 100.0f, -100.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 100.0f, -100.0f, -100.0f);
// Top Face
glNormal3f( 0.0f, 1.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-100.0f, 100.0f, -100.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-100.0f, 100.0f, 100.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 100.0f, 100.0f, 100.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 100.0f, 100.0f, -100.0f);
// Bottom Face
glNormal3f( 0.0f,-1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-100.0f, -100.0f, -100.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 100.0f, -100.0f, -100.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 100.0f, -100.0f, 100.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-100.0f, -100.0f, 100.0f);
// Right face
glNormal3f( 1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 100.0f, -100.0f, -100.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 100.0f, 100.0f, -100.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 100.0f, 100.0f, 100.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 100.0f, -100.0f, 100.0f);
// Left Face
glNormal3f(-1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-100.0f, -100.0f, -100.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-100.0f, -100.0f, 100.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-100.0f, 100.0f, 100.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-100.0f, 100.0f, -100.0f);
glEnd();
glDisable(GL_TEXTURE_2D); // Enable Texture Mapping
}
static void draw_cube()
{
glRotatef(30,1,1,1);
glBegin(GL_QUADS); // Draw The Cube Using quads
glColor4f(0.0f, 100.0f, 0.0f,0.5); // Color Blue
glVertex3f(100.0f, 100.0f, -100.0f); // Top Right Of The Quad (Top)
glVertex3f(-100.0f, 100.0f, -100.0f); // Top Left Of The Quad (Top)
glVertex3f(-100.0f, 100.0f, 100.0f); // Bottom Left Of The Quad (Top)
glVertex3f(100.0f, 100.0f, 100.0f); // Bottom Right Of The Quad (Top)
glColor4f(100.0f, 0.5f, 0.0f,0.5); // Color Orange
glVertex3f(100.0f, -100.0f, 100.0f); // Top Right Of The Quad (Bottom)
glVertex3f(-100.0f, -100.0f, 100.0f); // Top Left Of The Quad (Bottom)
glVertex3f(-100.0f, -100.0f, -100.0f); // Bottom Left Of The Quad (Bottom)
glVertex3f(100.0f, -100.0f, -100.0f); // Bottom Right Of The Quad (Bottom)
glColor4f(100.0f, 0.0f, 0.0f,0.5); // Color Red
glVertex3f(100.0f, 100.0f, 100.0f); // Top Right Of The Quad (Front)
glVertex3f(-100.0f, 100.0f, 100.0f); // Top Left Of The Quad (Front)
glVertex3f(-100.0f, -100.0f, 100.0f); // Bottom Left Of The Quad (Front)
glVertex3f(100.0f, -100.0f, 100.0f); // Bottom Right Of The Quad (Front)
glColor3f(100.0f, 100.0f, 0.0f); // Color Yellow
glVertex3f(100.0f, -100.0f, -100.0f); // Top Right Of The Quad (Back)
glVertex3f(-100.0f, -100.0f, -100.0f); // Top Left Of The Quad (Back)
glVertex3f(-100.0f, 100.0f, -100.0f); // Bottom Left Of The Quad (Back)
glVertex3f(100.0f, 100.0f, -100.0f); // Bottom Right Of The Quad (Back)
glColor3f(0.0f, 0.0f, 100.0f); // Color Blue
glVertex3f(-100.0f, 100.0f, 100.0f); // Top Right Of The Quad (Left)
glVertex3f(-100.0f, 100.0f, -100.0f); // Top Left Of The Quad (Left)
glVertex3f(-100.0f, -100.0f, -100.0f); // Bottom Left Of The Quad (Left)
glVertex3f(-100.0f, -100.0f, 100.0f); // Bottom Right Of The Quad (Left)
glColor3f(100.0f, 0.0f, 100.0f); // Color Violet
glVertex3f(100.0f, 100.0f, -100.0f); // Top Right Of The Quad (Right)
glVertex3f(100.0f, 100.0f, 100.0f); // Top Left Of The Quad (Right)
glVertex3f(100.0f, -100.0f, 100.0f); // Bottom Left Of The Quad (Right)
glVertex3f(100.0f, -100.0f, -100.0f); // Bottom Right Of The Quad (Right)
glEnd();
}
#endif
static void drawRotatingAxis(void)
{
static GLUquadricObj *quadratic;
float AL = 45;
if (get_mode(view) != MM_ROTATE)
return;
if (!quadratic) {
quadratic = gluNewQuadric(); // Create A Pointer To The Quadric Object
gluQuadricNormals(quadratic, GLU_SMOOTH); // Create Smooth Normals
// gluQuadricTexture(quadratic, GL_TRUE); // Create Texture Coords
gluQuadricDrawStyle(quadratic, GLU_LINE);
}
glPushMatrix();
glLoadIdentity();
glMultMatrixf(view->arcball->Transform.M); /*arcball transformations , experimental */
glLineWidth(3);
glBegin(GL_LINES);
glColor3f(1, 1, 0);
glVertex3f(0, 0, 0);
glVertex3f(0, AL, 0);
glVertex3f(0, 0, 0);
glVertex3f(AL, 0, 0);
glVertex3f(0, 0, 0);
glVertex3f(0, 0, AL);
glEnd();
glColor4f(0, 1, 0, 0.3);
gluSphere(quadratic, AL, 20, 20);
glLineWidth(1);
glPopMatrix();
}
/*
refreshes camera settings using view parameters such as pan zoom etc
if a camera is selected viewport is switched to 3D
params:ViewInfo , global view variable defined in viewport.c
return value:always 1
*/
static int glupdatecamera(ViewInfo * view)
{
if (view->active_camera == -1)
glTranslatef(-view->panx, -view->pany, view->panz);
/*toggle to active camera */
else {
glMultMatrixf(view->arcball->Transform.M); /*arcball transformations , experimental */
glTranslatef(-view->cameras[view->active_camera]->targetx,
-view->cameras[view->active_camera]->targety, 0);
}
view->clipX1=0;
view->clipX2=0;
view->clipY1=0;
view->clipY2=0;
view->clipZ1=0;
view->clipZ2=0;
GetOGLPosRef(1, view->h - 5, &(view->clipX1), &(view->clipY1),
&(view->clipZ1));
GetOGLPosRef(view->w - 1, 1, &(view->clipX2), &(view->clipY2),
&(view->clipZ2));
if (view->active_camera == -1) {
glScalef(1 / view->zoom * -1, 1 / view->zoom * -1,
1 / view->zoom * -1);
} else {
glScalef(1 / view->cameras[view->active_camera]->r,
1 / view->cameras[view->active_camera]->r,
1 / view->cameras[view->active_camera]->r);
}
return 1;
}
#if 0
static void drawtestpoly(void)
{
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
// glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE , GL_DECAL);
// glBindTexture(GL_TEXTURE_2D,view->widgets->fontset->fonts[view->widgets->fontset->activefont]->texId);
glBindTexture(GL_TEXTURE_2D, 1);
glColor4f(1, 1, 1, 1);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glTexCoord2f(0.0, 1.0);
glVertex3f(0.0, 256.0, 0.0);
glTexCoord2f(1.0, 1.0);
glVertex3f(256.0, 256.0, 0.0);
glTexCoord2f(1.0, 0.0);
glVertex3f(256.0, 0.0, 0.0);
glTexCoord2f(0.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glEnd();
glDisable(GL_TEXTURE_2D);
}
#endif
/*
draws grid (little dots , with no use)
params:ViewInfo , global view variable defined in viewport.c
return value:none
*/
static void glexpose_grid(ViewInfo * view)
{
//drawing grids
float x, y;
if (view->gridVisible) {
glPointSize(1);
glBegin(GL_POINTS);
glColor4f(view->gridColor.R, view->gridColor.G, view->gridColor.B,
view->gridColor.A);
for (x = view->bdxLeft; x <= view->bdxRight;
x = x + view->gridSize) {
for (y = view->bdyBottom; y <= view->bdyTop;
y = y + view->gridSize) {
glVertex3f(x, y, 0);
}
}
glEnd();
}
}
/*
draws active graph depending on graph type
params:ViewInfo , global view variable defined in viewport.c
return value:1 if there is a graph to draw else 0
*/
static int glexpose_drawgraph(ViewInfo * view)
{
if (view->activeGraph > -1) {
// if (GD_TopView(view->g[view->activeGraph]))
// {
if (!view->Topview->fisheyeParams.active)
// drawTopViewGraph(view->g[view->activeGraph]); //view->Topview style dots and straight lines
renderSmGraph(view->g[view->activeGraph],view->Topview);
else {
drawtopologicalfisheye(view->Topview);
}
// }
// else
// drawGraph(view->g[view->activeGraph]); //xdot based drawing functions
return 1;
}
return 0;
}
#if 0
static void test_color_pallete(void)
{
int ind = 0;
float xGAP = 5;
float yGAP = 80;
float x = 50;
float y = 50;
glCompColor c;
for (ind = 0; ind < 350; ind++) {
getcolorfromschema(view->colschms, ind, 350, &c);
x = ind * xGAP;
glBegin(GL_POLYGON);
glColor3f(c.R, c.G, c.B);
glVertex3f(x, y, 0.0);
glVertex3f(x + xGAP, y, 0.0);
glVertex3f(x + xGAP, y + yGAP, 0.0);
glVertex3f(x, y + yGAP, 0.0);
glEnd();
}
}
#endif
/*
main gl expose ,any time sreen needs to be redrawn, this function is called by gltemplate
,all drawings are initialized in this function
params:ViewInfo , global view variable defined in viewport.c
return value:0 if something goes wrong with GL 1 , otherwise
*/
int glexpose_main(ViewInfo * view)
{
static int doonce = 0;
if (!glupdatecamera(view))
return 0;
// glEnable(GL_DEPTH_TEST);
// draw_cube();
// draw_cube_tex();
if (view->activeGraph >= 0) {
if (!doonce) {
doonce = 1;
btnToolZoomFit_clicked(NULL, NULL);
btnToolZoomFit_clicked(NULL, NULL);
}
}
else
return 0;
glexpose_grid(view);
#if UNUSED
draw_fisheye_magnifier(view);
draw_magnifier(view);
#endif
drawBorders(view);
glexpose_drawgraph(view);
drawRotatingAxis();
draw_selpoly(&view->Topview->sel.selPoly);
glCompSetDraw(view->widgets);
// draw_stuff();
// test_color_pallete();
// drawtestpoly();
/*DEBUG*/
/* if (view->mouse.mouse_mode == MM_PAN)
{
glBegin(GL_LINE_STRIP);
glColor4f((GLfloat) 1, (GLfloat) 0.0, (GLfloat) 0.0,
(GLfloat) 1);
glVertex3f((GLfloat) view->GLx, (GLfloat) view->GLy,
(GLfloat) 0.001);
glVertex3f((GLfloat) view->GLx2, (GLfloat) view->GLy2,
(GLfloat) 0.001);
glEnd();
}*/
/*DEBUG*/ return 1;
}
/*
void drawRotatingTools(void)
{
float x, y;
float x1, y1, z1;
float x2, y2, z2;
float R1, R2;
if ((view->mouse.mouse_mode == MM_ROTATE)
&& (view->active_camera >= 0)) {
R1 = 25;
R2 = 200;
glCompDrawBegin();
GetOGLPosRef(1, view->h - 5, &x1, &y1, &z1);
GetOGLPosRef(view->w - 1, 1, &x2, &y2, &z2);
x = (x2 - x1) / (float) 2.0;
y = (y2 - y1) / (float) 2.0;
glTranslatef(x, y, 0);
if ((view->mouse.rotate_axis == MOUSE_ROTATE_X)
|| (view->mouse.rotate_axis == MOUSE_ROTATE_XY)) {
glLineWidth(2);
glColor4f(0, 1, 0, 0.5);
} else {
glLineWidth(1);
glColor4f(1, 0, 0, 0.5);
}
drawEllipse(R1, R2, 90, 270);
if ((view->mouse.rotate_axis == MOUSE_ROTATE_Y)
|| (view->mouse.rotate_axis == MOUSE_ROTATE_XY)) {
glLineWidth(2);
glColor4f(0, 1, 0, 0.5);
} else {
glLineWidth(1);
glColor4f(1, 0, 0, 0.5);
}
drawEllipse(R2, R1, 0, 180);
if (view->mouse.rotate_axis == MOUSE_ROTATE_Z) {
glLineWidth(2);
glColor4f(0, 1, 0, 0.5);
} else {
glLineWidth(1);
glColor4f(1, 0, 0, 0.5);
}
drawEllipse(R2, R2, 0, 360);
glCompDrawEnd();
}
}
*/