skymen's Recent Forum Activity

  • Oh :o

    Nice, thanks. I'll look into this. I'll need to learn some proper webgl first. I didn't know you could get C2's gl by doing glw.gl xD.

    I guess I misread glwrap.js cause I never saw anywhere anything named this.gl, only gl.

    Oh interesting, I didn't know "multiply" was one of the options now. It didn't used to be. I'm not sure if that would cause compatibility issues on some browsers.

    Well it seems like most browsers support it. Every browser except Edge 11 and prior. Edge 12 supports it.

    According to MDN: developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation

    I hadn't thought of creating individual letters of different colors as needed and keeping them for later use. Probably works well when only using a limited amount of colors. If the user ended up trying to do gradual color transitions you may run out of video memory though.

    Yeah it works pretty well in most cases. But indeed it may become inefficient if a user uses too many colors for too many characters. However run out of video memory? How so? Maybe run out of RAM, but VRAM? I'm genuinely asking here. I create the texture on a virtual canvas, and then store it in a JS object. I never actually add the canvas to the document. Would that still use up some video memory?

    It's not bad to end a batch in c2's renderer. It does it all the time. All a batch does is it sends multiple quads using the same texture at the same time instead of separately. Besides you'd be doing your own batching of all the letters in your spritefont renderer. The only drawback is if multiple spritefont instances drawn right after each other then they could only be batched individually instead of together, but I say it doesn't matter too much.

    Yeah ok I kinda get it. I really need to learn webgl, because I didn't know most of that.

    Maybe that could be a useful example to use alongside a webgl tutorial.

    Yes thanks again. I'll look into it and maybe I can use that to make the code more optimized.

  • Hi, thanks R0J0hound for your super helfpul answer.

    Sadly I had already found a way to do this.

    Indeed what I do right now, is I draw the letter on a black canvas the size of the letter, multiply by my color, and draw the letter again in 'destination-in' mode to mask the canvas's content.

    Then to save performance, I cache the texture in an object and if I ever need to redraw that letter with that color, I don't need to redo the process. This is helpful given that in a game the colored parts of the text are often the same words.

    But indeed this is problematic on WebGL because changing an image to a webGL texture had some issues. So I decided to cache the texture as well. So I draw the image, convert it to a texture only once.

    However, this still has some overhead compared to the canvas reder mode.

    I'll need to see if recoding the same process in WebGL will save more perf compared to keeping what I have right now or not.

    Also I don't think breaking C2's batch is a good idea. I have little to no experience in WebGL so I'm probably wrong, but afaik this means that the rendering gets a lot more tedious the more I have letters since I need to create a new batch and break it for each letter. Also I wasn't able to create a new proper batch using the same params C2 uses because I can't access these values, but again, maybe it's due to my inexperience with WebGL

    		function getColoredTexture(inst, image, color, clip, scale, letter) {
    		if(!color || color === 'None') {
    			return image
    		}
    		if (inst.cachedImages !== undefined && inst.cachedImages[letter] !== undefined && inst.cachedImages[letter][color] !== undefined) {
    			return inst.cachedImages[letter][color];
    		}
    		// Create new canvas
    		var charCanvas = createCanvas(clip.w * scale, clip.h * scale)
    		var charContext = charCanvas.getContext("2d");
    		// Draw letter on it
    		charContext.fillStyle = 'black';
    		charContext.fillRect(0, 0, charCanvas.width, charCanvas.height);
    		charContext.drawImage(image,
    			clip.x, clip.y, clip.w, clip.h,
    			0, 0, clip.w * scale, clip.h * scale);
    		// Apply color
    		charContext.globalCompositeOperation = 'multiply';
    		charContext.fillStyle = color;
    		charContext.fillRect(0, 0, clip.w * scale, clip.h * scale);
    		// Restore the transparency
    		charContext.globalCompositeOperation = 'destination-in';
    		charContext.drawImage(image,
    			clip.x, clip.y, clip.w, clip.h,
    			0, 0, clip.w * scale, clip.h * scale);
    		// Restore composite operation
    		charContext.globalCompositeOperation = 'source-over';
    		if (inst.cachedImages === undefined) {
    			inst.cachedImages = {}
    		}
    		if (inst.cachedImages[letter] === undefined) {
    			inst.cachedImages[letter] = {}
    		}
    		inst.cachedImages[letter][color] = charCanvas
    		return charCanvas
    	}
    

    Here's the code and here's how it looks

    cdn.discordapp.com/attachments/183566321156358144/481403367705542659/2018-08-21_11-58-23.gif

    EDIT: Just realized I should probably not recreate a whole new canvas each time. I'll change that.

  • matpow2

    I couldn't locate the Discord for Chowdren or MP2 so i sent you a direct email with c3 file. Hope it works!

    Hi, unless I'm wrong, said Discord server is this one discord.gg/qgkAPPk

    It's not specific to Chowdren. If such server exists I recommend that matpow posts it

  • Hi, I'm making the Spritefont Deluxe addon for Construct 2 and I've been trying to make the spritefont support per letter color for quite a long time now. However I can't seem to find a way to do this.

    I tried adding a tint effect to the spritefont and changing its values during runtime. This only changes the values for the next draw and hence affects the whole Spritefont.

    I tried looking at the way the engine draws the canvas, until I finally found the code that draws the object using WebGL effects. It's in layout.js in Layer.DrawGL. There I had the code to "simulate" changing the effect used for glw rendering. However for that I'd need to push a new batch and apply a whole bunch of values that I don't have access to and that would make performance terrible If I needed to push a new batch for each letter or set of letters.

    I tried looking into how I could do this using only Javascript. Right my best bet would be to print the letter texture image on a canvas, then change every white pixel into my color, and then get the new texture image and use that to render.

    While this may work even though I didn't try yet this seems like a very inneficient way of doing it so I really don't know if that's the best way to do this.

    I'm kind of in a corner right now so if anyone has a better idea, I'd be really glad to take it.

  • Uhhh. I think this topic slightly derivated from it's original goal, so let's get back to the original subject.

    The software is really great. C3 is doing well according to scirra.

    Everything is evolving and I can only foresee a bright future for Construct 3.

    The community hasn't really changed since Construct Classic. Just different people. It's always been the same, with your same amount of kinda toxic people but it's not important. Most people are just happy with how everything is and there is no reason to think that anything will go badly.

    Now I'd really like the few people who used their post to send a negative message about a part of the community (namely the said discord server) or about scirra to stop doing that.

    Guys this is not a discord server war field nor a place to send your frustration to. So stop it.

    Now I hope that you'll have a great time using Construct again, and everyone else in the community will be happy to help you if you have questions.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Fair enough x)

  • All the internal layer code should also be considered private methods for the engine's use only and should not be used from the SDK. You will probably break all sorts of things if you do this, and we will not offer any support for using private and undocumented parts of the engine, so you should find a different solution.

    Yes I already know all of that thank you x).

    But in theory, if I manage to manually trigger the parts of the code that are only ran once because they assume that the layer number should never change, it should work.

    Again, note that I am not speaking about wether this is a good idea or not. I'm speaking about whether this is possible.

    Also, given that this is done as a 3rd party addon, you wouldn't offer support if the addon broke anything as it's 3rd party anyway. I'm not modifying anything in any of C2's files. In the worst case scenario, if I run into very bad issues, I'll just remove the plugin and everything will start working again.

  • The whole purpose of using the layer's constructor is that it already manages all of the parrallax, scale, and all of that stuff already.

    Also when copying a layer, it copies all of th layer's properties as well. Including these, but also including the instances on the layer in theory. This is why I don't quite understand why they don't get created and assumed something else did that.

  • Well. Creating layers.

    In the end the method might also be used to reorder layers, delete them or duplicate them.

    If you mean "In what context is this useful to have because it would be the only way to achieve a given goal" I'm pretty sure you can find tons of possible uses of this on your own, but let me make myself clear. The whole point of me wanting to do this is to make it easy to do stuff, not to make it possible.

    There are many ways to avoid a problem by using alternative ways, but when these ways involve wasting my time doing stuff I don't like doing then I'm out. In fact this is exactly what I described at the beginning of my post, and this is also why I don't request for this to be a feature but rather for this to be a discussion about what can be done theoretically using the engine's hidden functions.

  • As reported here:

    github.com/Scirra/Construct-3-bugs/issues/1911

    The textbox bar doesn't work. I'm surprised I haven't heard anyone complain about this sooner. I don't seem to be the only one experiencing this though.

  • Eh. I kinda like the overall style of the new website. Everything is fine to me. The colors look really nice. Also I don't think a dark theme for a forum would work well. Just an opinion though.

  • Hi,

    I'll try to make this quick. Yesterday I was thinking about how I would manage a particular issue I have with my project which involve my will to make as many things as possible automated and my strong hate for boring work.

    Basically I was in the case where my project needed a LOT of layers to work for the UI. So that meant creating a layout filled with lots of global layers dedicated to UI and then having to add these layers manually to all of my layouts that need that UI.

    I know. I don't wanna do that either. So instead I figured I might try to automate the process of creating layers. So I took a deep dive into the construct 2 code, reading most of the runtime code, most of the cr code, and most of layout.js.

    My main inspiration was Toby's Unload and Preload plugins which allow a user to load layouts and basically make a real loading screen. I knew that to do this he kinda had to take deep dives into the engine as well.

    Anyway, here's what I gathered from this, and I'm not done looking around yet, but I figured I might as well make a topic that I'd keep updated.

    The code to create a new layer in a layout is pretty simple:

    var layout = this.runtime.running_layout;
    var layer = this.runtime.layouts_by_index[1].layers[0]; // whatever method you use to get other layers.
    //You can also create a new layer by calling the constructor in cr
    layer = new cr.layer(layout, layerData) // With layerData being an array containing all of the layer's base info. You can get a look at what it looks like by logging the variable m in the Layer's constructor in layout.js
    layer.number = layout.layers.length;
    cr.seal(layer);
    layout.layers.push(layer);
    

    This works for copying any layer from any layout or creating a brand new one.

    Now this comes with issues, including some I have yet to figure out.

    The first issue is that layers are assigned an sid value which I can only imagine is used to manage layers during runtime. I can't tell which issues having two layers on two different layouts share the same sid would create, but I can guess it could mess with the existance of that layer entirely, or even overwriting it entirely which would be bad. A fix would be to just make sure to deep copy the layer and change the sid instead of copying directly.

    Having 2 layers share the same sid on the same layout seems to erase one of them. Or it could also be due to both layers sharing the same name. Anyway, it's problematic in any case.

    The second issue is that objects aren't copied over from that piece of code only. I gathered that some other piece of code is in charge of actually creating the objects a layer is holding. I'll have to keep investigating to be sure.

    The third issue seems to be a bug that should be a problem in most use cases. When I tried creating a new layer entirely, I tried setting it to non transparent, and to change the background color to cyan, just for the sake of testing the thing. The new cyan layer did appear in front of my other layer containing random sprites, but when I tried moving one of these sprites to the new layer the sprite wouldn't appear. This is weird because the debugger says that the sprite did in fact change layers, and when the layer is transparent, it works totally fine and the sprite gets thrown in front of all of the other sprites.

    Another issue that I think will never be resolved is the case of global layers. Given my initial intent, my goal was to create new empty layers named after global layers so C2 would do the job of copying all of the objects for me, but unfortunately the only reference for "global layers" I was able to find in the code was about making sure two objects from global layers didn't share the same UID, which makes me think that global layers are entirely managed in the editor and when it comes to previewing and exporting, C2 copies all of the stuff on the global layers to all the overriden ones. So global layers don't exist during runtime. Which is kinda lame, because my original idea wont work, but kinda makes sense as well.

    My initial question was "Can I make it so I can add all of my UI stuff through events, including the layers?" and the answer is "Yes, in theory, but if I don't wrap my head around these issues, I'll have to make one global layer, shove all of my UI in it, and create all the new empty layers at runtime, and manually move all of the UI to the right layer after creating it. Which hopefully works and doesn't make C2 freak out for a frame"

    Also, I guess deleting layers, reordering them, and duplicating them should be possible if done right. It even seems that creating new layouts entirely could be a thing in theory. Which would be absolutely amazing for lots of things.

    Anyway, this is what I gathered, but I didn't write any of that code, just read it and I guess I'd need to know what Ashley has to say about this. If I'm mistaken about anything in here, please tell me. If you have any insight to give me, please do. The following is addressed to you.

    Please note that this is not a feature request even though this would be amazing to have in the new C3 runtime, even though it would be super dangerous in the hands of new users. I'm not making a feature request for this because I don't see the point of making one yet.

    Please also note that while I am speaking in the Javascript SDK and while I do plan on making a plugin to allow me to control these from the event sheet if it happens to be possible, I do not plan to share that plugin to anyone any time soon. I'm not willing to give support to this, and any user wanting this is either advanced enough to replicate what I did from the piece of code I shared or shouldn't be attempting this entirely.

    Finally, please note that this is all a discussion about what can or cannot be done using C2 by potentially rewriting parts of the runtime through a plugin, and while I do realise that this may not be a good choice to step out of what is documented in the SDK (because most undocumented stuff is undocumented for a reason), I wouldn't want to talk about that because it would make no sense to warn anyone about this. I just wanna have fun with the engine without breaking half of it, so I wanna know if there are things I need to know before trying to do so. By that I mean potential issues I didn't see coming, incompatibilities with what the editor might do, stuff breaking when exporting etc.

    Thanks for reading all of this. Anyone curious about this can discuss it in this topic.

skymen's avatar

skymen

Member since 3 Aug, 2015

Twitter
skymen has 100 followers

Connect with skymen

Trophy Case

  • 9-Year Club
  • Entrepreneur Sold something in the asset store
  • Jupiter Mission Supports Gordon's mission to Jupiter
  • Forum Contributor Made 100 posts in the forums
  • Popular Game One of your games has over 1,000 players
  • x34
    Coach One of your tutorials has over 1,000 readers
  • x2
    Educator One of your tutorials has over 10,000 readers
  • Regular Visitor Visited Construct.net 7 days in a row
  • Steady Visitor Visited Construct.net 30 days in a row
  • RTFM Read the fabulous manual
  • x7
    Quick Draw First 5 people to up-vote a new Construct 3 release
  • x2
    Lightning Draw First person to up-vote a new Construct 3 release
  • x2
    Great Comment One of your comments gets 3 upvotes
  • Email Verified

Progress

22/44
How to earn trophies

Blogs

  • Skymen

    Sometimes I do some cool stuff in Construct. Sometimes I like to talk about it.