* merged background images back into 1.5 branch

* fixed warnings and bugs (nDim)


git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/branches/1.5@315 8a3a26a2-13c4-0310-b231-cf6edde360e5
This commit is contained in:
mattn 2008-08-26 06:11:47 +00:00
parent 58f2e361fc
commit 2abefddf8a
3 changed files with 341 additions and 217 deletions

View file

@ -2242,7 +2242,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 select", FreeCaller<WXY_BackgroundSelect>());
return misc_menu_item;
}

View file

@ -33,6 +33,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "igl.h"
#include "ibrush.h"
#include "iundo.h"
#include "iimage.h"
#include "ifilesystem.h"
#include "os/path.h"
#include "image.h"
#include "gtkutil/messagebox.h"
#include <gtk/gtklabel.h>
#include <gtk/gtkmenuitem.h>
@ -50,6 +55,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "gtkutil/container.h"
#include "gtkutil/widget.h"
#include "gtkutil/glwidget.h"
#include "gtkutil/filechooser.h"
#include "gtkmisc.h"
#include "select.h"
#include "csg.h"
@ -65,6 +71,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "grid.h"
#include "windowobservers.h"
void LoadTextureRGBA(qtexture_t* q, unsigned char* pPixels, int nWidth, int nHeight);
// d1223m
extern bool g_brush_always_caulk;
@ -850,6 +857,13 @@ 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;
@ -950,7 +964,7 @@ void XYWnd::DropClipPoint(int pointx, int pointy)
Vector3 mid;
Select_GetMid(mid);
g_clip_viewtype = static_cast<VIEWTYPE>(GetViewType());
int nDim = (g_clip_viewtype == YZ ) ? nDim = 0 : ( (g_clip_viewtype == XZ) ? nDim = 1 : nDim = 2 );
const int nDim = (g_clip_viewtype == YZ ) ? 0 : ( (g_clip_viewtype == XZ) ? 1 : 2 );
point[nDim] = mid[nDim];
vector3_snap(point, GetGridSize());
NewClipPoint(point);
@ -1556,6 +1570,75 @@ 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)
globalOutputStream() << "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) {
globalOutputStream() << "Could not load texture " << fileNameWithoutExt << "\n";
return;
}
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;
case YZ:
m_ix = 1;
m_iy = 2;
break;
}
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 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",
"No selection", eMB_OK, eMB_ICONERROR);
return;
}
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);
}
/*
============================================================================
@ -1575,155 +1658,14 @@ double two_to_the_power(int power)
return pow(2.0f, power);
}
void XYWnd::XY_DrawGrid()
void XYWnd::XY_DrawAxis(void)
{
float x, y, xb, xe, yb, ye;
float w, h;
char text[32];
float step, minor_step, stepx, stepy;
step = minor_step = stepx = stepy = GetGridSize();
int minor_power = Grid_getPower();
int mask;
while((minor_step * m_fScale) <= 4.0f) // make sure minor grid spacing is at least 4 pixels on the screen
{
++minor_power;
minor_step *= 2;
}
int power = minor_power;
while((power % 3) != 0 || (step * m_fScale) <= 32.0f) // make sure major grid spacing is at least 32 pixels on the screen
{
++power;
step = float(two_to_the_power(power));
}
mask = (1 << (power - minor_power)) - 1;
while ((stepx * m_fScale) <= 32.0f) // text step x must be at least 32
stepx *= 2;
while ((stepy * m_fScale) <= 32.0f) // text step y must be at least 32
stepy *= 2;
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_1D);
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glLineWidth(1);
w = (m_nWidth / 2 / m_fScale);
h = (m_nHeight / 2 / m_fScale);
int nDim1 = (m_viewType == YZ) ? 1 : 0;
int nDim2 = (m_viewType == XY) ? 1 : 2;
xb = m_vOrigin[nDim1] - w;
if (xb < region_mins[nDim1])
xb = region_mins[nDim1];
xb = step * floor (xb/step);
xe = m_vOrigin[nDim1] + w;
if (xe > region_maxs[nDim1])
xe = region_maxs[nDim1];
xe = step * ceil (xe/step);
yb = m_vOrigin[nDim2] - h;
if (yb < region_mins[nDim2])
yb = region_mins[nDim2];
yb = step * floor (yb/step);
ye = m_vOrigin[nDim2] + h;
if (ye > region_maxs[nDim2])
ye = region_maxs[nDim2];
ye = step * ceil (ye/step);
#define COLORS_DIFFER(a,b) \
((a)[0] != (b)[0] || \
(a)[1] != (b)[1] || \
(a)[2] != (b)[2])
// djbob
// draw minor blocks
if (g_xywindow_globals_private.d_showgrid)
{
if (COLORS_DIFFER(g_xywindow_globals.color_gridminor, g_xywindow_globals.color_gridback))
{
glColor3fv(vector3_to_array(g_xywindow_globals.color_gridminor));
glBegin (GL_LINES);
int i = 0;
for (x = xb ; x < xe ; x += minor_step, ++i)
{
if((i & mask) != 0)
{
glVertex2f (x, yb);
glVertex2f (x, ye);
}
}
i = 0;
for (y = yb ; y < ye ; y += minor_step, ++i)
{
if((i & mask) != 0)
{
glVertex2f (xb, y);
glVertex2f (xe, y);
}
}
glEnd();
}
// draw major blocks
if (COLORS_DIFFER(g_xywindow_globals.color_gridmajor, g_xywindow_globals.color_gridback))
{
glColor3fv(vector3_to_array(g_xywindow_globals.color_gridmajor));
glBegin (GL_LINES);
for (x=xb ; x<=xe ; x+=step)
{
glVertex2f (x, yb);
glVertex2f (x, ye);
}
for (y=yb ; y<=ye ; y+=step)
{
glVertex2f (xb, y);
glVertex2f (xe, y);
}
glEnd();
}
}
// draw coordinate text if needed
if ( g_xywindow_globals_private.show_coordinates)
{
glColor3fv(vector3_to_array(g_xywindow_globals.color_gridtext));
float offx = m_vOrigin[nDim2] + h - 6 / m_fScale, offy = m_vOrigin[nDim1] - w + 1 / m_fScale;
for (x = xb - fmod(xb, stepx); x <= xe ; x += stepx)
{
glRasterPos2f (x, offx);
sprintf (text, "%g", x);
GlobalOpenGL().drawString(text);
}
for (y = yb - fmod(yb, stepy); y <= ye ; y += stepy)
{
glRasterPos2f (offy, y);
sprintf (text, "%g", y);
GlobalOpenGL().drawString(text);
}
if (Active())
glColor3fv(vector3_to_array(g_xywindow_globals.color_viewname));
// we do this part (the old way) only if show_axis is disabled
if (!g_xywindow_globals_private.show_axis)
{
glRasterPos2f ( m_vOrigin[nDim1] - w + 35 / m_fScale, m_vOrigin[nDim2] + h - 20 / m_fScale );
GlobalOpenGL().drawString(ViewType_getTitle(m_viewType));
}
}
if ( g_xywindow_globals_private.show_axis)
{
if ( g_xywindow_globals_private.show_axis) {
const char g_AxisName[3] = { 'X', 'Y', 'Z' };
const int nDim1 = (m_viewType == YZ) ? 1 : 0;
const int nDim2 = (m_viewType == XY) ? 1 : 2;
const int w = (m_nWidth / 2 / m_fScale);
const int h = (m_nHeight / 2 / m_fScale);
const Vector3& colourX = (m_viewType == YZ) ? g_xywindow_globals.AxisColorY : g_xywindow_globals.AxisColorX;
const Vector3& colourY = (m_viewType == XY) ? g_xywindow_globals.AxisColorY : g_xywindow_globals.AxisColorZ;
@ -1755,13 +1697,179 @@ void XYWnd::XY_DrawGrid()
GlobalOpenGL().drawChar(g_AxisName[nDim2]);
glRasterPos2f ( -10 / m_fScale, 28 / m_fScale );
GlobalOpenGL().drawChar(g_AxisName[nDim2]);
}
}
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;
char text[32];
float step, minor_step, stepx, stepy;
step = minor_step = stepx = stepy = GetGridSize();
int minor_power = Grid_getPower();
int mask;
while ((minor_step * m_fScale) <= 4.0f) { // make sure minor grid spacing is at least 4 pixels on the screen
++minor_power;
minor_step *= 2;
}
int power = minor_power;
while ((power % 3) != 0 || (step * m_fScale) <= 32.0f) { // make sure major grid spacing is at least 32 pixels on the screen
++power;
step = float(two_to_the_power(power));
}
mask = (1 << (power - minor_power)) - 1;
while ((stepx * m_fScale) <= 32.0f) // text step x must be at least 32
stepx *= 2;
while ((stepy * m_fScale) <= 32.0f) // text step y must be at least 32
stepy *= 2;
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_1D);
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glLineWidth(1);
w = (m_nWidth / 2 / m_fScale);
h = (m_nHeight / 2 / m_fScale);
const int nDim1 = (m_viewType == YZ) ? 1 : 0;
const int nDim2 = (m_viewType == XY) ? 1 : 2;
xb = m_vOrigin[nDim1] - w;
if (xb < region_mins[nDim1])
xb = region_mins[nDim1];
xb = step * floor (xb / step);
xe = m_vOrigin[nDim1] + w;
if (xe > region_maxs[nDim1])
xe = region_maxs[nDim1];
xe = step * ceil (xe / step);
yb = m_vOrigin[nDim2] - h;
if (yb < region_mins[nDim2])
yb = region_mins[nDim2];
yb = step * floor (yb / step);
ye = m_vOrigin[nDim2] + h;
if (ye > region_maxs[nDim2])
ye = region_maxs[nDim2];
ye = step * ceil (ye / step);
#define COLORS_DIFFER(a,b) \
((a)[0] != (b)[0] || \
(a)[1] != (b)[1] || \
(a)[2] != (b)[2])
// djbob
// draw minor blocks
if (g_xywindow_globals_private.d_showgrid) {
if (COLORS_DIFFER(g_xywindow_globals.color_gridminor, g_xywindow_globals.color_gridback)) {
glColor3fv(vector3_to_array(g_xywindow_globals.color_gridminor));
glBegin (GL_LINES);
int i = 0;
for (x = xb ; x < xe ; x += minor_step, ++i) {
if ((i & mask) != 0) {
glVertex2f (x, yb);
glVertex2f (x, ye);
}
}
i = 0;
for (y = yb ; y < ye ; y += minor_step, ++i) {
if ((i & mask) != 0) {
glVertex2f (xb, y);
glVertex2f (xe, y);
}
}
glEnd();
}
// draw major blocks
if (COLORS_DIFFER(g_xywindow_globals.color_gridmajor, g_xywindow_globals.color_gridback)) {
glColor3fv(vector3_to_array(g_xywindow_globals.color_gridmajor));
glBegin (GL_LINES);
for (x = xb ; x <= xe ; x += step) {
glVertex2f (x, yb);
glVertex2f (x, ye);
}
for (y = yb ; y <= ye ; y += step) {
glVertex2f (xb, y);
glVertex2f (xe, y);
}
glEnd();
}
}
// draw coordinate text if needed
if ( g_xywindow_globals_private.show_coordinates) {
glColor3fv(vector3_to_array(g_xywindow_globals.color_gridtext));
float offx = m_vOrigin[nDim2] + h - 6 / m_fScale, offy = m_vOrigin[nDim1] - w + 1 / m_fScale;
for (x = xb - fmod(xb, stepx); x <= xe ; x += stepx) {
glRasterPos2f (x, offx);
sprintf (text, "%g", x);
GlobalOpenGL().drawString(text);
}
for (y = yb - fmod(yb, stepy); y <= ye ; y += stepy) {
glRasterPos2f (offy, y);
sprintf (text, "%g", y);
GlobalOpenGL().drawString(text);
}
if (Active())
glColor3fv(vector3_to_array(g_xywindow_globals.color_viewname));
// we do this part (the old way) only if show_axis is disabled
if (!g_xywindow_globals_private.show_axis) {
glRasterPos2f ( m_vOrigin[nDim1] - w + 35 / m_fScale, m_vOrigin[nDim2] + h - 20 / m_fScale );
GlobalOpenGL().drawString(ViewType_getTitle(m_viewType));
}
}
XYWnd::XY_DrawAxis();
// show current work zone?
// the work zone is used to place dropped points and brushes
if (g_xywindow_globals_private.d_show_work)
{
if (g_xywindow_globals_private.d_show_work) {
glColor3f( 1.0f, 0.0f, 0.0f );
glBegin( GL_LINES );
glVertex2f( xb, Select_getWorkZone().d_work_min[nDim2] );
@ -2265,7 +2373,10 @@ void XYWnd::XY_Draw()
glDisable(GL_COLOR_MATERIAL);
glDisable(GL_DEPTH_TEST);
if (m_backgroundActivated)
XY_DrawBackground();
XY_DrawGrid();
if ( g_xywindow_globals_private.show_blocks)
XY_DrawBlockGrid();

View file

@ -30,6 +30,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "gtkutil/xorrectangle.h"
#include "view.h"
#include "map.h"
#include "texturelib.h"
#include "qerplugin.h"
@ -104,7 +105,11 @@ public:
void XY_Draw();
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);
@ -162,6 +167,11 @@ public:
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;
private:
float m_fScale;
Vector3 m_vOrigin;
@ -296,6 +306,9 @@ void XZ_Front_Shown_Construct(GtkWindow* parent);
void XYWindow_Construct();
void XYWindow_Destroy();
void WXY_Print();
void WXY_BackgroundSelect();
void XYShow_registerCommands();
void XYWnd_registerShortcuts();