void CameraController::frame( const Imath::Box3f &box, const Imath::V3f &viewDirection, const Imath::V3f &upVector )
{
	// make a matrix to centre the camera on the box, with the appropriate view direction
	M44f cameraMatrix = rotationMatrixWithUpDir( V3f( 0, 0, -1 ), viewDirection, upVector );
	M44f translationMatrix;
	translationMatrix.translate( box.center() );
	cameraMatrix *= translationMatrix;

	// translate the camera back until the box is completely visible
	M44f inverseCameraMatrix = cameraMatrix.inverse();
	Box3f cBox = transform( box, inverseCameraMatrix );

	Box2f screenWindow = m_data->screenWindow->readable();
	if( m_data->projection->readable()=="perspective" )
	{
		// perspective. leave the field of view and screen window as is and translate
		// back till the box is wholly visible. this currently assumes the screen window
		// is centred about the camera axis.
		float z0 = cBox.size().x / screenWindow.size().x;
		float z1 = cBox.size().y / screenWindow.size().y;

		m_data->centreOfInterest = std::max( z0, z1 ) / tan( M_PI * m_data->fov->readable() / 360.0 ) + cBox.max.z +
			m_data->clippingPlanes->readable()[0];

		cameraMatrix.translate( V3f( 0.0f, 0.0f, m_data->centreOfInterest ) );
	}
	else
	{
		// orthographic. translate to front of box and set screen window
		// to frame the box, maintaining the aspect ratio of the screen window.
		m_data->centreOfInterest = cBox.max.z + m_data->clippingPlanes->readable()[0] + 0.1; // 0.1 is a fudge factor
		cameraMatrix.translate( V3f( 0.0f, 0.0f, m_data->centreOfInterest ) );

		float xScale = cBox.size().x / screenWindow.size().x;
		float yScale = cBox.size().y / screenWindow.size().y;
		float scale = std::max( xScale, yScale );

		V2f newSize = screenWindow.size() * scale;
		screenWindow.min.x = cBox.center().x - newSize.x / 2.0f;
		screenWindow.min.y = cBox.center().y - newSize.y / 2.0f;
		screenWindow.max.x = cBox.center().x + newSize.x / 2.0f;
		screenWindow.max.y = cBox.center().y + newSize.y / 2.0f;
	}

	m_data->transform->matrix = cameraMatrix;
	m_data->screenWindow->writable() = screenWindow;
}
void CameraController::track( const Imath::V2f &p )
{
	V2i resolution = m_data->resolution->readable();
	Box2f screenWindow = m_data->screenWindow->readable();

	V2f d = p - m_data->motionStart;
	V3f translate( 0.0f );
	translate.x = -screenWindow.size().x * d.x/(float)resolution.x;
	translate.y = screenWindow.size().y * d.y/(float)resolution.y;
	if( m_data->projection->readable()=="perspective" && m_data->fov )
	{
		translate *= tan( M_PI * m_data->fov->readable() / 360.0f ) * (float)m_data->centreOfInterest;
	}
	M44f t = m_data->motionMatrix;
	t.translate( translate );
	m_data->transform->matrix = t;
}
void CameraController::dolly( const Imath::V2f &p )
{
	V2i resolution = m_data->resolution->readable();
	V2f dv = V2f( (p - m_data->motionStart) ) / resolution;
	float d = dv.x - dv.y;

	if( m_data->projection->readable()=="perspective" )
	{
		// perspective
		m_data->centreOfInterest = m_data->motionCentreOfInterest * expf( -1.9f * d );
		
		M44f t = m_data->motionMatrix;
		t.translate( V3f( 0, 0, m_data->centreOfInterest - m_data->motionCentreOfInterest ) );
		
		m_data->transform->matrix = t;
	}
	else
	{
		// orthographic
		Box2f screenWindow = m_data->motionScreenWindow;

		V2f centreNDC = V2f( m_data->motionStart ) / resolution;
		V2f centre(
			lerp( screenWindow.min.x, screenWindow.max.x, centreNDC.x ),
			lerp( screenWindow.max.y, screenWindow.min.y, centreNDC.y )
		);

		float newWidth = m_data->motionScreenWindow.size().x * expf( -1.9f * d );
		newWidth = std::max( newWidth, 0.01f );

		float scale = newWidth / screenWindow.size().x;
		
		screenWindow.min = (screenWindow.min - centre) * scale + centre;
		screenWindow.max = (screenWindow.max - centre) * scale + centre;
		m_data->screenWindow->writable() = screenWindow;
	}	
}
void BackdropNodeGadget::doRender( const Style *style ) const
{
	// this is our bound in gadget space
	Box2f bound = boundPlug()->getValue();
	
	// but because we're going to draw our contents at an arbitrary scale,
	// we need to compute a modified bound which will be in the right place
	// following scaling. 
	
	const Backdrop *backdrop = static_cast<const Backdrop *>( node() );
	const float scale = backdrop->scalePlug()->getValue();
	
	bound.min /= scale;
	bound.max /= scale;
	
	glPushMatrix();
	
	glScalef( scale, scale, scale );

	const Box3f titleCharacterBound = style->characterBound( Style::HeadingText );
	const float titleBaseline = bound.max.y - g_margin - titleCharacterBound.max.y;

	if( IECoreGL::Selector::currentSelector() )
	{
		// when selecting we render in a simplified form.
		// we only draw a thin strip around the edge of the backdrop
		// to allow the edges to be grabbed for dragging, and a strip
		// at the top to allow the title header to be grabbed for moving
		// around. leaving the main body of the backdrop as a hole is
		// necessary to allow the GraphGadget to continue to perform
		// drag selection on the nodes on top of the backdrop.
		
		const float width = hoverWidth() / scale;
			
		style->renderSolidRectangle( Box2f( bound.min, V2f( bound.min.x + width, bound.max.y ) ) ); // left
		style->renderSolidRectangle( Box2f( V2f( bound.max.x - width, bound.min.y ), bound.max ) ); // right
		style->renderSolidRectangle( Box2f( bound.min, V2f( bound.max.x, bound.min.y + width ) ) ); // bottom
		style->renderSolidRectangle( Box2f( V2f( bound.min.x, bound.max.y - width ), bound.max ) ); // top
		style->renderSolidRectangle( Box2f( V2f( bound.min.x, titleBaseline - g_margin ), bound.max ) ); // heading
	}
	else
	{
		// normal drawing mode
	
		style->renderBackdrop( bound, getHighlighted() ? Style::HighlightedState : Style::NormalState );

		const std::string title = backdrop->titlePlug()->getValue();
		if( title.size() )
		{
			Box3f titleBound = style->textBound( Style::HeadingText, title );
			glPushMatrix();
				glTranslatef( bound.center().x - titleBound.size().x / 2.0f, titleBaseline, 0.0f );
				style->renderText( Style::HeadingText, title );
			glPopMatrix();
		}

		if( m_hovered )
		{
			style->renderHorizontalRule(
				V2f( bound.center().x, titleBaseline - g_margin / 2.0f ),
				bound.size().x - g_margin * 2.0f,
				Style::HighlightedState
			);
		}

		Box2f textBound = bound;
		textBound.min += V2f( g_margin );
		textBound.max = V2f( textBound.max.x - g_margin, titleBaseline - g_margin );
		if( textBound.hasVolume() )
		{
			std::string description = backdrop->descriptionPlug()->getValue();
			style->renderWrappedText( Style::BodyText, description, textBound );
		}
	}
	
	glPopMatrix();
}
Exemple #5
0
MeshPrimitivePtr MeshPrimitive::createPlane( const Box2f &b, const Imath::V2i &divisions )
{
    V3fVectorDataPtr pData = new V3fVectorData;
    std::vector<V3f> &p = pData->writable();

    // add vertices
    float xStep = b.size().x / (float)divisions.x;
    float yStep = b.size().y / (float)divisions.y;
    for ( int i = 0; i <= divisions.y; ++i )
    {
        for ( int j = 0; j <= divisions.x; ++j )
        {
            p.push_back( V3f( b.min.x + j * xStep, b.min.y + i * yStep, 0 ) );
        }
    }

    IntVectorDataPtr vertexIds = new IntVectorData;
    IntVectorDataPtr verticesPerFace = new IntVectorData;
    std::vector<int> &vpf = verticesPerFace->writable();
    std::vector<int> &vIds = vertexIds->writable();

    FloatVectorDataPtr sData = new FloatVectorData;
    FloatVectorDataPtr tData = new FloatVectorData;
    std::vector<float> &s = sData->writable();
    std::vector<float> &t = tData->writable();

    float sStep = 1.0f / (float)divisions.x;
    float tStep = 1.0f / (float)divisions.y;

    // add faces
    int v0, v1, v2, v3;
    for ( int i = 0; i < divisions.y; ++i )
    {
        for ( int j = 0; j < divisions.x; ++j )
        {
            v0 = j + (divisions.x+1) * i;
            v1 = j + 1 + (divisions.x+1) * i;;
            v2 = j + 1 + (divisions.x+1) * (i+1);
            v3 = j + (divisions.x+1) * (i+1);

            vpf.push_back( 4 );
            vIds.push_back( v0 );
            vIds.push_back( v1 );
            vIds.push_back( v2 );
            vIds.push_back( v3 );

            s.push_back( j * sStep );
            s.push_back( (j+1) * sStep );
            s.push_back( (j+1) * sStep );
            s.push_back( j * sStep );

            t.push_back( 1 - i * tStep );
            t.push_back( 1 - i * tStep );
            t.push_back( 1 - (i+1) * tStep );
            t.push_back( 1 - (i+1) * tStep );
        }
    }

    MeshPrimitivePtr result = new MeshPrimitive( verticesPerFace, vertexIds, "linear", pData );
    result->variables["s"] = PrimitiveVariable( PrimitiveVariable::FaceVarying, sData );
    result->variables["t"] = PrimitiveVariable( PrimitiveVariable::FaceVarying, tData );

    return result;
}
void TexViewerModule::draw(Box2f viewport, Box2f screen_viewport, float scale, unsigned int recurse) {

	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glBoxToBox(viewport, screen_viewport);

	Vector2f s = size();
	glBegin(GL_QUADS);
	glColor3f(0.0f, 0.0f, 0.0f);
	glVertex2f(-0.5f*s.x, -0.5f*s.y);
	glVertex2f( 0.5f*s.x, -0.5f*s.y);
	glVertex2f( 0.5f*s.x,  0.5f*s.y);
	glVertex2f(-0.5f*s.x,  0.5f*s.y);
	glEnd();

	if (tex_out().tex != 0) {

		glDisable(GL_BLEND);
		glUseProgramObjectARB(scale_bias_shader->handle);
		glUniform1fARB(glGetUniformLocationARB(scale_bias_shader->handle, "scale"), 1.0f);
		glUniform1fARB(glGetUniformLocationARB(scale_bias_shader->handle, "bias"), 0.5f);
		glColor3f(1.0f, 1.0f, 1.0f);

		glEnable(GL_TEXTURE_RECTANGLE_ARB);
		glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex_out().tex);
		#ifdef ATI_HACK
		set_nearest();
		#else
		set_linear(); //no ATI_HACK
		#endif
		float px_size = 2.0f / Graphics::screen_y * viewport.size().x / screen_viewport.size().x * tex_out().height / size().y;
		glBegin(GL_QUADS);
		glColor3f(0.0f, 0.0f, 0.0f);
		glTexCoord2f(0-0.5f * px_size, 0-0.5f * px_size);
		glMultiTexCoord2f(GL_TEXTURE1_ARB, 0+0.5f * px_size, 0+0.5f * px_size);
		if (rotate) {
			glVertex2f(-0.5f*s.x, -0.5f*s.y);
		} else {
			glVertex2f(-0.5f*s.x,  0.5f*s.y);
		}

		glTexCoord2f(tex_out().width-0.5f * px_size, 0-0.5f * px_size);
		glMultiTexCoord2f(GL_TEXTURE1_ARB, tex_out().width+0.5f * px_size, 0+0.5f * px_size);

		if (rotate) {
			glVertex2f(-0.5f*s.x,  0.5f*s.y);
		} else {
			glVertex2f( 0.5f*s.x,  0.5f*s.y);
		}

		glTexCoord2f(tex_out().width-0.5f * px_size, tex_out().height-0.5f * px_size);
		glMultiTexCoord2f(GL_TEXTURE1_ARB, tex_out().width+0.5f * px_size, tex_out().height+0.5f * px_size);

		if (rotate) {
			glVertex2f( 0.5f*s.x,  0.5f*s.y);
		} else {
			glVertex2f( 0.5f*s.x, -0.5f*s.y);
		}

		glTexCoord2f(0-0.5f * px_size, tex_out().height-0.5f * px_size);

		glMultiTexCoord2f(GL_TEXTURE1_ARB, 0+0.5f * px_size, tex_out().height+0.5f * px_size);

		if (rotate) {
			glVertex2f( 0.5f*s.x, -0.5f*s.y);
		} else {
			glVertex2f(-0.5f*s.x, -0.5f*s.y);
		}
		glEnd();
		glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
		glDisable(GL_TEXTURE_RECTANGLE_ARB);

		glUseProgramObjectARB(0);
		glEnable(GL_BLEND);
	} else {
		glBegin(GL_LINES);
		glColor3f(1.0f, 0.0f, 0.0f);
		glVertex2f(-0.4f*s.x, -0.4f*s.y);
		glVertex2f( 0.4f*s.x,  0.4f*s.y);
		glVertex2f( 0.4f*s.x, -0.4f*s.y);
		glVertex2f(-0.4f*s.x,  0.4f*s.y);
		glEnd();
	}

	glBegin(GL_LINE_LOOP);
	glColor3f(1.0f, 1.0f, 1.0f);
	glVertex2f(-0.5f*s.x, -0.5f*s.y);
	glVertex2f( 0.5f*s.x, -0.5f*s.y);
	glVertex2f( 0.5f*s.x,  0.5f*s.y);
	glVertex2f(-0.5f*s.x,  0.5f*s.y);
	glEnd();

	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);
	Graphics::gl_errors("TexViewer::draw");

}
Exemple #7
0
void LayersDialog::draw(Box2f viewport, Box2f screen_viewport, float scale, unsigned int recurse) {

	if (!subpixel_shader.ref) {
		Graphics::ShaderObjectRef frag = Graphics::get_shader_object("ll_shaders/ll_subpixel.glsl", GL_FRAGMENT_SHADER_ARB);
		assert(frag.ref);
		subpixel_shader = Graphics::get_program_object(frag);
		assert(subpixel_shader.ref);
		glUseProgramObjectARB(subpixel_shader->handle);
		glUniform1iARB(glGetUniformLocationARB(subpixel_shader->handle, "image"), 0);
		glUseProgramObjectARB(0);
	}


	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glBoxToBox(viewport, screen_viewport);
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();

	glBegin(GL_QUADS);
	glColor3f(0.4f, 0.2f, 0.2f);
	glVertex2f(-size().x*0.5f, -size().y*0.5f);
	glVertex2f( size().x*0.5f, -size().y*0.5f);
	glVertex2f( size().x*0.5f,  size().y*0.5f);
	glVertex2f(-size().x*0.5f,  size().y*0.5f);
	glEnd();

	if (!layering()) {
		glMatrixMode(GL_PROJECTION);
		glPopMatrix();
		glMatrixMode(GL_MODELVIEW);
		glPopMatrix();
		return;
	}

	vector< DialogBin > const &bins = layering()->bins;
	const float dialog_tween = layering()->dialog_tween;
	const unsigned int width = layering()->width;
	const unsigned int height = layering()->height;
	vector< GLuint > const &textures = layering()->textures;

	for (unsigned int b = 0; b < bins.size(); ++b) {
		float alpha = bins[b].active?1.0f:0.3f;
		Box2f box = bins[b].get_box(dialog_tween);
		glBegin(GL_QUADS);
		glColor4f(0.5f, 0.5f, 0.6f, alpha * 0.8f);
		glVertex2f(box.min.x, box.min.y);
		glVertex2f(box.max.x, box.min.y);
		glColor4f(0.9f, 0.85f, 0.83f, alpha * 0.8f);
		glVertex2f(box.max.x, box.max.y);
		glVertex2f(box.min.x, box.max.y);
		glEnd();
		Box2f tex = bins[b].get_tex_box(dialog_tween);
		Vector3f show = bins[b].get_show(dialog_tween, make_vector(width * 0.5f, height * 0.5f, width * 0.5f));
		show += bins[b].zoom_out * (make_vector(0.5f * width, 0.5f * height, 0.5f * width) - show);
		if (bins[b].layer < textures.size()) {
			float px_size = 2.0f / Graphics::screen_y * viewport.size().x / screen_viewport.size().x * show.z / (tex.max.y - tex.min.y);

			glUseProgramObjectARB(subpixel_shader->handle);
			glUniform1fARB(glGetUniformLocationARB(subpixel_shader->handle, "px_size"), px_size);

			glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textures[bins[b].layer]);
		}
		glColor4f(1.0f, 1.0f, 1.0f, alpha);
		glBegin(GL_QUADS);
		glTexCoord2f(show.x-show.z,show.y-show.z);
		glVertex2f(tex.min.x, tex.min.y);
		glTexCoord2f(show.x+show.z,show.y-show.z);
		glVertex2f(tex.max.x, tex.min.y);
		glTexCoord2f(show.x+show.z,show.y+show.z);
		glVertex2f(tex.max.x, tex.max.y);
		glTexCoord2f(show.x-show.z,show.y+show.z);
		glVertex2f(tex.min.x, tex.max.y);
		glEnd();
		glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
		glUseProgramObjectARB(0);

		//arrows:
		float s = box.size().y * (1.0f / 3.0f);
		glEnable(GL_POLYGON_SMOOTH);
		glBegin(GL_TRIANGLES);
		glColor4f(1.0f, 1.0f, 1.0f, 0.5f * alpha * bins[b].arrows);
		glVertex2f(box.max.x - s * 1.5f, box.max.y - 0.25 * s);
		glVertex2f(box.max.x - s * 0.75f, box.max.y - 1.25 * s);
		glVertex2f(box.max.x - s * 2.25f, box.max.y - 1.25 * s);

		glVertex2f(box.max.x - s * 1.5f, box.min.y + 0.25 * s);
		glVertex2f(box.max.x - s * 0.75f, box.min.y + 1.25 * s);
		glVertex2f(box.max.x - s * 2.25f, box.min.y + 1.25 * s);
		glEnd();
		glDisable(GL_POLYGON_SMOOTH);
		glBegin(GL_LINES);
		glColor4f(1.0f, 1.0f, 1.0f, 0.5f * alpha * bins[b].arrows);
		glVertex2f(tex.max.x + box.size().x * 0.05f, box.center().y);
		glVertex2f(box.max.x - box.size().x * 0.05f, box.center().y);
		glEnd();
	}

	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();

}