misc...
	* new very fast entity names rendering system
	* render entity names in cam within < 512u dist or if selected
This commit is contained in:
Garux
2017-08-02 09:36:47 +03:00
parent bec8719fe1
commit 43d4204697
16 changed files with 556 additions and 45 deletions

View File

@@ -348,7 +348,7 @@ const AABB& localAABB() const {
return m_curveBounds;
}
void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, bool selected ) const {
void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, bool selected, const AABB& childBounds ) const {
if ( isModel() && selected ) {
m_renderOrigin.render( renderer, volume, localToWorld );
}
@@ -362,10 +362,6 @@ void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& l
if ( !m_curveCatmullRom.m_renderCurve.m_vertices.empty() ) {
renderer.addRenderable( m_curveCatmullRom.m_renderCurve, localToWorld );
}
}
void renderWireframe( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, bool selected, const AABB& childBounds ) const {
renderSolid( renderer, volume, localToWorld, selected );
if ( g_showNames ) {
// draw models as usual
@@ -379,10 +375,14 @@ void renderWireframe( Renderer& renderer, const VolumeTest& volume, const Matrix
m_name_origin = childBounds.origin;
}
renderer.addRenderable( m_renderName, localToWorld );
m_renderName.render( renderer, volume, localToWorld, selected );
}
}
void renderWireframe( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, bool selected, const AABB& childBounds ) const {
renderSolid( renderer, volume, localToWorld, selected, childBounds );
}
void testSelect( Selector& selector, SelectionTest& test, SelectionIntersection& best ){
PointVertexArray_testSelect( &m_curveNURBS.m_renderCurve.m_vertices[0], m_curveNURBS.m_renderCurve.m_vertices.size(), test, best );
PointVertexArray_testSelect( &m_curveCatmullRom.m_renderCurve.m_vertices[0], m_curveCatmullRom.m_renderCurve.m_vertices.size(), test, best );
@@ -499,7 +499,7 @@ Doom3GroupInstance( const scene::Path& path, scene::Instance* parent, Doom3Group
m_contained.instanceDetach( Instance::path() );
}
void renderSolid( Renderer& renderer, const VolumeTest& volume ) const {
m_contained.renderSolid( renderer, volume, Instance::localToWorld(), getSelectable().isSelected() );
m_contained.renderSolid( renderer, volume, Instance::localToWorld(), getSelectable().isSelected(), Instance::childBounds() );
m_curveNURBS.renderComponentsSelected( renderer, volume, localToWorld() );
m_curveCatmullRom.renderComponentsSelected( renderer, volume, localToWorld() );

View File

@@ -253,12 +253,12 @@ void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& l
renderer.PopState();
}
renderer.SetState( m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly );
if ( g_showNames ) {
m_renderName.render( renderer, volume, localToWorld, selected );
}
}
void renderWireframe( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, bool selected ) const {
renderSolid( renderer, volume, localToWorld, selected );
if ( g_showNames ) {
renderer.addRenderable( m_renderName, localToWorld );
}
}
void translate( const Vector3& translation ){

View File

@@ -44,6 +44,8 @@
#include "generic.h"
#include "doom3group.h"
#include "namedentity.h"
EGameType g_gameType;
@@ -391,6 +393,7 @@ void Entity_Construct( EGameType gameType ){
Doom3Group_construct();
RenderablePivot::StaticShader::instance() = GlobalShaderCache().capture( "$PIVOT" );
RenderableNamedEntity::StaticShader::instance() = GlobalShaderCache().capture( "$TEXT" );
GlobalShaderCache().attachRenderable( StaticRenderableConnectionLines::instance() );
}
@@ -399,6 +402,7 @@ void Entity_Destroy(){
GlobalShaderCache().detachRenderable( StaticRenderableConnectionLines::instance() );
GlobalShaderCache().release( "$PIVOT" );
GlobalShaderCache().release( "$TEXT" );
Doom3Group_destroy();
MiscModel_destroy();

View File

@@ -215,17 +215,20 @@ void renderArrow( Renderer& renderer, const VolumeTest& volume, const Matrix4& l
renderer.addRenderable( m_arrow, localToWorld );
}
}
void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, bool selected ) const {
renderer.SetState( m_entity.getEntityClass().m_state_fill, Renderer::eFullMaterials );
renderer.addRenderable( m_aabb_solid, localToWorld );
renderArrow( renderer, volume, localToWorld );
if ( g_showNames ) {
m_renderName.render( renderer, volume, localToWorld, selected );
}
}
void renderWireframe( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
void renderWireframe( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, bool selected ) const {
renderer.SetState( m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly );
renderer.addRenderable( m_aabb_wire, localToWorld );
renderArrow( renderer, volume, localToWorld );
if ( g_showNames ) {
renderer.addRenderable( m_renderName, localToWorld );
m_renderName.render( renderer, volume, localToWorld, selected );
}
}
@@ -322,10 +325,10 @@ GenericEntityInstance( const scene::Path& path, scene::Instance* parent, Generic
}
void renderSolid( Renderer& renderer, const VolumeTest& volume ) const {
m_contained.renderSolid( renderer, volume, Instance::localToWorld() );
m_contained.renderSolid( renderer, volume, Instance::localToWorld(), getSelectable().isSelected() );
}
void renderWireframe( Renderer& renderer, const VolumeTest& volume ) const {
m_contained.renderWireframe( renderer, volume, Instance::localToWorld() );
m_contained.renderWireframe( renderer, volume, Instance::localToWorld(), getSelectable().isSelected() );
}
void testSelect( Selector& selector, SelectionTest& test ){

View File

@@ -148,13 +148,8 @@ void detach( scene::Traversable::Observer* observer ){
m_traverse.detach( observer );
}
void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, bool selected, const AABB& childBounds ) const {
renderer.SetState( m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly );
}
void renderWireframe( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, const AABB& childBounds ) const {
renderSolid( renderer, volume, localToWorld );
if ( g_showNames ) {
// don't draw the name for worldspawn
if ( !strcmp( m_entity.getEntityClass().name(), "worldspawn" ) ) {
@@ -164,10 +159,14 @@ void renderWireframe( Renderer& renderer, const VolumeTest& volume, const Matrix
// place name in the middle of the "children cloud"
m_name_origin = childBounds.origin;
renderer.addRenderable( m_renderName, localToWorld );
m_renderName.render( renderer, volume, localToWorld, selected );
}
}
void renderWireframe( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, bool selected, const AABB& childBounds ) const {
renderSolid( renderer, volume, localToWorld, selected, childBounds );
}
void updateTransform(){
m_transform.localToParent() = g_matrix4_identity;
matrix4_translate_by_vec3( m_transform.localToParent(), m_origin );
@@ -299,10 +298,10 @@ GroupInstance( const scene::Path& path, scene::Instance* parent, Group& group )
m_contained.instanceDetach( Instance::path() );
}
void renderSolid( Renderer& renderer, const VolumeTest& volume ) const {
m_contained.renderSolid( renderer, volume, Instance::localToWorld() );
m_contained.renderSolid( renderer, volume, Instance::localToWorld(), getSelectable().isSelected(), Instance::childBounds() );
}
void renderWireframe( Renderer& renderer, const VolumeTest& volume ) const {
m_contained.renderWireframe( renderer, volume, Instance::localToWorld(), Instance::childBounds() );
m_contained.renderWireframe( renderer, volume, Instance::localToWorld(), getSelectable().isSelected(), Instance::childBounds() );
}
STRING_CONSTANT( Name, "GroupInstance" );

View File

@@ -1408,12 +1408,13 @@ void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& l
renderer.addRenderable( m_render_center, localToWorld );
}
}
if ( g_showNames && !string_equal( m_named.name(), "light" ) ) {
m_renderName.render( renderer, volume, localToWorld, selected );
}
}
void renderWireframe( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, bool selected ) const {
renderSolid( renderer, volume, localToWorld, selected );
if ( g_showNames && !string_equal( m_named.name(), "light" ) ) {
renderer.addRenderable( m_renderName, localToWorld );
}
}
void testSelect( Selector& selector, SelectionTest& test, const Matrix4& localToWorld ){

View File

@@ -194,14 +194,13 @@ void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& l
if ( selected ) {
m_renderOrigin.render( renderer, volume, localToWorld );
}
renderer.SetState( m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly );
if ( g_showNames && !string_equal( m_named.name(), "misc_model" ) ) {
m_renderName.render( renderer, volume, localToWorld, selected );
}
}
void renderWireframe( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, bool selected ) const {
renderSolid( renderer, volume, localToWorld, selected );
if ( g_showNames && !string_equal( m_named.name(), "misc_model" ) ) {
renderer.addRenderable( m_renderName, localToWorld );
}
}
void translate( const Vector3& translation ){

View File

@@ -66,6 +66,9 @@ const char* name() const {
const char* classname() const {
return m_entity.getEntityClass().name();
}
const Colour3& color() const {
return m_entity.getEntityClass().color;
}
void attach( const NameCallback& callback ){
m_changed.insert( callback );
}
@@ -86,6 +89,182 @@ void identifierChanged( const char* value ){
typedef MemberCaller1<NamedEntity, const char*, &NamedEntity::identifierChanged> IdentifierChangedCaller;
};
#include "renderable.h"
#include "pivot.h"
#include "math/frustum.h"
class RenderableNamedEntity : public OpenGLRenderable {
NamedEntity& m_named;
const Vector3& m_position;
mutable GLuint m_tex_normal;
mutable GLuint m_tex_selected;
mutable GLuint* m_tex;
int m_width;
int m_height;
unsigned int m_colour[3];
mutable float m_screenPos[2];
public:
typedef Static<Shader*, RenderableNamedEntity> StaticShader;
static Shader* getShader() {
return StaticShader::instance();
}
RenderableNamedEntity( NamedEntity& named, const Vector3& position )
: m_named( named ), m_position( position ), m_tex_normal( 0 ), m_tex_selected( 0 ) {
construct_textures( g_showTargetNames ? m_named.name() : m_named.classname() );
m_named.attach( IdentifierChangedCaller( *this ) );
}
private:
void setSelected( bool selected ) const {
m_tex = selected ? &m_tex_selected : &m_tex_normal;
}
void setSelectedColour( bool selected ){
if( selected ){
m_colour[0] = 255;
m_colour[1] = 255;
m_colour[2] = 0;
}
else{
m_colour[0] = static_cast<unsigned int>( m_named.color()[0] * 255.f );
m_colour[1] = static_cast<unsigned int>( m_named.color()[1] * 255.f );
m_colour[2] = static_cast<unsigned int>( m_named.color()[2] * 255.f );
}
}
void construct_texture( const char* name ){
glGenTextures( 1, m_tex );
if( *m_tex > 0 ) {
GlobalOpenGL().m_font->renderString( name, *m_tex, m_colour, m_width, m_height );
}
}
void construct_textures( const char* name ){
setSelected( false );
setSelectedColour( false );
construct_texture( name );
setSelected( true );
setSelectedColour( true );
construct_texture( name );
}
void delete_textures(){
glDeleteTextures( 1, &m_tex_normal );
glDeleteTextures( 1, &m_tex_selected );
m_tex_normal = 0;
m_tex_selected = 0;
}
public:
void render( RenderStateFlags state ) const {
if( *m_tex > 0 ){
glBindTexture( GL_TEXTURE_2D, *m_tex );
//Here we draw the texturemaped quads.
//The bitmap that we got from FreeType was not
//oriented quite like we would like it to be,
//so we need to link the texture to the quad
//so that the result will be properly aligned.
glBegin( GL_QUADS );
glTexCoord2i( 0, 1 );
glVertex2f( m_screenPos[0], m_screenPos[1] );
glTexCoord2i( 0, 0 );
glVertex2f( m_screenPos[0], m_screenPos[1] + m_height + .01f );
glTexCoord2i( 1, 0 );
glVertex2f( m_screenPos[0] + m_width + .01f, m_screenPos[1] + m_height + .01f );
glTexCoord2i( 1, 1 );
glVertex2f( m_screenPos[0] + m_width + .01f, m_screenPos[1] );
glEnd();
glBindTexture( GL_TEXTURE_2D, 0 );
}
}
void render( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, bool selected ) const{
if( !selected && volume.fill() ){
// globalOutputStream() << localToWorld << " localToWorld\n";
// globalOutputStream() << volume.GetModelview() << " modelview\n";
// globalOutputStream() << volume.GetProjection() << " Projection\n";
// globalOutputStream() << volume.GetViewport() << " Viewport\n";
Matrix4 viewproj = matrix4_multiplied_by_matrix4( volume.GetProjection(), volume.GetModelview() );
Vector3 viewer = vector4_to_vector3( viewer_from_viewproj( viewproj ) );
Vector3 pos_in_world = matrix4_transformed_point( localToWorld, m_position );
if( vector3_length_squared( pos_in_world - viewer ) > 512*512 ){
return;
}
//globalOutputStream() << viewer[0] << " " << viewer[1] << " " << viewer[2] << " Viewer\n";
//globalOutputStream() << pos_in_world[0] << " " << pos_in_world[1] << " " << pos_in_world[2] << " position\n";
//globalOutputStream() << m_position[0] << " " << m_position[1] << " " << m_position[2] << " position\n";
}
setSelected( selected );
Vector4 position;
position[0] = m_position[0];
position[1] = m_position[1];
position[2] = m_position[2];
position[3] = 1.f;
#if 0
// globalOutputStream() << position[0] << " " << position[1] << " " << position[2] << " " << position[3] << " position\n";
matrix4_transform_vector4( localToWorld, position );
// globalOutputStream() << position[0] << " " << position[1] << " " << position[2] << " " << position[3] << " localToWorld\n";
matrix4_transform_vector4( volume.GetModelview(), position );
// globalOutputStream() << position[0] << " " << position[1] << " " << position[2] << " " << position[3] << " Modelview\n";
matrix4_transform_vector4( volume.GetProjection(), position );
// globalOutputStream() << position[0] << " " << position[1] << " " << position[2] << " " << position[3] << " Projection\n";
position[0] /= position[3];
position[1] /= position[3];
position[2] /= position[3];
// globalOutputStream() << position[0] << " " << position[1] << " " << position[2] << " " << position[3] << " Projection division\n";
matrix4_transform_vector4( volume.GetViewport(), position );
// globalOutputStream() << position[0] << " " << position[1] << " " << position[2] << " " << position[3] << " Viewport\n";
#else
Matrix4 object2screen = volume.GetProjection();
matrix4_multiply_by_matrix4( object2screen, volume.GetModelview() );
matrix4_multiply_by_matrix4( object2screen, localToWorld );
// globalOutputStream() << position[0] << " " << position[1] << " " << position[2] << " " << position[3] << " position\n";
matrix4_transform_vector4( object2screen, position );
// globalOutputStream() << position[0] << " " << position[1] << " " << position[2] << " " << position[3] << " Projection\n";
position[0] /= position[3];
position[1] /= position[3];
position[2] /= position[3];
// globalOutputStream() << position[0] << " " << position[1] << " " << position[2] << " " << position[3] << " Projection division\n";
matrix4_transform_vector4( volume.GetViewport(), position );
// globalOutputStream() << position[0] << " " << position[1] << " " << position[2] << " " << position[3] << " Viewport\n";
#endif
//globalOutputStream() << volume.GetViewport()[0] << " " << volume.GetViewport()[5] << " Viewport size\n";
m_screenPos[0] = position[0];
m_screenPos[1] = position[1];
//globalOutputStream() << m_screenPos[0] << " " << m_screenPos[1] << "\n";
renderer.PushState();
// Pivot2World_viewplaneSpace( m_localToWorld, localToWorld, volume.GetModelview(), volume.GetProjection(), volume.GetViewport() );
renderer.Highlight( Renderer::ePrimitive, false );
renderer.Highlight( Renderer::eFace, false );
renderer.SetState( getShader(), Renderer::eWireframeOnly );
renderer.SetState( getShader(), Renderer::eFullMaterials );
// m_localToWorld = volume.GetViewport();
// matrix4_full_invert( m_localToWorld );
renderer.addRenderable( *this, g_matrix4_identity );
renderer.PopState();
}
~RenderableNamedEntity(){
m_named.detach( IdentifierChangedCaller( *this ) );
delete_textures();
}
void identifierChanged( const char* value ){
delete_textures();
construct_textures( g_showTargetNames ? value : m_named.classname() );
}
typedef MemberCaller1<RenderableNamedEntity, const char*, &RenderableNamedEntity::identifierChanged> IdentifierChangedCaller;
};
/*
class RenderableNamedEntity : public OpenGLRenderable
{
const NamedEntity& m_named;
@@ -99,7 +278,7 @@ void render( RenderStateFlags state ) const {
GlobalOpenGL().drawString( g_showTargetNames ? m_named.name() : m_named.classname() );
}
};
*/
#endif