Tuesday, August 12, 2014
Eyes Test 3
Alright, I've been struggling with figuring out how I'm going to do layers... I decided I'd take a break from that and focus on 3D stuff. By applying transformations to a 4x4 Matrix (and then casting it to a 3x3 Matrix), I can use it to give the impression that a shape exists in a 3D space.
Oh yeah, I also added in some code for doing gradients. Anyways, I've at least got those things out of the way, so I'll be focusing again on doing layers....ugh.
Friday, August 8, 2014
Layering - a Work In Progress
Hi!
Today I decided I needed to focus on doing proper, optimized layering, but unfortunately it's complicated enough that I feel I need to make sure I have everything written in stone before actually trying to do layering myself. For that reason, I've started a document describing my thoughts and ideas for how I might (and will) go through getting layering to work. It is a WIP, so you might actually catch me working on it in real-time.
Click here to view the document.
I also suspect this will take several days to get in order, which is why I'm posting now as apposed to later when I've finished everything. That way, you can keep an eye on my progress.
Today I decided I needed to focus on doing proper, optimized layering, but unfortunately it's complicated enough that I feel I need to make sure I have everything written in stone before actually trying to do layering myself. For that reason, I've started a document describing my thoughts and ideas for how I might (and will) go through getting layering to work. It is a WIP, so you might actually catch me working on it in real-time.
Click here to view the document.
I also suspect this will take several days to get in order, which is why I'm posting now as apposed to later when I've finished everything. That way, you can keep an eye on my progress.
Thursday, August 7, 2014
Putting it all together - Eye Test 2
This is the result of everything I've done today. Hot dog, I got a LOT of stuff done today.
I still have a lot of work to do in order for this to be efficient and working properly. It might be necessary for me to do 3D vectors and 4x4 Matrices as well to get things like this eye test to work right, but THAT'LL BE FOR ANOTHER DAY, MKAY?
I still have a lot of work to do in order for this to be efficient and working properly. It might be necessary for me to do 3D vectors and 4x4 Matrices as well to get things like this eye test to work right, but THAT'LL BE FOR ANOTHER DAY, MKAY?
Parenting
Wow, I never thought I'd post this much stuff in one day.
I've whipped up a class called Entity that serves to contain shapes and other entities. It manages it's own attributes, such as rotation, shear, scale, etc... and can "recursively" draw to the screen in a layered manner similar to how Flash might.
I did a simple test where there's only two entities.
I've whipped up a class called Entity that serves to contain shapes and other entities. It manages it's own attributes, such as rotation, shear, scale, etc... and can "recursively" draw to the screen in a layered manner similar to how Flash might.
I did a simple test where there's only two entities.
- The first entity only contains a red shape
- The second entity contains a hollow box, the first entity, and a green shape
Masking - Take 2
Ok, I found a solution. My solution is to type-cast the masked layer's alpha array to contain values of type <type 'numpy.uint16'> instead of <type 'numpy.uint8'>, which allows me to multiply the values of the two alpha arrays without worrying about modulation since 255*255 (the largest value this could possibly produce) isn't bigger than nor equal to 2^16. I then divide the resulting product-array by the value 255, and then finally assign it to the alpha values in the masked layer.
masked_alpha = pygame.surfarray.pixels_alpha(self.output_layer)
mask_alpha = pygame.surfarray.pixels_alpha(self.mask_layer)
new_masked_alpha = numpy.uint16(masked_alpha)
new_masked_alpha *= mask_alpha
new_masked_alpha /= 255
masked_alpha *= 0
masked_alpha += new_masked_alpha
del new_masked_alpha
del masked_alpha
del mask_alpha
The result is beautiful.
The only complaint that I have about using this method is that since I have to type-cast the one array, the values have to be copied over instead of referenced, which can be SLOW. Even so, I'm very happy with this result since it performs perfectly and is relatively fast.
masked_alpha = pygame.surfarray.pixels_alpha(self.output_layer)
mask_alpha = pygame.surfarray.pixels_alpha(self.mask_layer)
new_masked_alpha = numpy.uint16(masked_alpha)
new_masked_alpha *= mask_alpha
new_masked_alpha /= 255
masked_alpha *= 0
masked_alpha += new_masked_alpha
del new_masked_alpha
del masked_alpha
del mask_alpha
The result is beautiful.
The only complaint that I have about using this method is that since I have to type-cast the one array, the values have to be copied over instead of referenced, which can be SLOW. Even so, I'm very happy with this result since it performs perfectly and is relatively fast.
Masking - Take 1 Analysis
Alright, so I figured out the issue with the first solution. The problem is the values are of type <type 'numpy.uint8'>. What's special about these values is that they're modulated by 2^8, meaning the values wrap around whenever they get larger than 255 or less than 0.
I'll have to figure out a way to get around this issue.
I'll have to figure out a way to get around this issue.
Masking - Take 1
Good morning!
Today I'd like to focus on doing masking. Masking is, by definition, applying the alpha of one image multiplicity to the alpha of another image. To explain this simply, it just means that an additional layer of alpha is applied to an image (even if that image already has an alpha channel), and will only allow that image to show through wherever the alpha is greater than 0 on the mask.
I've already whipped up an example, which I was surprised to find was much simpler than I had expected. As it turns out, the guys who work on Pygame recently added a feature to the surfarray sub-module to allow users to directly reference the alpha pixels of a surface in the form of an array. This is an extremely fast operation since it's merely referencing the alpha values rather than copying them. The fact that they're being referenced is also very useful since any changes done to the values in that array immediately show on the surface.
What I've done is generated the alpha-arrays for both the masked layer and the masking layer and multiplied the masking layer's alpha-array to the masked-layer's alpha array. I then made sure to delete those arrays, since the surfaces remain locked as long as those arrays exist.
masked_alpha = pygame.surfarray.pixels_alpha(self.output_layer)
mask_alpha = pygame.surfarray.pixels_alpha(self.mask_layer)
masked_alpha *= mask_alpha
del masked_alpha
del mask_alpha
The result is shown in the image below. The order is masked layer, masking layer, output layer.
For the most part, this does the job as described, but if you look carefully you can see that there's some strange artifacts showing up in the output layer. It's really unfortunate that those are showing up, since this solution is near perfect for what I am doing. Unfortunately, those stupid artifacts are reason enough to look for another solution (or simply a fix to this existing solution), which is why this post is titled "Take 1." I'll see what I can figure out.
Today I'd like to focus on doing masking. Masking is, by definition, applying the alpha of one image multiplicity to the alpha of another image. To explain this simply, it just means that an additional layer of alpha is applied to an image (even if that image already has an alpha channel), and will only allow that image to show through wherever the alpha is greater than 0 on the mask.
I've already whipped up an example, which I was surprised to find was much simpler than I had expected. As it turns out, the guys who work on Pygame recently added a feature to the surfarray sub-module to allow users to directly reference the alpha pixels of a surface in the form of an array. This is an extremely fast operation since it's merely referencing the alpha values rather than copying them. The fact that they're being referenced is also very useful since any changes done to the values in that array immediately show on the surface.
What I've done is generated the alpha-arrays for both the masked layer and the masking layer and multiplied the masking layer's alpha-array to the masked-layer's alpha array. I then made sure to delete those arrays, since the surfaces remain locked as long as those arrays exist.
masked_alpha = pygame.surfarray.pixels_alpha(self.output_layer)
mask_alpha = pygame.surfarray.pixels_alpha(self.mask_layer)
masked_alpha *= mask_alpha
del masked_alpha
del mask_alpha
The result is shown in the image below. The order is masked layer, masking layer, output layer.
For the most part, this does the job as described, but if you look carefully you can see that there's some strange artifacts showing up in the output layer. It's really unfortunate that those are showing up, since this solution is near perfect for what I am doing. Unfortunately, those stupid artifacts are reason enough to look for another solution (or simply a fix to this existing solution), which is why this post is titled "Take 1." I'll see what I can figure out.
Wednesday, August 6, 2014
Matrices
Hi guys. Yeah sorry, I know it's been a while since my last update but I've been busy with life stuff...
Today I focused on learning about matrices and how they're freaking awesome for vector graphics because you can do all your transformations to the matrix first before applying it to a shape. This means you'd only need to do ONE transformation calculation per point, as compared to doing each transformation one at a time for every single point (which can be costly when there's a lot of points and a lot of transformations).
Here's a little animation I threw together where I manipulate a shape using a matrix.
This is also really nice for doing cumulative transformations on children of parent entities - a topic which will be relevant in the near future. We'd only need to pass down the resultant transformation matrix from the parent to the child when calculating the new shape the child would form after the transformations are applied. This way, any transformations done to the parent will directly affect the child as well.
Today I focused on learning about matrices and how they're freaking awesome for vector graphics because you can do all your transformations to the matrix first before applying it to a shape. This means you'd only need to do ONE transformation calculation per point, as compared to doing each transformation one at a time for every single point (which can be costly when there's a lot of points and a lot of transformations).
Here's a little animation I threw together where I manipulate a shape using a matrix.
This is also really nice for doing cumulative transformations on children of parent entities - a topic which will be relevant in the near future. We'd only need to pass down the resultant transformation matrix from the parent to the child when calculating the new shape the child would form after the transformations are applied. This way, any transformations done to the parent will directly affect the child as well.
Subscribe to:
Posts (Atom)