2 Copyright (C) 2003 Reed Mideke.
4 This file is part of GtkRadiant.
6 GtkRadiant is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 GtkRadiant is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GtkRadiant; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 // Code by reyalP aka Reed Mideke
26 // Based on various other plugins
31 CBackgroundRender render;
33 CBackgroundImage backgroundXY(XY), backgroundXZ(XZ), backgroundYZ(YZ);
35 CBackgroundRender::CBackgroundRender()
40 CBackgroundRender::~CBackgroundRender()
44 void CBackgroundRender::Register()
46 g_QglTable.m_pfnHookGL2DWindow(this);
49 void CBackgroundRender::Draw2D(VIEWTYPE vt)
53 backgroundXY.Render();
56 backgroundXZ.Render();
59 backgroundYZ.Render();
65 CBackgroundImage::CBackgroundImage(VIEWTYPE vt)
70 // TODO, sensible defaults ? Or not show until we have extents ?
71 m_xmin = m_ymin = 0.0f;
72 m_xmax = m_ymax = 0.0f;
95 * should cleanup, but I don't think we can be sure it happens before our
97 CBackgroundImage::~CBackgroundImage()
102 void CBackgroundImage::Cleanup()
105 g_QglTable.m_pfn_qglDeleteTextures(1, &m_tex->texture_number);
111 void CBackgroundImage::Render()
113 if (!m_bActive || !Valid()) {
116 g_QglTable.m_pfn_qglPushAttrib(GL_ALL_ATTRIB_BITS);
118 g_QglTable.m_pfn_qglEnable(GL_TEXTURE_2D);
119 g_QglTable.m_pfn_qglEnable(GL_BLEND);
120 g_QglTable.m_pfn_qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
121 g_QglTable.m_pfn_qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
122 g_QglTable.m_pfn_qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
123 g_QglTable.m_pfn_qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
125 g_QglTable.m_pfn_qglPolygonMode(GL_FRONT, GL_FILL);
126 // TODO, just so we can tell if we end up going the wrong way
127 // g_QglTable.m_pfn_qglPolygonMode(GL_BACK,GL_LINE);
128 // TODO any other state we should not assume ?
130 g_QglTable.m_pfn_qglBindTexture(GL_TEXTURE_2D, m_tex->texture_number);
131 g_QglTable.m_pfn_qglBegin(GL_QUADS);
133 g_QglTable.m_pfn_qglColor4f(1.0, 1.0, 1.0, m_alpha);
134 g_QglTable.m_pfn_qglTexCoord2f(0.0, 1.0);
135 g_QglTable.m_pfn_qglVertex2f(m_xmin, m_ymin);
137 g_QglTable.m_pfn_qglTexCoord2f(1.0, 1.0);
138 g_QglTable.m_pfn_qglVertex2f(m_xmax, m_ymin);
140 g_QglTable.m_pfn_qglTexCoord2f(1.0, 0.0);
141 g_QglTable.m_pfn_qglVertex2f(m_xmax, m_ymax);
143 g_QglTable.m_pfn_qglTexCoord2f(0.0, 0.0);
144 g_QglTable.m_pfn_qglVertex2f(m_xmin, m_ymax);
146 g_QglTable.m_pfn_qglEnd();
147 g_QglTable.m_pfn_qglBindTexture(GL_TEXTURE_2D, 0);
149 g_QglTable.m_pfn_qglPopAttrib();
152 bool CBackgroundImage::Load(const char *filename)
156 unsigned char *image = NULL; // gets allocated with what ? g_malloc
157 int width = 0, height = 0;
159 g_FuncTable.m_pfnLoadImage(filename, &image, &width, &height);
162 Syn_Printf(MSG_WARN "load %s failed\n", filename);
166 // just in case we want to build for an old version
167 // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=900
168 #ifdef BKGRND2D_JPG_WORKAROUND
169 if ( strlen( filename ) > 4 && !strcmp( ".jpg",filename + strlen( filename ) - 4 ) ) {
170 Syn_Printf( MSG_PREFIX ".jpg workaround, clearing alpha channel\n" );
171 int size = width * height * 4;
173 for ( i = 3; i < size; i += 4 ) {
179 //TODO bug for stored texture size
180 //TODO whose gl context are we in, anyway ?
181 newtex = g_FuncTable.m_pfnLoadTextureRGBA(image, width, height);
186 Syn_Printf(MSG_WARN "image to texture failed\n");
193 g_FuncTable.m_pfnSysUpdateWindows(W_XY);
198 bool CBackgroundImage::SetExtentsMM()
200 entity_s *worldentity;
202 int xmin = 0, ymin = 0, xmax = 0, ymax = 0;
204 worldentity = (entity_s *) g_FuncTable.m_pfnGetEntityHandle(0);
206 Syn_Printf(MSG_WARN "SetExtentsMM worldspawn not found\n");
209 //TODO val is not NULL even if key does not exist
210 val = g_EntityTable.m_pfnValueForKey(worldentity, "mapcoordsmins");
211 if (!val || !val[0]) {
212 Syn_Printf(MSG_WARN "SetExtentsMM mapcoordsmins not found\n");
215 // we could be more robust
216 // note contortions due to splashs strange idea of min and max
217 if (sscanf(val, "%d %d", &xmin, &ymax) != 2) {
218 Syn_Printf(MSG_WARN "SetExtentsMM mapcoordsmins malformed\n");
222 val = g_EntityTable.m_pfnValueForKey(worldentity, "mapcoordsmaxs");
223 if (!val || !val[0]) {
224 Syn_Printf(MSG_WARN "SetExtentsMM mapcoordsmaxs not found\n");
227 if (sscanf(val, "%d %d", &xmax, &ymin) != 2) {
228 Syn_Printf(MSG_WARN "SetExtentsMM mapcoordsmaxs malformed\n");
231 //might do sanity check before we commit
232 m_xmin = (float) xmin;
233 m_ymin = (float) ymin;
234 m_xmax = (float) xmax;
235 m_ymax = (float) ymax;
237 g_FuncTable.m_pfnSysUpdateWindows(W_XY);
241 // TODO, this should just be exported from core
242 // ripped directly from radiant/select.cpp:Select_GetBounds
244 static bool get_selection_bounds(vec3_t mins, vec3_t maxs)
248 brush_t *selected_brushes = g_DataTable.m_pfnSelectedBrushes();
249 //TODO should never happen
250 if (!selected_brushes) {
251 Sys_Printf(MSG_PREFIX "selected_brushes = NULL\n");
254 // this should mean no selection
255 if (selected_brushes == selected_brushes->next) {
256 Sys_Printf(MSG_PREFIX "nothing selected\n");
261 for (i = 0; i < 3; i++) {
266 for (b = selected_brushes->next; b != selected_brushes; b = b->next) {
267 if (b->owner->eclass->fixedsize) {
268 for (i = 0; i < 3; i++) {
269 if (b->owner->origin[i] < mins[i]) {
270 mins[i] = b->owner->origin[i];
272 if (b->owner->origin[i] > maxs[i]) {
273 maxs[i] = b->owner->origin[i];
277 for (i = 0; i < 3; i++) {
278 if (b->mins[i] < mins[i]) {
279 mins[i] = b->mins[i];
281 if (b->maxs[i] > maxs[i]) {
282 maxs[i] = b->maxs[i];
290 bool CBackgroundImage::SetExtentsSel()
294 if (!get_selection_bounds(mins, maxs)) {
298 if (((int) mins[m_ix] == (int) maxs[m_ix]) ||
299 ((int) mins[m_iy] == (int) maxs[m_iy])) {
300 Syn_Printf(MSG_PREFIX "tiny selection\n");
309 g_FuncTable.m_pfnSysUpdateWindows(W_XY);