void OpenGLInitialization( void )
{
	// We're drawing on a white background
	glClearColor(1.0, 1.0, 1.0, 1.0);

	// Convert our xyz curves into vertex arrays
	for (uint i=0; i<curves.Size(); i++)
		drawableCurves.Add( CurveToVertexArray( curves[i] ) );

	// Covert our xyz curves into difference arrays.  TODO: This is hard coded (our difference is
	//    computed from either curve #0 or curve #6)
	for (uint i=0; i<curves.Size(); i++)
		errorCurves.Add( DifferenceToVertexArray( curves[i], curves[ i<6?0:6 ] ) );

	// Load the shaders to draw our curves; set some parameters
	draw = new IGLUShaderProgram( "shaders/drawXYZCurve.vert.glsl", 
								  "shaders/drawXYZCurve.geom.glsl",
								  "shaders/drawXYZCurve.frag.glsl" );
	draw["xRange"] = vec2( 330.0f, 843.0f );
	draw["yRange"] = vec2( -0.13f, 2.05f );

	// Load the shader to draw our axes
	drawAxes = new IGLUShaderProgram( "shaders/drawAxes.vert.glsl", 
								      "shaders/drawAxes.frag.glsl" );

	// Create the geometry for our axes
	axes = new IGLUVertexArray();
	float axesData[] = { -0.90f, -0.88f, 0.95f, -0.88f,       // x-axis line
		                 -0.88f, -0.88f, -0.88f, 0.95f,       // y-axis line
						 -0.90f, -0.6513f, -0.88f, -0.6513f,  // 0.25 tick
						 -0.90f, -0.4225f, -0.88f, -0.4225f,  // 0.5 tick
						 -0.90f, -0.1938f, -0.88f, -0.1938f,  // 0.75 tick
						 -0.90f, 0.035f, -0.88f, 0.035f,      // 1.0 tick
						 -0.90f, 0.2638f, -0.88f, 0.2638f,    // 1.25 tick
						 -0.90f, 0.4925f, -0.88f, 0.4925f,    // 1.5 tick
						 -0.90f, 0.7213f, -0.88f, 0.7213f,    // 1.75 tick
						 -0.90f, 0.95f, -0.88f, 0.95f,        // 2.0 tick
						 -0.7243f, -0.88f, -0.7243f, -0.91f,  // 400 nm tick
						 -0.5296f, -0.88f, -0.5296f, -0.91f,  // 450 nm tick
						 -0.3349f, -0.88f, -0.3349f, -0.91f,  // 500 nm tick
						 -0.1402f, -0.88f, -0.1402f, -0.91f,  // 550 nm tick
						 0.0545f, -0.88f, 0.0545f, -0.91f,    // 600 nm tick
						 0.24915f, -0.88f, 0.24915f, -0.91f,  // 650 nm tick
						 0.4438f, -0.88f, 0.4438f, -0.91f,    // 700 nm tick
						 0.6385f, -0.88f, 0.6385f, -0.91f,    // 750 nm tick
						 0.8332f, -0.88f, 0.8332f, -0.91f,    // 800 nm tick
	};
	axes->SetVertexArray( sizeof( axesData ), axesData );
	axes->EnableAttribute( IGLU_ATTRIB_VERTEX, 2, GL_FLOAT );
}
// Draw
void display ( void )
{
	int j=0;
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	glLineWidth( GLfloat(lineWidth) );

	if (!useErrors)
	{
		// Bind and setup the shader
		draw->Enable();
		draw["xRange"] = vec2( 330.0f, 843.0f );
		draw["yRange"] = vec2( -0.13f, 2.05f );
		draw["useXYZ"]    = vec3( displayX ? 1.0f : 0.0f, 
								  displayY ? 1.0f : 0.0f, 
								  displayZ ? 1.0f : 0.0f );
			// For each curve, check if it's selected to be display, if so, draw it
			for (uint i=0; i<drawableCurves.Size(); i++)
			{
				// Check if this curve was selected to be drawn
				if ( curveSelection[i]->GetValue() )
				{
					draw["xColor"] = colorArr[j++];
					draw["yColor"] = colorArr[j++];
					draw["zColor"] = colorArr[j++];
					drawableCurves[i]->DrawArrays( GL_LINE_STRIP, 0, 471 );
				}
			}
		draw->Disable();

		// After drawing the curve, draw the axes
		drawAxes->Enable();
			axes->DrawArrays( GL_LINES, 0, 38 );
		drawAxes->Disable();
	}
	else
	{
		// Bind and setup the shader
		draw->Enable();
		draw["xRange"] = vec2( 330.0f, 843.0f );
		draw["yRange"] = vec2( -0.25f, 0.25f );
		draw["useXYZ"]    = vec3( displayX ? 1.0f : 0.0f, 
								  displayY ? 1.0f : 0.0f, 
								  displayZ ? 1.0f : 0.0f );
			// For each curve, check if it's selected to be display, if so, draw it
			for (uint i=0; i<errorCurves.Size(); i++)
			{
				// Check if this curve was selected to be drawn
				if ( curveSelection[i]->GetValue() )
				{
					draw["xColor"] = colorArr[j++];
					draw["yColor"] = colorArr[j++];
					draw["zColor"] = colorArr[j++];
					errorCurves[i]->DrawArrays( GL_LINE_STRIP, 0, 471 );
				}
			}
		draw->Disable();
	}

	// Draw the labels
	for (int i=0; i<10; i++)
		IGLUDraw::DrawColorText( IGLU_FONT_VARIABLE, 
		                         int(textOffsetFactor.X()*labels[i].x), 
								 int(textOffsetFactor.Y()*labels[i].y), 
								 color::Gray80, labels[i].name, textOffsetFactor.X() );
}
int main(int argc, char** argv)
{
	// Load all the XYZ curves we might look at...
	curves.Add( new XYZ1931CIE1nm() );
	curves.Add( new XYZ1931CIE10nm() );
	curves.Add( new XYZ1931Binned30nm() );
	curves.Add( new XYZSimpleGaussian1931() );
	curves.Add( new XYZMultiLobeFit1931() );
	curves.Add( new XYZMoonSpencer1945() );
	curves.Add( new XYZ1964CIE1nm() );
	curves.Add( new XYZSimpleGaussian1964() );
	curves.Add( new XYZTannenbaum1974() );

	// Setup our window 
	IGLUWindow::Ptr myWin = new IGLUWindow( 800, 600, "XYZ Curve and Approximation Viewer \t [Press (+) for options.]" );
	myWin->SetWindowProperties( IGLU_WINDOW_DOUBLE |
								IGLU_WINDOW_REDRAW_ON_IDLE ); 
	myWin->SetDisplayCallback( display );  
	myWin->SetIdleCallback( idle );
	myWin->SetKeyboardCallback( keys );
	myWin->SetReshapeCallback( reshape );
	myWin->SetPreprocessOnGLInit( OpenGLInitialization );
	myWin->CreateWindow( argc, argv );     

	// We set the window up with a particular scaling for the label locations.
	//    If we've changed the window resolution, we'll need to rescale
	textOffsetFactor = vec2( myWin->w()/800.0f, myWin->h()/600.0f );

	// Create a widget window to allow us to interact/change our IGLUVariables
	uiWin = new IGLUWidgetWindow( 300, 600, "UI Widget Window" );
	uiWin->AddWidget( &lineWidth );
	uiWin->AddWidgetSpacer();
	uiWin->AddWidget( &displayX );
	uiWin->AddWidget( &displayY );
	uiWin->AddWidget( &displayZ );
	uiWin->AddWidgetSpacer();

	// Convert these curves into vertex arrays
	for (uint i=0; i<curves.Size(); i++)
	{
		curveSelection.Add( new IGLUBool( i==0, curves[i]->CurveName() ) );
		uiWin->AddWidget( curveSelection[i] );
	}

	uiWin->AddWidgetSpacer();
	uiWin->AddWidget( &useErrors );

	myWin->SetWidgetWindow( uiWin );
	
	// Start the FLTK interaction loop
	IGLUWindow::Run();
	return 0;
}
示例#4
0
void IGLUShaderVariable::operator= ( const IGLUTexture *val )
{
	// Check for a valid shader index (else we have no variable to assign to!)
	if ( val == NULL || m_varIdx < 0 ) return;
	
	//Depending on whether we are binding image
	IGLUArray1D<IGLUShaderTexture *> *parentArr = 0;
	
	
	//Is the LHS a sampler or image type?
	bool lhsIsImage = IsImage(m_varType);

	if(lhsIsImage){
		
		//Check for variable type mismatch
		if( HasImageTypeMismatch( val ) ) return;
		
		//We are going to modify the parent's array of images
		parentArr = &m_parent->m_activeImage;

	}else{

		// Check for variable type mismatches.  
		if ( HasTextureTypeMismatch( val ) ) return;

		parentArr = &m_parent->m_activeTex;
	}

	// OK.  We now know we can do an assignment, lets get that setup.
	IGLUShaderTexture *ptr = 0;

	// 1) Look to see if we'd previously assigned a texture to this sampler
	//    in the parent shader.  If so, grab it's info.
	for (uint i=0; i < parentArr->Size(); i++)         // Look through list of active samplers for the parent shader
		if ( (*parentArr)[i]->m_glslVarLoc == m_varIdx ) // Is this sampler the variable on the LHS of the assignment?
			ptr = (*parentArr)[i];                       // If so, grab a pointer to its previously assigned tex struct.

	// 2) If we already have a data structure, lets replace/update that 
	//    texture with the one the user just specified.
	if (ptr) ptr->m_tex = val;

	// 3) If we haven't yet assigned a texture to this GLSL sampler, set up
	//    a new structure with appropriate data, assign it the next available
	//    texture unit (e.g., GL_TEXTURE4), and tell the shader to start
	//    binding it whenever the shader is enabled.
	else
	{
		ptr               = new IGLUShaderTexture();  // Create a structure for this sampler's texture.
		ptr->m_tex        = val;                      // Remember the texture pointer for this sampler
		ptr->m_glslVarLoc = m_varIdx;                 // What's the linked uniform/sampler location in GLSL?
		ptr->m_texUnit    = int( parentArr->Size() );  // What OpenGL texture unit did we assign?
		strncpy( ptr->m_texName, m_varName, 32 );     // Copy the GLSL sampler variable name.	

		// Add this to the list of textures the shader knows about.
		parentArr->Add( ptr );

		// Add a texture/unit/variable flag to the list store in the parent.
		//    In particular, right now, this flag only stores if the variable/unit we've bound to
		//    asks for a shadow sampler...  In that case, we'll need to tell the texture we enable
		//    that it should expect to be queried with a comparison operator, rather than as an image.
		m_parent->m_activeTexFlags.Add( IsShadowSampler( m_varType ) ? IGLU_SHADER_TEX_IS_SHADOW : IGLU_SHADER_TEX_DEFAULT );

		// Tell the shader what texture unit to look on for this sampler
		m_parent->PushProgram();
			glUniform1i( m_varIdx, ptr->m_texUnit );
		m_parent->PopProgram();
	}

	// If we're currently enabled, we'd better do the work the shader class
	//    would normally do (in ShaderProgram::Enable()) to enable this texture.
	if (m_parent->IsEnabled() && ptr){
		if(lhsIsImage)
			val->BindToImageUnit(ptr->m_texUnit);
		else
			val->Bind(GL_TEXTURE0 + ptr->m_texUnit);
	}
	
}