Jump to content
  • entries
    941
  • comments
    5,894
  • views
    867,724

Textures in Leadwerks Engine 3


Josh

5,153 views

 Share

Textures in LE3 give you more control. You can retrieve all or part of any mipmap of a texture to system memory, edit the texture, then send it back to the GPU. Fortunately, the engine checks the bounds of the texture so you don't have to worry about producing any blue screens of death, as can happen when you're having too much fun with GPU memory.

 

Here's some simple code to retrieve the texture from video memory into a system memory bank, modify it, and send it back to the graphics card:

Bank* pixels = new Bank( texture->GetMipmapSize(0) );
texture->GetPixels( pixels );
pixels->PokeByte( (x*height + y)*4, 255 );
texture->SetPixels( pixmap );

There are overloaded functions for raw memory pointers, but the bank syntax has a little extra error checking, since this kind of thing can easily produce BSODs.

 

If you want to get really fancy, there are additional parameters that will let your retrieve or send part of a texture to and from the GPU. This is something I use extensively in the terrain editing routines, which take place on the GPU (that's why terrain editing is so fast). I use a shader to modify part of the terrain heightmap, and then I have to retrieve the modified heightmap back to system memory. Because the textures can be pretty big, it's more efficient to retrieve a sub-rectangle of pixels instead of the whole texture.

 

I ran into some trouble with DDS compression, as the image below demonstrates. This is what happens when you accidentally offset DDS mipmap data by four bytes. (This has been fixed):

blogentry-1-009463200 1286667131_thumb.jpg

The texture loader can handle background texture loading, so if you want you can have those cool blurry textures when a level starts, and they get sharper after a few seconds. This cuts the texture load time down to practically zero. If you have a large scene with lots of large textures, this will be nice to cut level load times down.

 

All media files in LE3 can be reloaded with a Reload() class function. This is necessary for some of the art pipeline features in the editor, so it's being built in from the very beginning. It is pretty cool to tap a key and watch your textures reload one mipmap at a time. This also means you can change the texture quality setting on the fly and not worry about reloading textures manually...when you change the texture quality setting the engine will automatically reload all textures that came from a file.

 

As we saw last week, here is the proper way to load a texture and apply it to a material in LE3:

Texture* tex = LoadTexture("brickwall01.dds");
mat->SetTexture(tex);
delete tex;

It occurred to me this can be simplified with an alternate overloaded function:

mat->SetTexture("brickwall01.dds");

The same can be done with shaders. If it succeeds, true is returned, otherwise false is returned:

mat->SetShader("Shaders/simple.shader");

So that's a nice convenient feature.

 

It was pointed out that my Copy(int unique) syntax was confusing, and I agree, because I couldn't even remember which was which. Therefore you will have an Instance() and Copy() function for textures, shaders, entities, materials, etc. The Instance() function will act like LE2's CopyEntity(), and the Copy() function will make a unique copy that can be modified without altering the original.

 

Texture animation is supported, out of the box. I'm using the old Quake naming convention where you add +framenumber to the end of the texture to specify an animation. For example, if you load "fire+01.dds", the engine will look for "fire+02.dds", "fire+03.dds", etc., until all frames are loaded. The texture will automatically switch frames with an animation speed you specify. It should be possible to convert AVI files into a sequence of separate frames, but I haven't looked into it yet.

 

That's all I have for now. It feels like I am really in the thick of LE3 development now. I've already done most of the graphics stuff with LE2, so I know how to do that. What I am really looking forward to is the high-level features, particularly the script and flowgraph implementation. I like to attack unknowns first, because the more I know, the better I can design the engine. We already know we can do fantastic graphics, and I understand how that all works. It would make sense to focus on areas that I haven't developed as extensively in the past...networking, gameplay, and the art pipeline. Therefore, we may see a Leadwerks 3 beta with just basic graphics and a focus on gameplay features first.

 

Please "like" this blog! :)

  • Upvote 2
 Share

16 Comments


Recommended Comments

I think "Instance" might be a bit confusing as well since this is usually the function called to get the instance from a Singleton.

 

Otherwise it all looks great! Nice to not have to write the extra line to call LoadTexture. But maybe mat->setTexture should return NULL or the pointer to the loaded texture in case the user wants to save a copy of it?

Link to comment

Could the following be simplified?

Bank* pixels = new Bank( texture->GetMipmapSize(0) );
texture->GetPixels( pixels );
pixels->PokeByte( (x*height + y)*4, 255 );
texture->SetPixels( pixmap );

 

to

 

Bank* pixels = new Bank( texture );
pixels->PokeByte( (x*height + y)*4, 255 );

 

What does PokeByte() do and could it be less math involved? (not that it's hard math or anything, but I remember working with bitmap pixels directly before and you had the offset and how it's all stored in a single array, but it's easier to think of an image as a 2D array with width & height like paint programs visually do)

Link to comment
Therefore, we may see a Leadwerks 3 beta with just basic graphics and a focus on gameplay features first

 

Very good new, cant wait to test anti-aliasing and this kind of thing with the graphic quality of LE3 ;)

Link to comment

I don't know how much the read/write pixel stuff can be made because a single pixel can use 1, 2, 3, 4, 8, or 16 bytes, depending on the format. I thought about a WritePixel() command where one of the parameters was a pointer to the pixel data, that had to be in the required format and length, but that was even more confusing. Additionally, DDS data stores pixel data in blocks, and you can't really write a single pixel, although you can still manipulate the data. Therefore it seemed best to just let the programmer use a memory pointer and read/write the data how they like, because it will be different for each format. I could do a WritePixel() command that accepted four floats and converted that to the proper format, but that's imprecise and probably not as good as writing the exact values in the correct format.

 

It's also possible to add your own texture loaders with this:

tex = new Texture(512,512,TEXTURE_MIPMAPS);
tex->SetPixels( mipmap0, 0 );
tex->SetPixels( mipmap1, 1 );
tex->SetPixels( mipmap2, 2 );
tex->SetPixels( mipmap3, 3 );
tex->SetPixels( mipmap4, 4 );
tex->SetPixels( mipmap5, 5 );
tex->SetPixels( mipmap6, 6 );
tex->SetPixels( mipmap7, 7 );
tex->SetPixels( mipmap8, 8 );

Or maybe:

tex = new Texture(512,512,TEXTURE_MIPMAPS);
tex->SetPixels( mipmap0, 0 );
tex->GenMipmaps();

Link to comment

Cool .Nice progress.

 

When we can expect beta ;)

 

Edit : I don't want to push you guys , just interesting about ;)

Link to comment

I would like to know if we can expect the beta i november or december to organize my project correctly :s

So would I, but at this point your guess is as good as mine. I am terrible at predicting development times, and I don't want to compromise anything by trying to hurry it up to meet a schedule. Obviously, I would like to have a beta available in November, but I don't know whether that will happen.

Link to comment

No problems Josh i am the first one to have enormous difficulties to predict the development time of my projects ;)

 

Thanks for the answer.

Link to comment

I think that Josh said that it will not be free, But if you buy the beta you dont have to buy the final version and the beta will be at discounted price for existing LE developpers ;)

Link to comment

Obviously, I would like to have a beta available in November, but I don't know whether that will happen.

Josh, of course, I'm just curious, and I want to put my hands on as soon as posible. ;)

Link to comment

I have not decided how this will be handled yet.

;)

Darn. I really wanted access to both the beta and the discount. I hope I'll get a chance to buy it. But I could also understand the need to focus the beta process.

 

Also, I vote for:

 

texture->WritePixel(x,y,color);

;)

Link to comment

Realtime texture updates, animated textures and background loading ! ;) That's sweet ! I like it (but i'm not on facebook)

 

can this texture updates be used to make decals ?

Link to comment

MAybe something like Octane Renderer did with a paid beta model.

 

They get plenty of feedback on their forums plus a lot pre-license selling. On the other hand all those early-adopters wont need to buy the full priced version later. So some income will be gone I guess.

Link to comment
Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...