Changeset 79
- Timestamp:
- 07/17/08 22:24:02 (5 months ago)
- Files:
-
- trunk/bin/yage3d.exe (modified) (previous)
- trunk/demo2/main.d (modified) (4 diffs)
- trunk/doc/ideas.txt (modified) (3 diffs)
- trunk/doc/ref/snippet.d (deleted)
- trunk/doc/unresolved.txt (modified) (1 diff)
- trunk/src/yage/core/math.d (modified) (1 diff)
- trunk/yage/core/vector.d (modified) (3 diffs)
- trunk/yage/gui/style.d (modified) (3 diffs)
- trunk/yage/gui/surface.d (modified) (9 diffs)
- trunk/yage/resource/font.d (modified) (3 diffs)
- trunk/yage/resource/image.d (modified) (10 diffs)
- trunk/yage/resource/resource.d (modified) (3 diffs)
- trunk/yage/resource/texture.d (modified) (4 diffs)
- trunk/yage/system/constant.d (modified) (1 diff)
- trunk/yage/system/device.d (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/demo2/main.d
r75 r79 102 102 103 103 104 // Create 104 // Create some windows 105 105 void onMouseDown2(Surface self, byte buttons, Vec2i coordinates){ 106 106 self.raise(); … … 122 122 123 123 auto window1 = new Surface(view); 124 window1.style.set("top: 5%; right: 3%; width: 160; height: 120; background-position: 5px 5px; " ~124 window1.style.set("top: 0; right: 0; width: 400; height: 60; background-position: 5px 5px; " ~ 125 125 "background-repeat: nineslice; background-material: url('gui/skin/clear2.png')"); 126 126 window1.onMouseDown = &onMouseDown2; 127 127 window1.onMouseMove = &onMouseMove2; 128 128 window1.onMouseUp = &onMouseUp2; 129 window1.onMouseOver = &onMouseOver;130 window1.onMouseOut = &onMouseOut;129 //window1.onMouseOver = &onMouseOver; 130 //window1.onMouseOut = &onMouseOut; 131 131 132 132 auto window2 = new Surface(window1); 133 window2.style.set("top: 10; right: 10; width: 50; height: 30; background-position: 5px 5px; " ~133 window2.style.set("top: 30; right: 0; width: 50; height: 30; background-position: 5px 5px; " ~ 134 134 "background-repeat: nineslice; background-material: url('gui/skin/clear2.png')"); 135 135 window2.onMouseDown = &onMouseDown2; … … 138 138 window2.onMouseOver = &onMouseOver; 139 139 window2.onMouseOut = &onMouseOut; 140 141 142 window1.style.fontFamily = Resource.font("gui/font/Vera.ttf"); 143 window1.style.fontSize = 12; 144 window1.style.color = Color("black"); 140 145 141 146 // Music … … 190 195 fps++; 191 196 if (frame.get()>=0.25f) 192 { char[] caption = formatString(" Yage Test (%.2f fps) (%d objects, %d polygons, %d vertices rendered)\0",197 { char[] caption = formatString("(%.2f fps) (%d objects, %d polygons, %d vertices)", 193 198 fps/frame.get(), camera.getNodeCount(), camera.getPolyCount(), camera.getVertexCount()); 194 SDL_WM_SetCaption( caption.ptr, null);195 //deletecaption;199 SDL_WM_SetCaption((caption ~"\0").ptr, null); 200 window1.text = caption; 196 201 frame.reset(); 197 202 fps = 0; trunk/doc/ideas.txt
r28 r79 7 7 Add boolean set operations to the Resource manager, to load all resources from a new level and free only those that aren't part of that set. 8 8 9 class Layer9 class Surface 10 10 { 11 bool passthrough; // pass events that occur on this layerto those behind it.11 bool passthrough; // pass events that occur on this surface to those behind it. 12 12 13 13 setOnClick(function); // mousebutton, mouseposition … … 36 36 37 37 A sensor node that checks for certain events (brightness, velocity, distance, etc.) and calls callback functions when 38 certain events occur. 38 certain events occur. (any node can do this in its update function). 39 39 40 40 Use axis sorting to tell what lights affect what nodes (instead of n*m distance check). But most lights have large radius? … … 42 42 Use dx cross dy to calculate normals for parametric graphnodes. 43 43 44 Create typed exceptions. 45 46 Make logging consistent and typed. 47 trunk/doc/unresolved.txt
r70 r79 22 22 fixed? 23 23 24 Dmd has trouble compiling incrementally with -O25 26 24 There is jumpiness in the rendering. Every 10th or so frame takes almost exactly twice as long to render 27 25 than others, when rendering the same thing. Especially noticable when rendering lots of models trunk/src/yage/core/math.d
r67 r79 10 10 import std.math; 11 11 import std.random; 12 import std.intrinsic; 12 13 13 14 public const float PI_180 = 0.01745329251994; // PI / 180 trunk/yage/core/vector.d
r76 r79 123 123 124 124 125 /// Allow for lin near additions and subtractions among Vectors of the same size and type.125 /// Allow for linear additions, subtractions, multiplcations, and divisions among Vectors of the same size and type. 126 126 VST opAdd(VST s) 127 127 { VST res; … … 130 130 return res; 131 131 } 132 /// Ditto132 /// ditto 133 133 void opAddAssign(VST s) 134 134 { for (int i=0; i<v.length; i++) 135 135 v[i] += s.v[i]; 136 136 } 137 /// Ditto137 /// ditto 138 138 VST opSub(VST s) 139 139 { VST res; … … 142 142 return res; 143 143 } 144 /// Ditto144 /// ditto 145 145 void opSubAssign(VST s) 146 146 { for (int i=0; i<v.length; i++) 147 147 v[i] -= s.v[i]; 148 } 149 150 /// Allow for additions, subtractions, multiplcations, and divisions where a scalar is applied to each vector component. 151 void opMulAssign(float s) 152 { for (int i=0; i<v.length; i++) 153 v[i] += s; 154 } 155 /// ditto 156 void opDivAssign(float s) 157 { for (int i=0; i<v.length; i++) 158 v[i] /= s; 148 159 } 149 160 trunk/yage/gui/style.d
r76 r79 10 10 import yage.core.color; 11 11 import yage.core.vector; 12 import yage.resource.font; 12 13 import yage.resource.resource; 13 14 import yage.resource.material; … … 154 155 } 155 156 // Font 156 //FontfontFamily;157 //float fontSize;158 //byte fontSizeUnit;157 Font fontFamily; 158 float fontSize = 12; 159 Unit fontSizeUnit = Style.PX; 159 160 //float fontWeight; 160 //Color color;161 Color color; 161 162 162 163 // Padding … … 242 243 switch (property) 243 244 { /// TODO: Lots more properties 245 case "color": color = Color(tokens[1]); break; 246 244 247 case "backgroundcolor": backgroundColor = Color(tokens[1]); break; 245 248 case "backgroundrepeat": backgroundRepeat = translate[tokens[1]]; break; trunk/yage/gui/surface.d
r76 r79 13 13 import derelict.opengl.glext; 14 14 import derelict.opengl.glu; 15 import derelict.opengl.extension.ext.blend_color; // opengl 1.2 15 16 import yage.core.all; 16 17 import yage.system.device; … … 18 19 import yage.system.input; 19 20 import yage.resource.texture; 21 import yage.resource.image; 20 22 import yage.gui.style; 21 23 import yage.system.rendertarget; … … 33 35 { 34 36 static final Style defaultStyle; 35 Style style; 37 Style style; 38 char[] text; 39 Image textImage; 40 Texture textTexture; 36 41 37 42 // internal values … … 40 45 Vec2f offset; // pixel distance of top left from the window's top left at 0, 0 41 46 42 bool mouseIn; // is this used?47 bool mouseIn; // used to track mouseover/mouseout 43 48 44 49 protected Style old_style; // Used for comparison to see if dirty. 45 50 protected Surface old_parent; 51 protected char[] old_text; 46 52 47 53 protected float[72] vertices = 0; // Used for rendering … … 94 100 95 101 /** 96 * Recalculate all properties of this Surface based on its style.*/ 102 * Recalculate all properties of this Surface based on its style. 103 * TODO: Ensure vertex and tex coord assignments are 100% on the stack (see array literals).*/ 97 104 void calculate() 98 105 { … … 185 192 float h = this.height(); 186 193 vertices[0..8] = [0.0f, h, w, h, w, 0, 0, 0]; 187 tex_coords[0..8] = [0.0f, 0, portion.x, 0, portion.x, portion.y, 0, portion.y]; 194 tex_coords[0..8] = [0.0f, 0, portion.x, 0, portion.x, portion.y, 0, portion.y]; 188 195 break; 189 196 case Style.NINESLICE: … … 201 208 // V | 202 209 // 1<---2 203 // TODO: Use same array for both using glScalef, once portion becomes unnecessary.204 210 // TODO: Ensure this operation is 100% on the stack. 205 211 vertices[0..72] = [ … … 281 287 282 288 glEnable(GL_BLEND); 283 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);289 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 284 290 285 291 //This may need to be changed for when people wish to render surfaces individually so the already rendered are not cleared. … … 297 303 } 298 304 305 306 299 307 void draw() 300 308 { 301 if(style.visible) 309 void drawQuad(int style) 310 { switch(style) 311 { case Style.NONE: 312 313 case Style.STRETCH: 314 glDrawArrays(GL_QUADS, 0, 4); 315 break; 316 case Style.NINESLICE: 317 glDrawArrays(GL_QUADS, 0, 36); 318 break; 319 default: 320 throw new Exception("Not a valid fill type"); 321 break; 322 } 323 } 324 325 326 if (style.visible) 302 327 { 303 if (dirty) 328 // Update positions 329 if (dirty()) 304 330 calculate(); 305 331 306 307 332 // Update Text 333 // Todo: check style font properties for changes also. 334 if (style.fontFamily && text != old_text) 335 { Timer a = new Timer(); 336 textImage = style.fontFamily.render(text, cast(int)style.fontSize, cast(int)style.fontSize, -1, -1, true); 337 writefln(a, textImage.getWidth(), textImage.getHeight()); 338 a.reset(); 339 if (textTexture.texture) 340 delete textTexture.texture; 341 342 writefln(a); 343 a.reset(); 344 textTexture = Texture(new GPUTexture(textImage, false, false), true, TEXTURE_FILTER_BILINEAR); 345 346 writefln(a); 347 348 old_text = text; 349 } 350 351 // Translate to the topleft corner of this 308 352 glPushMatrix(); 309 353 glTranslatef(topLeft.x, topLeft.y, 0); 310 glVertexPointer(2, GL_FLOAT, 0, vertices.ptr); 311 glTexCoordPointer(2, GL_FLOAT, 0, tex_coords.ptr); 312 313 void draw2() 314 { switch(style.backgroundRepeat) 315 { case Style.STRETCH: 316 glDrawArrays(GL_QUADS, 0, 4); 317 break; 318 case Style.NINESLICE: 319 glDrawArrays(GL_QUADS, 0, 36); 320 break; 321 default: 322 throw new Exception("Not a valid fill type"); 323 break; 324 } 325 } 326 354 355 // Draw background color 327 356 if (style.backgroundColor.a > 0) // If backgroundColor alpha. 328 357 { glColor4ubv(style.backgroundColor.ub.ptr); 329 draw2(); 330 glColor4ubv(Color(0xFFFFFFFF).ub.ptr); 331 } 332 358 glVertexPointer(2, GL_FLOAT, 0, vertices.ptr); 359 drawQuad(Style.STRETCH); 360 glColor4f(1, 1, 1, 1); 361 } 362 363 // Draw background material 333 364 if (style.backgroundMaterial !is null) 334 365 { glEnable(GL_TEXTURE_2D); 335 Texture(style.backgroundMaterial, true, TEXTURE_FILTER_BILINEAR).bind(); 336 draw2(); 337 glDisable(GL_TEXTURE_2D); 338 Texture(style.backgroundMaterial, true, TEXTURE_FILTER_BILINEAR).unbind(); 339 } 340 366 Texture tex = Texture(style.backgroundMaterial, true, TEXTURE_FILTER_BILINEAR); 367 tex.bind(); 368 glVertexPointer(2, GL_FLOAT, 0, vertices.ptr); 369 glTexCoordPointer(2, GL_FLOAT, 0, tex_coords.ptr); 370 drawQuad(style.backgroundRepeat); 371 tex.unbind(); 372 } 373 374 // Draw Text 375 if (textTexture.texture) 376 { 377 float ws = textImage.getWidth(); 378 float hs = textImage.getHeight(); 379 float[8] vertices = [0.0f, hs, ws, hs, ws, 0, 0, 0]; 380 float[8] tex_coords=[0.0f, 1, 1, 1, 1, 0, 0, 0]; 381 382 // Apply States 383 glEnable(GL_TEXTURE_2D); 384 textTexture.bind(); 385 386 glPushMatrix(); 387 glVertexPointer(2, GL_FLOAT, 0, vertices.ptr); 388 glTexCoordPointer(2, GL_FLOAT, 0, tex_coords.ptr); 389 390 // This extension is available as of OpenGL 1.1 or 1.2 and allows drawing text in a single pass. 391 if (Device.getSupport(DEVICE_BLEND_COLOR)) 392 { 393 // Apply states 394 Vec4f color = style.color.vec4f; 395 glBlendFunc(GL_CONSTANT_COLOR_EXT, GL_ONE_MINUS_SRC_COLOR); 396 glBlendColorEXT(color.r, color.g, color.b, 1); 397 glColor3f(color.a, color.a, color.a); 398 399 glDrawArrays(GL_QUADS, 0, 4); 400 401 // Revert states 402 glColor4f(1, 1, 1, 1); 403 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // reset blend function 404 } else 405 { 406 /// TODO: see http://dsource.org/projects/arclib/browser/trunk/arclib/freetype/freetype/font.d 407 } 408 409 // Revert States 410 glPopMatrix(); 411 textTexture.unbind(); 412 } 413 414 glDisable(GL_TEXTURE_2D); 415 341 416 // Using a zbuffer might make this unecessary. tradeoffs? 342 417 if (!children.sorted(true, (Surface s){return s.style.zIndex;} )) trunk/yage/resource/font.d
r76 r79 10 10 import std.stdio; 11 11 import derelict.freetype.ft; 12 import yage.core.math; 12 13 import yage.resource.exception; 13 14 import yage.resource.resource; … … 22 23 FT_Face face; 23 24 25 /// 24 26 this(char[] filename) 25 27 { 26 28 // Initialize Freetype library if not initialized 29 // TODO: Move this into Device? 27 30 if (!freetype_initialized) 28 { auto error = FT_Init_FreeType(&library); 29 if (error) 30 throw new Exception("Freetype Failed"); 31 { if (FT_Init_FreeType(&library)) 32 throw new Exception("Freetype2 Failed"); 31 33 } 32 34 … … 37 39 throw new ResourceLoadException("Could not open font file '" ~ source ~ "'. The format is not recognized by Freetype2."); 38 40 else if (error) 39 throw new ResourceLoadException("Could not open font file '" ~ source ~ "'."); 41 throw new ResourceLoadException("Freetype2 could not open font file '" ~ source ~ "'."); 42 } 43 44 /// 45 ~this() 46 { /// TODO: cleanup. 40 47 } 41 48 42 49 43 44 Image getGlyph(dchar[] text, int width=0, int height=0) 50 /** 51 * Render an image from text. 52 * Params: 53 * text = 54 * width = 55 * height = 56 * line_width = Letters will wrap to the next line after this amount (breaking on spaces) 57 * line_height = This much space will occur between each line, defaults to 1.5x height. 58 * image_pow2 = If true, the image returned will always have its dimensions as powers of two. 59 * Returns: 60 */ 61 Image render(char[] text, int width, int height=0, int line_width=-1, int line_height=-1, bool image_pow2=false) 45 62 { 63 // Calculate parameters 64 if (line_height==-1) 65 line_height = cast(int)(height*1.5); 66 if (line_width==-1) 67 line_width = int.max; 46 68 69 // Give our font size to freetype. 47 70 auto error = FT_Set_Pixel_Sizes(face, width, height); // face, pixel width, pixel height 48 71 if (error) 49 throw new Exception(" Font Error.");72 throw new Exception("Invalid font size."); 50 73 51 //foreach (c; text) 52 //{ 53 error = FT_Load_Char(face, text[0], FT_LOAD_RENDER); // Load into slot 74 // Stores a single rendered letter. 75 struct Letter 76 { Image image; 77 int advancex; 78 int advancey; // unnecessary? 79 int top; 80 int left; 81 } 82 83 Letter[] letters; // array of all rendered letters. 84 int total_width = 0; 85 int total_height = 0; 86 int image_height = 0; 87 int lines=1; // number of lines of text. 88 89 // Create a glyph for each letter and store its parameters 90 foreach (c; text) 91 { 92 error = FT_Load_Char(face, c, FT_LOAD_RENDER); // Load into slot 54 93 if (error) 55 94 throw new Exception("Font Error."); 56 95 57 96 auto bitmap = face.glyph.bitmap; 58 writefln("glyph size=", bitmap.width, " ", bitmap.rows);59 97 ubyte[] data = (cast(ubyte*)bitmap.buffer)[0..(bitmap.width*bitmap.rows)]; 60 Image img = new Image(data, 1, bitmap.width, bitmap.rows);61 98 62 return img; 99 // Set the values of the 100 Letter letter; 101 letter.image = new Image(data.dup, 1, bitmap.width, bitmap.rows); 102 letter.top = face.glyph.bitmap_top; 103 letter.left = face.glyph.bitmap_left; 104 letter.advancex = total_width; 105 letter.advancey = total_height; 106 letters ~= letter; 63 107 64 //} 108 total_width+= face.glyph.advance.x>>6; 109 total_height+= face.glyph.advance.y>>6; 110 } 65 111 66 112 113 // Composite all glyph images into a single image. 114 // We have to do this here since we need to render them before calculating sizes. 115 int img_width = image_pow2 ? nextPow2(total_width) : total_width; 116 int img_height = image_pow2 ? nextPow2(line_height*lines) : line_height*lines; 117 Image result = new Image(1, img_width, img_height); 118 for (int i=0; i<letters.length; i++) 119 { result.overlay(letters[i].image, letters[i].advancex+letters[i].left, (letters[i].advancey-letters[i].top+height)); 120 delete letters[i].image; 121 } 122 123 return result; 67 124 } 68 69 ~this() 70 { 71 72 } 73 74 75 protected void load() 76 { 77 78 } 125 79 126 } trunk/yage/resource/image.d
r76 r79 17 17 * Bugs: 18 18 * An RGB image will often be returned when loading grayscale images. Use setFormat(IMAGE_FORMAT_GRAYSCALE) to correct this. 19 * The load and resize functions seem to have images with widths that aren't a multiple of 4.*/ 19 * 20 * TODO: Add convolution support: http://www.php.net/manual/en/function.imageconvolution.php#77818 */ 20 21 class Image 21 22 { … … 43 44 44 45 /** 46 * Create a new emtpy image. 47 * Params: 48 * channels = number of color channels. 49 * width = width in pixels 50 * height = height in pixel */ 51 this(int channels, int width, int height) 52 { data.length = channels*width*height; 53 this.channels = channels; 54 this.width = width; 55 this.height = height; 56 } 57 58 /** 45 59 * Construct from image data in memory. This does not create a copy of the data. 46 60 * Params: 47 * image = array of raw image data 48 * width = width in pixels 49 * height = height in pixels, if 0 it is auto-calculated from width, channels, and data's length.*/ 61 * image = array of raw image data 62 * channels = number of color channels. 63 * width = width in pixels 64 * height = height in pixels, if 0 it is auto-calculated from width, channels, and data's length.*/ 50 65 this(ubyte[] data, int channels, int width, int height=0) 51 66 { this.data = data; … … 54 69 if (height) 55 70 this.height = height; 71 else if (width && channels) 72 this.height = data.length / (width*channels); 56 73 else 57 this.height = data.length / (width*channels);74 this.height = 0; 58 75 } 59 76 … … 187 204 body 188 205 { int i = (y*width+x)*channels; 189 //std.stdio.writefln(i, "..", i+channels);190 206 return data[i..(i+channels)]; 191 207 } … … 193 209 in { assert(x<width && y<height); } 194 210 body 195 { int i = (y*width *+x)*channels;211 { int i = (y*width+x)*channels; 196 212 return data[i..(i+channels)] = val[0..channels]; 197 213 } 198 214 215 /** 216 * Paste another image on top of this one. 217 * This does not make a copy. */ 218 void overlay(Image img, int xoffset=0, int yoffset=0) 219 { 220 for (int x=0; x<img.width; x++) 221 { int xoffsetx = xoffset + x; 222 if (xoffsetx < width && xoffsetx > 0) 223 { for (int y=0; y<img.height; y++) 224 { int yoffsety = yoffset+y; 225 if (yoffsety < height && yoffsety > 0) 226 this[xoffsetx, yoffsety][0..channels] = img[x, y][0..channels]; // TODO: convert format 227 } } } 228 } 229 230 void overlayAndFlip(Image img, int xoffset=0, int yoffset=0) 231 { 232 for (int x=0; x<img.width; x++) 233 { int xoffsetx = xoffset + x; 234 if (xoffsetx < width && xoffsetx > 0) 235 { for (int y=0; y<img.height; y++) 236 { int yoffsety = yoffset+y; 237 if (yoffsety < height && yoffsety > 0) 238 this[xoffsetx, yoffsety][0..channels] = img[x, img.height-y-1][0..channels]; 239 } } } 240 } 241 199 242 /** 200 243 * Return a c-style pointer to the image data. … … 210 253 * width = The new width. 211 254 * height = The new height. If 0, height will be calculated automatically with aspect ratio maintained. 212 * Returns: A new image of the same type .*/255 * Returns: A new image of the same type and of the new size, or an exact copy if the dimensions are the same. */ 213 256 Image resize(int width, int height=0) 214 257 { Image result = new Image(); … … 217 260 result.height = height; 218 261 else 219 result.height = width*this.height/this.width; 262 result.height = width*this.height/this.width; 220 263 result.channels = channels; 264 265 // Return a copy if there's nothing to resize. 266 if (result.width == this.width && result.height == this.height) 267 { result.data = this.data.dup; 268 return this; 269 } 270 221 271 result.data.length = width*height*channels; 222 223 272 float width1 = 1/(width-1.0f); 224 273 float height1= 1/(height-1.0f); … … 235 284 236 285 // TODO: modify this to return a new image in the given format. 237 voidsetFormat(int channels)286 Image setFormat(int channels) 238 287 { if (channels == this.channels) 239 return ;240 241 ubyte[] result;288 return this; 289 290 Image result = new Image(channels, width, height); 242 291 243 292 switch (channels) … … 245 294 case 1: 246 295 // Set each pixel to the average of RGB, dropping alpha if present 247 for (int i=0; i<data.length-2; i+=channels) 248 data[i/channels] = cast(ubyte)((data[i] + data[i+1] + data[i+2]) / 3); 249 data.length = width*height; 296 for (int i=0; i<data.length-this.channels-1; i+=this.channels) 297 { int sum=0; 298 for (int j=0; j<this.channels; j++) 299 sum += data[i+j]; 300 result.data[i/this.channels] = cast(ubyte)(sum / this.channels); 301 } 302 this = result; 250 303 break; 251 304 case 3: … … 277 330 } 278 331 this.channels = channels; 332 333 return this; 279 334 } 280 335 /** trunk/yage/resource/resource.d
r76 r79 11 11 import yage.core.array; 12 12 import yage.core.misc; 13 import yage.resource.font; 13 14 import yage.resource.model; 14 15 import yage.resource.material; … … 32 33 static char[][] paths = [""]; // paths to look for resources 33 34 35 private static Font[char[]] fonts; 34 36 private static GPUTexture[char[]][2][2] textures; // [source][clamped][compressed][mipmapped][filter] 35 37 private static Shader[char[]] shaders; … … 119 121 } 120 122 121 /** Acquire and return the given Model. 122 * If it has already been loaded, the in-memory copy will be returned. 123 * If not, it will be loaded and uploaded to video memory. 124 * All associated Materials, Textures, and Shaders will be loaded into 125 * the resource pool as well. 126 * Params: source = The 3D Model file that will be loaded. */ 123 /** 124 * Acquire and return the given Font. 125 * If it has already been loaded, the in-memory copy will be returned. 126 * If not, it will be loaded and then returned. 127 * Params: source = The Font file that will be loaded. */ 128 static Font font(char[] source) 129 { if (source in fonts) 130 return fonts[source]; 131 Timer t = new Timer(); 132 fonts[source] = new Font(source); 133 Log.write(Log.RESOURCE, "Resource ", source ~ " loaded in ", t, " seconds."); 134 return fonts[source]; 135 } 136 137 /** 138 * Acquire and return the given Model. 139 * If it has already been loaded, the in-memory copy will be returned. 140 * If not, it will be loaded and uploaded to video memory. 141 * All associated Materials, Textures, and Shaders will be loaded into 142 * the resource pool as well. 143 * Params: source = The 3D Model file that will be loaded. */ 127 144 static Model model(char[] source) 128 145 { if (source in models) trunk/yage/resource/texture.d
r76 r79 172 172 if (blend != BLEND_MULTIPLY) 173 173 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 174 175 glBindTexture(GL_TEXTURE_2D, 0); 174 176 } 175 177 … … 205 207 this() 206 208 { glGenTextures(1, &gl_index); 207 Texture(this).bind(); 208 Texture(this).unbind(); 209 210 // For some reason these need to be called or everything runs slowly. 211 glBindTexture(GL_TEXTURE_2D, gl_index); 212 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 213 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 214 glBindTexture(GL_TEXTURE_2D, 0); 209 215 } 210 216 … … 296 302 297 303 // Upload image 304 // TODO: Use image's built in resizer instead of glu. 305 // glu has resizing issues with non power of two source textures. 298 306 if (mipmap) 299 307 { //writefln(GL_TEXTURE_2D, " ", glinternalformat, " ", image.getWidth(), " ", image.getHeight(), " ", glformat, " ", GL_UNSIGNED_BYTE, " ", image.getData().length); … … 316 324 317 325 // Resize if necessary 318 image = image.resize(min(newwidth, max), min(newheight, max)); 326 if (newwidth != width || newheight != height) 327 image = image.resize(min(newwidth, max), min(newheight, max)); 319 328 glTexImage2D(GL_TEXTURE_2D, 0, glinternalformat, image.getWidth(), image.getHeight(), 0, glformat, GL_UNSIGNED_BYTE, image.getData().ptr); 320 329 trunk/yage/system/constant.d
r76 r79 15 15 DEVICE_SHADER, /// Hardware support for openGl vertex and fragment shaders 16 16 DEVICE_VBO, /// Hardware support for caching vertex data in video memory (Vertex Buffer Object) 17 DEVICE_BLEND_COLOR, 17 18 18 19 DEVICE_MAX_LIGHTS, /// Maximum number of lights that can be used at one time trunk/yage/system/device.d
r76 r79 41 41 abstract class Device 42 42 { 43 43 44 // Video 44 45 protected static SDL_Surface* sdl_surface; // Holds a reference to the main (and only) SDL surface … … 153 154 }else 154 155 Log.write("GL_ARB_vertex_buffer_object not supported. This is still ok."); 156 157 // Attempt to load blend color extension 158 if (getSupport(DEVICE_BLEND_COLOR)) 159 { if (!EXTBlendColor.load("GL_EXT_blend_color")) 160 throw new Exception("GL_EXT_blend_color extension detected but it could not be loaded."); 161 Log.write("GL_EXT_blend_color support enabled."); 162 }else 163 Log.write("GL_EXT_blend_color not supported. This is still ok."); 155 164 156 165 // OpenGL options … … 226 235 static bool checkExtension(char[] name) 227 236 { char[] exts = std.string.toString(cast(char*)glGetString(GL_EXTENSIONS)); 228 int result = find(to upper(exts), toupper(name)~" ");229 delete exts; 237 int result = find(tolower(exts), tolower(name)~" "); 238 delete exts; // [above] append space to ensure we're not matching part of another extension. 230 239 if (result>=0) 231 240 return true; … … 273 282 static bool getSupport(int constant) 274 283 { //return false; 275 static int shader=-1, vbo=-1, mt=-1, np2=-1 ; // so support only has to be found once284 static int shader=-1, vbo=-1, mt=-1, np2=-1, bc=-1; // so lookup only has to occur once. 276 285 switch (constant) 277 286 { case DEVICE_SHADER: … … 294 303 np2 = checkExtension("GL_ARB_texture_non_power_of_two"); 295 304 return cast(bool)np2; 305 case DEVICE_BLEND_COLOR: 306 if (bc==-1) 307 bc = checkExtension("GL_EXT_blend_color"); 308 return cast(bool)bc; 296 309 default: 297 310 throw new Exception("Unknown Device.getSupport() constant: '" ~
