⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hairmain.cpp

📁 hair solusion, c&#226 cs ádasda
💻 CPP
字号:
/**********************************************************/
/*                                                        */
/*                     HairMain.cpp                       */
/*                    Steve Sloan II                      */
/*                      March 2003                        */
/*                                                        */
/**********************************************************/

#include <math.h>
#include <GL/glut.h>
#include <string.h>

#include "GL/glui.h"

#include "utils.h"

#include "decal.h"
#include "HairGuides.h"
#include "ToolMarker.h"

#define MAXPATH 1024
#define FILECHOICES 9
#define DEFAULTFILE 4

#define DEFAULTSPACING 20

#define ORTHOWIDTH 0.8

#define FILE_CHOICE_ID		111
#define PERSP_CHECK_ID		112
#define HAIRSPACING_ID		113

static char scFileList[FILECHOICES][MAXPATH] = {
	"c:\\temp\\tgatest.tga",
	"c:\\temp\\colortest.tga",
	"c:\\temp\\blurtest.tga",
	"c:\\temp\\bobble08.tga",
	"c:\\temp\\jgfronta.tga",
	"c:\\temp\\14by11.tga",
	"c:\\temp\\16by12.tga",
	"c:\\temp\\bobble08_full.tga",
	"c:\\temp\\threeby3.tga"
};

// GLUI Elements

/** These are the live variables passed into GLUI ***/
int bSpin = 0;
int bPersp = 0;
int nHairSpacing = DEFAULTSPACING;

int mainWindow;

int ScreenWidth = 0;
int ScreenHeight = 0;

GLUI_Rotation *glui_rotate;
float mTrackball[16];

GLUI_Listbox *glui_FileSectionLB;
int FileSelection = DEFAULTFILE;

GLUI_Spinner *spacing_spinner;

GLUI_Panel *glui_hairsettings;
GLUI_Panel *glui_view;

GLuint nCursorPos = 0;

// Texture Info

Decal *CurrentDecal;

HairGuides HairArray;

ToolMarker Cursor;

GLdouble projmatrix[16];

// PrintPicture
// Input: tgaInfo*
// Output: void
// An early test function, confirming that the TGA reader works

void PrintPicture(tgaInfo *info)
{
	int mode, i, j, cursor;
	unsigned char grayscale = 0;

	printf("    width  = %4d\n", info->width);
	printf("    height = %4d\n", info->height);

	// compute the number of actual components
	mode = info->pixelDepth / 8;

	for (j = (info->height - 1); j >= 0; j--)
	{
		printf("[");
		for (i = 0; i < info->width; i ++)
		{
			cursor = mode * (j * info->width + i);
			grayscale =	(unsigned char)(0.30 * info->imageData[cursor] + 
							0.59 * info->imageData[cursor+1] +
							0.11 * info->imageData[cursor+2]);
			if (grayscale > 128)
				printf("X");
			else
				printf(" ");
		}
		printf("]\n");
	}
}

// DoPicture
// Input: char*
// Output: void
// Opens the TGA file specified by sFileName, copies its
// data into a texture with power-of-two dimensions, then
// sets up the texture for use in OpenGL

void DoPicture(char* sFileName)
{
	if (CurrentDecal)
		CurrentDecal->SetDecal(sFileName);
	else
		CurrentDecal = new Decal(sFileName);

	CurrentDecal->InitGLTexture();

	HairArray.SetTextureInfo(CurrentDecal);
	HairArray.SetPixelSpacing(nHairSpacing);

	Cursor.SetTextureInfo(CurrentDecal);
	Cursor.CreateDisplayList();
}

// DoReshape
// Input: void
// Output: void
// Do the actual work behind myGlutReshape

void DoReshape()
{
	glViewport( 0, 0, ScreenWidth, ScreenHeight );

	glMatrixMode( GL_PROJECTION );
	glLoadIdentity();

	float xy_aspect = (float)ScreenWidth / (float)ScreenHeight;

	if (bPersp)
	{
		glFrustum( -xy_aspect*.08, xy_aspect*.08, -.08, .08, .1, 15.0 );
	}
	else
	{
		float scaled_aspect = xy_aspect * ORTHOWIDTH;
		glOrtho( -scaled_aspect, scaled_aspect, -ORTHOWIDTH, ORTHOWIDTH, -10.0, 10.0 );
	}

	// Store the new projection matrix
	glGetDoublev(GL_PROJECTION_MATRIX, projmatrix);

	// Refresh the screen
	glutPostRedisplay();
}

void MoveCursor()
{
/*
	if ( ( nCursorPos > CurrentDecal->nPixelTextureWidth ) || ( nCursorPos > CurrentDecal->nPixelTextureHeight ) )
		nCursorPos = 0;
	else
		nCursorPos++;

	Cursor.SetPixelPos( nCursorPos, nCursorPos );
*/
}

// myGlutIdle
// Input: void
// Output: void
// Called when the program isn't doing anything else

void myGlutIdle( void )
{
	// According to the GLUT specification, the current window is
	// undefined during an idle callback.  So we need to explicitly
	// change it if necessary
	if ( glutGetWindow() != mainWindow )
		glutSetWindow(mainWindow);

	MoveCursor();

	glutPostRedisplay();
}

// myGlutReshape
// Input: w, h = New width and height of the window
// Output: void
// Update the screen's proportions when the window resizes

void myGlutReshape(int w, int h)
{
	ScreenWidth  = w;
	ScreenHeight = h;

	DoReshape();
}

// myGlutDisplay
// Input: void
// Output: void
// Display the scene

void myGlutDisplay(void)
{
	static float rotationX = 0.0, rotationY = 0.0;
	GLuint i = 0;

	glClearColor( .9f, .9f, .9f, 1.0f );
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

	/*** Rotate the object ***/
	rotationX += 3.3f;
	rotationY += 4.7f;

	glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();
	glTranslatef( 0.0, 0.0, -1.0 );
	if (bSpin)
	{
		glRotatef( rotationY, 0.0, 1.0, 0.0 );
		glRotatef( rotationX, 1.0, 0.0, 0.0 );
	}
	else
	{
		glMultMatrixf(mTrackball);
	}

	CurrentDecal->DoTransform();

	GLfloat fPlaneDif[]  = {1.0, 1.0, 1.0, 1.0};
	GLfloat fPlaneAmb[]  = {0.0, 0.0, 0.0, 1.0};
	GLfloat fPlaneSpec[] = {1.0, 1.0, 1.0, 1.0};

	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,  fPlaneDif);
	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT,  fPlaneAmb);

	CurrentDecal->Draw();

	HairArray.Draw();

	Cursor.Draw();

	glutSwapBuffers(); 
}

GLdouble dClamp(GLdouble val, GLdouble min, GLdouble max)
{
	if (val > max) return max;

	if (val < min) return min;

	return val;
}

void PlaceCursor(int mousex, int mousey)
{
	GLint viewport[4];
	GLdouble mvmatrix[16];
	GLdouble x1, y1, z1;
	GLdouble x2, y2, z2;
	GLdouble t;
	GLdouble wx, wy;
	GLint realy;

	glGetIntegerv(GL_VIEWPORT, viewport);
	glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix);

	// Get the "mouse line", from the mouse directly into the screen, in world coordinates
	realy = viewport[3] - (GLint) mousey - 1;

	gluUnProject( (GLdouble) mousex, (GLdouble) realy, 0.0,
		mvmatrix, projmatrix, viewport, &x1, &y1, &z1 );

	gluUnProject( (GLdouble) mousex, (GLdouble) realy, 1.0,
		mvmatrix, projmatrix, viewport, &x2, &y2, &z2 );

	// Compute where the "mouse line" intersects z = 0
	t = z1 / (z1 - z2);
	wx = x1 + t * (x2 - x1);
	wy = y1 + t * (y2 - y1);

	wx = dClamp(wx, 0.0, CurrentDecal->fPhysicalTextureWidth);
	wy = dClamp(wy, 0.0, CurrentDecal->fPhysicalTextureHeight);

	Cursor.SetWorldPos(wx, wy);
}

// myGlutPassiveMotion
// Input: void
// Output: void
// Display the scene

void myGlutPassiveMotion(int x, int y)
{
//	printf("Passive     x, y = (%5d, %5d)\n", x, y);

	PlaceCursor(x, y);
}

// myGlutMouse
// Input: void
// Output: void
// Display the scene

void myGlutMouse(int button, int state, int x, int y)
{
	switch (button)
	{
		case GLUT_LEFT_BUTTON:
			printf("L ");
			break;

		case GLUT_MIDDLE_BUTTON:
			printf("M ");
			break;

		case GLUT_RIGHT_BUTTON:
			printf("R ");
			break;
	}

	switch (state)
	{
		case GLUT_UP:
			printf("U ");
			break;

		case GLUT_DOWN:
			printf("D ");
			break;
	}

//	printf("        x, y = (%5d, %5d)\n", x, y);

	PlaceCursor(x, y);
}

// myGlutMotion
// Input: void
// Output: void
// Display the scene

void myGlutMotion(int x, int y)
{
//	printf("button down x, y = (%5d, %5d)\n", x, y);

	PlaceCursor(x, y);
}

// glui_control
// Input: control = ID of the control that changed
// Output: void
// React to changes in the widget data

void glui_control( int control )
{
	switch(control) {
		case FILE_CHOICE_ID:
			FileSelection = glui_FileSectionLB->get_int_val();
			DoPicture(scFileList[FileSelection]);
			break;

		case PERSP_CHECK_ID:
			DoReshape();
			break;

		case HAIRSPACING_ID:

			// Update the value
			nHairSpacing = spacing_spinner->get_int_val();

			// Change the spacing to match
			HairArray.SetPixelSpacing(nHairSpacing);

			// Refresh the screen
			glutPostRedisplay();

			break;
	}
}

// Cleanup
// Input: void
// Output: void
// Delete any data structures

void Cleanup()
{
	if (CurrentDecal)
	{
		delete CurrentDecal;
		CurrentDecal = NULL;
	}
}

// quit
// Input: status = program exit status
// Output: void
// Stuff to do when the program exits

void quit(int status) {
	Cleanup();
	exit(status);
}

void PrintVectorAngle(double x, double y)
{
	double angle = GetVectorAngle(x, y);

	printf("angle(%7.2f, %7.2f) = %7.2f\n", x, y, angle);
}

// main
// Input: argc, argv = program command line arguments
// Output: void
// Main body of the program

int main(int argc, char **argv)
{
	int i;

	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowPosition(0,0);
	glutInitWindowSize(500,500);
	mainWindow = glutCreateWindow("TGA Test");

	GLUI_Master.set_glutReshapeFunc(myGlutReshape);
	GLUI_Master.set_glutDisplayFunc(myGlutDisplay);

	GLUI_Master.set_glutMouseFunc(myGlutMouse);

	glutMotionFunc(myGlutMotion);
	glutPassiveMotionFunc(myGlutPassiveMotion);

	CurrentDecal = NULL;

	PrintVectorAngle( 0.0,  0.0); // 0
	PrintVectorAngle( 0.0,  1.0); // 0
	PrintVectorAngle( 1.0,  1.0); // 45
	PrintVectorAngle( 1.0,  0.0); // 90
	PrintVectorAngle( 2.0, -1.0); // ~117
	PrintVectorAngle( 0.0, -1.0); // 180
	PrintVectorAngle(-2.0, -1.0); // ~243
	PrintVectorAngle(-1.0,  0.0); // 270
	PrintVectorAngle(-1.0,  2.0); // ~333

	/****************************************/
	/*       Set up OpenGL lights           */
	/****************************************/

//	GLfloat light0_ambient[] =  {0.1f, 0.1f, 0.3f, 1.0f};
//	GLfloat light0_diffuse[] =  {.6f, .6f, 1.0f, 1.0f};
	GLfloat light0_ambient[] =  {0.05f, 0.05f, 0.05f, 1.0f};
	GLfloat light0_diffuse[] =  {1.0f, 1.0f, 1.0f, 1.0f};
	GLfloat light0_position[] = {1.0f, 1.0f, 1.0f, 0.0f};

	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
	glLightfv(GL_LIGHT0, GL_POSITION, light0_position);

	/****************************************/
	/*          Enable z-buferring          */
	/****************************************/

	glEnable(GL_DEPTH_TEST);

	/* Get texture */
	DoPicture(scFileList[DEFAULTFILE]);

	/****************************************/
	/*         Here's the GLUI code         */
	/****************************************/

	GLUI *glui = GLUI_Master.create_glui( "GLUI" );

	glui_FileSectionLB = glui->add_listbox("Image File:",
		NULL,FILE_CHOICE_ID,glui_control);

	// Fill the file list box
	for (i = 0; i < FILECHOICES; i++)
		glui_FileSectionLB->add_item( i, scFileList[i] );

	// Set the list box to the default
	glui_FileSectionLB->set_int_val(DEFAULTFILE);

	glui_hairsettings = glui->add_panel("Hair Settings");

	spacing_spinner = glui->add_spinner_to_panel( glui_hairsettings, "Guide Hair Spacing:",
		GLUI_SPINNER_INT, NULL, HAIRSPACING_ID, glui_control );
	spacing_spinner->set_int_val( DEFAULTSPACING );
	spacing_spinner->set_int_limits( 1, 1000 );

	// Set up the rotation "trackball"
	glui_view = glui->add_panel("View");

	glui_rotate = glui->add_rotation_to_panel( glui_view, "Rotation", mTrackball );
	glui_rotate->set_spin( 0.95 );
	glui_rotate->reset();

	glui->add_checkbox_to_panel( glui_view, "Perspective", &bPersp, PERSP_CHECK_ID, glui_control );

	glui->add_checkbox_to_panel( glui_view, "Spin?", &bSpin );

	// Quit button
	glui->add_button( "Quit", 0,quit);

	glui->set_main_gfx_window( mainWindow );

	/* We register the idle callback with GLUI, *not* with GLUT */
	GLUI_Master.set_glutIdleFunc( myGlutIdle ); 

	glutMainLoop();

	Cleanup();

	return(0);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -