* rewrite and fix 2d background image feature; fix bug on intels (glPushAttrib)

This commit is contained in:
Garux 2018-08-28 23:58:02 +03:00
parent 1f4143ece2
commit e7fec22b52
3 changed files with 140 additions and 111 deletions

View File

@ -2249,7 +2249,7 @@ GtkMenuItem* create_misc_menu(){
create_menu_item_with_mnemonic( menu, "Map Info...", "MapInfo" );
// http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=394
// create_menu_item_with_mnemonic(menu, "_Print XY View", FreeCaller<WXY_Print>());
create_menu_item_with_mnemonic( menu, "_Background image...", FreeCaller<WXY_BackgroundSelect>() );
create_menu_item_with_mnemonic( menu, "Set 2D _Background image...", FreeCaller<WXY_SetBackgroundImage>() );
create_menu_item_with_mnemonic( menu, "Fullscreen", "Fullscreen" );
create_menu_item_with_mnemonic( menu, "Maximize view", "MaximizeView" );
return misc_menu_item;

View File

@ -625,13 +625,6 @@ XYWnd::XYWnd() :
m_fScale = 1;
m_viewType = XY;
m_backgroundActivated = false;
m_alpha = 1.0f;
m_xmin = 0.0f;
m_ymin = 0.0f;
m_xmax = 0.0f;
m_ymax = 0.0f;
m_entityCreate = false;
m_mnuDrop = 0;
@ -1263,73 +1256,127 @@ void XYWnd::XY_SnapToGrid( Vector3& point ){
}
}
void XYWnd::XY_LoadBackgroundImage( const char *name ){
const char* relative = path_make_relative( name, GlobalFileSystem().findRoot( name ) );
if ( relative == name ) {
void BackgroundImage::render( const VIEWTYPE viewtype ){
if( viewtype == _viewtype && _tex > 0 ){
// glPushAttrib( GL_ALL_ATTRIB_BITS ); //bug with intel
if ( GlobalOpenGL().GL_1_3() ) {
glActiveTexture( GL_TEXTURE0 );
glClientActiveTexture( GL_TEXTURE0 );
}
glEnable( GL_TEXTURE_2D );
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
// glPolygonMode( GL_FRONT, GL_FILL );
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
glDisable( GL_CULL_FACE );
glDisable( GL_DEPTH_TEST );
glBindTexture( GL_TEXTURE_2D, _tex );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
glBegin( GL_QUADS );
glColor4f( 1, 1, 1, _alpha );
glTexCoord2f( 0, 1 );
glVertex2f( _xmin, _ymin );
glTexCoord2f( 1, 1 );
glVertex2f( _xmax, _ymin );
glTexCoord2f( 1, 0 );
glVertex2f( _xmax, _ymax );
glTexCoord2f( 0, 0 );
glVertex2f( _xmin, _ymax );
glEnd();
glBindTexture( GL_TEXTURE_2D, 0 );
// glPopAttrib();
}
}
#include "qe3.h"
#include "os/file.h"
const char* BackgroundImage::background_image_dialog(){
StringOutputStream buffer( 1024 );
buffer << g_qeglobals.m_userGamePath.c_str() << "textures/";
if ( !file_readable( buffer.c_str() ) ) {
// just go to fsmain
buffer.clear();
buffer << g_qeglobals.m_userGamePath.c_str() << "/";
}
const char *filename = file_dialog( GTK_WIDGET( MainFrame_getWindow() ), TRUE, "Background Image", buffer.c_str(), NULL );
if ( filename != 0 ) {
// use VFS to get the correct relative path
const char* relative = path_make_relative( filename, GlobalFileSystem().findRoot( filename ) );
if ( relative == filename ) {
globalWarningStream() << "WARNING: could not extract the relative path, using full path instead\n";
}
char fileNameWithoutExt[512];
strncpy( fileNameWithoutExt, relative, sizeof( fileNameWithoutExt ) - 1 );
fileNameWithoutExt[512 - 1] = '\0';
fileNameWithoutExt[strlen( fileNameWithoutExt ) - 4] = '\0';
Image *image = QERApp_LoadImage( 0, fileNameWithoutExt );
if ( !image ) {
globalErrorStream() << "Could not load texture " << fileNameWithoutExt << "\n";
return;
return relative;
}
g_pParentWnd->ActiveXY()->m_tex = (qtexture_t*)malloc( sizeof( qtexture_t ) );
LoadTextureRGBA( g_pParentWnd->ActiveXY()->XYWnd::m_tex, image->getRGBAPixels(), image->getWidth(), image->getHeight() );
globalOutputStream() << "Loaded background texture " << relative << "\n";
g_pParentWnd->ActiveXY()->m_backgroundActivated = true;
int m_ix, m_iy;
switch ( g_pParentWnd->ActiveXY()->m_viewType )
{
case XY:
m_ix = 0;
m_iy = 1;
break;
case XZ:
m_ix = 0;
m_iy = 2;
break;
default: //case YZ:
m_ix = 1;
m_iy = 2;
break;
return 0;
}
Vector3 min, max;
Select_GetBounds( min, max );
g_pParentWnd->ActiveXY()->m_xmin = min[m_ix];
g_pParentWnd->ActiveXY()->m_ymin = min[m_iy];
g_pParentWnd->ActiveXY()->m_xmax = max[m_ix];
g_pParentWnd->ActiveXY()->m_ymax = max[m_iy];
void BackgroundImage::free_tex(){
if( _tex > 0 ){
glDeleteTextures( 1, &_tex );
_tex = 0;
}
}
void XYWnd::XY_DisableBackground( void ){
g_pParentWnd->ActiveXY()->m_backgroundActivated = false;
if ( g_pParentWnd->ActiveXY()->m_tex ) {
free( g_pParentWnd->ActiveXY()->m_tex );
}
g_pParentWnd->ActiveXY()->m_tex = NULL;
}
void WXY_BackgroundSelect( void ){
bool brushesSelected = Scene_countSelectedBrushes( GlobalSceneGraph() ) != 0;
if ( !brushesSelected ) {
gtk_MessageBox( 0, "You have to select some brushes to get the bounding box for.\n",
void BackgroundImage::set( const VIEWTYPE viewtype ){
const AABB bounds = GlobalSelectionSystem().getBoundsSelected();
const int nDim1 = ( viewtype == YZ ) ? 1 : 0;
const int nDim2 = ( viewtype == XY ) ? 1 : 2;
if( !( bounds.extents[nDim1] > 0 && bounds.extents[nDim2] > 0 ) ){
gtk_MessageBox( GTK_WIDGET( MainFrame_getWindow() ), "Select some objects to get the bounding box for image.\n",
"No selection", eMB_OK, eMB_ICONERROR );
return;
}
else{
free_tex();
const char *filename = background_image_dialog();
if( filename ){
StringOutputStream filename_noext( 1024 );
const char* ext = path_get_extension( filename );
if( string_empty( ext ) )
filename_noext << filename;
else
filename_noext << StringRange( filename, ext - 1 );
Image *image = QERApp_LoadImage( 0, filename_noext.c_str() );
if ( !image ) {
globalErrorStream() << "Could not load texture " << filename_noext.c_str() << "\n";
}
else{
qtexture_t* qtex = (qtexture_t*)malloc( sizeof( qtexture_t ) ); /* srs hack :E */
LoadTextureRGBA( qtex, image->getRGBAPixels(), image->getWidth(), image->getHeight() );
if( qtex->texture_number > 0 ){
globalOutputStream() << "Loaded background texture " << filename << "\n";
_tex = qtex->texture_number;
_viewtype = viewtype;
_xmin = bounds.origin[nDim1] - bounds.extents[nDim1];
_ymin = bounds.origin[nDim2] - bounds.extents[nDim2];
_xmax = bounds.origin[nDim1] + bounds.extents[nDim1];
_ymax = bounds.origin[nDim2] + bounds.extents[nDim2];
}
image->release();
free( qtex );
}
}
}
}
const char *filename = file_dialog( GTK_WIDGET( MainFrame_getWindow() ), TRUE, "Background Image", NULL, NULL );
g_pParentWnd->ActiveXY()->XY_DisableBackground();
if ( filename ) {
g_pParentWnd->ActiveXY()->XY_LoadBackgroundImage( filename );
}
void WXY_SetBackgroundImage(){
g_pParentWnd->ActiveXY()->setBackgroundImage();
}
/*
@ -1498,40 +1545,6 @@ void XYWnd::RenderActive( void ){
}
}
void XYWnd::XY_DrawBackground( void ){
glPushAttrib( GL_ALL_ATTRIB_BITS );
glEnable( GL_TEXTURE_2D );
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
glPolygonMode( GL_FRONT, GL_FILL );
glBindTexture( GL_TEXTURE_2D, m_tex->texture_number );
glBegin( GL_QUADS );
glColor4f( 1.0, 1.0, 1.0, m_alpha );
glTexCoord2f( 0.0, 1.0 );
glVertex2f( m_xmin, m_ymin );
glTexCoord2f( 1.0, 1.0 );
glVertex2f( m_xmax, m_ymin );
glTexCoord2f( 1.0, 0.0 );
glVertex2f( m_xmax, m_ymax );
glTexCoord2f( 0.0, 0.0 );
glVertex2f( m_xmin, m_ymax );
glEnd();
glBindTexture( GL_TEXTURE_2D, 0 );
glPopAttrib();
}
void XYWnd::XY_DrawGrid( void ) {
float x, y, xb, xe, yb, ye;
float w, h, a;
@ -2285,9 +2298,8 @@ void XYWnd::XY_Draw(){
glDisable( GL_COLOR_MATERIAL );
glDisable( GL_DEPTH_TEST );
if ( m_backgroundActivated ) {
XY_DrawBackground();
}
m_backgroundImage.render( m_viewType );
XY_DrawGrid();
if ( g_xywindow_globals_private.show_blocks ) {

View File

@ -58,6 +58,25 @@ inline const char* ViewType_getTitle( VIEWTYPE viewtype ){
return "";
}
class BackgroundImage
{
GLuint _tex;
const float _alpha;
float _xmin, _ymin, _xmax, _ymax;
VIEWTYPE _viewtype;
public:
BackgroundImage() : _tex( 0 ), _alpha( 1 ){
}
~BackgroundImage(){
free_tex();
}
void set( const VIEWTYPE viewtype );
void render( const VIEWTYPE viewtype );
private:
const char* background_image_dialog();
void free_tex();
};
#include "timer.h"
class FBO;
@ -107,9 +126,6 @@ void DrawCameraIcon( const Vector3& origin, const Vector3& angles );
void XY_DrawBlockGrid();
void XY_DrawAxis();
void XY_DrawGrid();
void XY_DrawBackground();
void XY_LoadBackgroundImage( const char *name );
void XY_DisableBackground();
void XY_MouseUp( int x, int y, unsigned int buttons );
void XY_MouseDown( int x, int y, unsigned int buttons );
@ -170,12 +186,13 @@ Matrix4 m_modelview;
int m_nWidth;
int m_nHeight;
// background image stuff
qtexture_t *m_tex;
bool m_backgroundActivated;
float m_alpha; // vertex alpha
float m_xmin, m_ymin, m_xmax, m_ymax;
void setBackgroundImage(){
m_backgroundImage.set( m_viewType );
}
private:
BackgroundImage m_backgroundImage;
float m_fScale;
Vector3 m_vOrigin;
@ -302,7 +319,7 @@ void XYWindow_Construct();
void XYWindow_Destroy();
void WXY_Print();
void WXY_BackgroundSelect();
void WXY_SetBackgroundImage();
void XYShow_registerCommands();
void XYWnd_registerShortcuts();