ymobe / rapanui

High level API for MOAI framework
185 stars 48 forks source link

Handling black bar when config.stretch is set to true #57

Closed Sylph closed 12 years ago

Sylph commented 12 years ago

I think it'll be a great feature to add an option that would allow us to still draw on the inadvertent black bars on the side, when config.stretch is set to true?

Manually scaling every object in the game code makes for a rather messy code, unless there's another option that I missed?

Thanks ^^

MattiaFortunati commented 12 years ago

Hi, I've implemented bounding box in the same way Moai guys suggested. Handling black bars would be great but I think the whole stretch should be revised, since, at the moment, the whole openGL is stretched.

Well...yes at the moment you cannot write on black bars or change their color, and if you want to do so, you have to invent some sort of workaround...

Thanks, issue labeled :D

Sylph commented 12 years ago

True, I also find that stretch system rather awkward, though using the following while setting offset to 0 should fix it for now,. It seems that the click positions may need some adjustments as well if this is done, and and may need to give a separate offset variable to use for positioning?

It's under "if config.stretch == true then" in RNFactory.lua

    SCREEN_UNITS_X = DEVICE_WIDTH * config.graphicsDesign.h/DEVICE_HEIGHT
    SCREEN_UNITS_Y = config.graphicsDesign.h
    RNFactory.screen.viewport:setSize(0, 0, DEVICE_WIDTH, DEVICE_HEIGHT)
    RNFactory.screen.viewport:setScale(SCREEN_UNITS_X, -SCREEN_UNITS_Y)

Right now i also have config.landscape = (config.sizes[config.device][1] < config.sizes[config.device][2]) on config.lua though.

Thanks for the amazing response time btw. :)

MattiaFortunati commented 12 years ago

What kind of issues are you encountering with stretch? Touch coordinates? What are your settings? (device size, orientation, graphics design)

config.landscape = (config.sizes[config.device][1] < config.sizes[config.device][2])

Oh, this is for automatically enable lanscape mode (in a more transparent way) based on config.sizes. Nice,maybe I'll add this into the RNFactory and remove "config.landscape=boolean" in further releases, but at the moment, I'll leave users "the power" to manually activate it or not.

Thanks!

Sylph commented 12 years ago

I currently have

config.sizes = {
    ["Auto"] = { MOAIEnvironment.screenWidth or 555, MOAIEnvironment.screenHeight or 1800,
                 MOAIEnvironment.screenWidth or 555, MOAIEnvironment.screenHeight or 1800}
} 
config.device = "Auto"
config.landscape = (config.sizes[config.device][1] < config.sizes[config.device][2]) -- When true then rotate device screen.
config.graphicsDesign = { w = 2048, h = 1536}

for testing, which on windows would just give 555:1800 for config.sizes. With landscape enabled, it create a viewport of 1800:555 size. Then the following code in RNFactory:

if config.stretch == true then
    local DEVICE_WIDTH, DEVICE_HEIGHT, gameAspect, realAspect
    DEVICE_WIDTH, DEVICE_HEIGHT = RNFactory.width, RNFactory.height

    local SCREEN_UNITS_X, SCREEN_UNITS_Y
    local gameAspect = config.graphicsDesign.h / config.graphicsDesign.w
    local realAspect = DEVICE_HEIGHT / DEVICE_WIDTH

    if (realAspect > gameAspect) then
        -- There are black bars on top/bottom
        SCREEN_UNITS_X = config.graphicsDesign.w
        SCREEN_UNITS_Y = config.graphicsDesign.w * realAspect
    else
        -- There are black bars on the sides
        SCREEN_UNITS_X = config.graphicsDesign.h / realAspect
        SCREEN_UNITS_Y = config.graphicsDesign.h
    end

    RNFactory.screen.viewport:setSize(0, 0, DEVICE_WIDTH, DEVICE_HEIGHT)
    RNFactory.screen.viewport:setScale(SCREEN_UNITS_X, -SCREEN_UNITS_Y)

    print("SCREEN UNITS X Y:", SCREEN_UNITS_X, SCREEN_UNITS_Y)
    print("DEVICE WIDTH HEIGHT:", DEVICE_WIDTH, DEVICE_HEIGHT)
    print("GraphicsDesign:", config.graphicsDesign.w, config.graphicsDesign.h)

    RNFactory.outWidth = config.graphicsDesign.w
    RNFactory.outHeight = config.graphicsDesign.h

    RNFactory.screenUnitsX = SCREEN_UNITS_X
    RNFactory.screenUnitsY = SCREEN_UNITS_Y
end

As easily noticeable I kept the offset at 0 by removing the offset handling there, so that there's no black bars on the left/top sides.

The prints give the following: SCREEN UNITS X Y: 4981.6216216216 1536 DEVICE WIDTH HEIGHT: 1800 555 GraphicsDesign: 2048 1536

Clicking very near the bottom right corner give 1790:536 as the x:y coordinates So, obviously the touch doesn't get scaled based on SCREEN_UNITS_X and SCREEN_UNITS_Y. The coordinate of the button clicks are very off.

MattiaFortunati commented 12 years ago

Ok, now I can figure out better your situation. I'm just missing something: what are problems in RapaNui stretch that made you change it?

However, yes, you need to change also "RNScreen:getObjectWithHighestLevelOn(x, y)" to fit touch coordinates, but, again, I did not understand why you need to change the stretch... weird coordinates? Or maybe because you don't want black stripes ...

Sylph commented 12 years ago

The black bars/stripes on the side as my first post indicate was the only reason. :) Player seems to complain a lot about it

MattiaFortunati commented 12 years ago

Ok now it's clearer, "awkward "was referred to this :D Players don't like this so much, I can imagine that...

I know black stripes are not so good, but are the fastest way to have the same graphics for every device (android is the real problem, and the new iPhon could be, too). [as cocos and other frameworks does ,too]

The long way is to have different devices and different graphics. So for the moment we give the possibility to stretch with bars as other frameworks.

However as we told above, it will be great to handle these awkward bars.

So , let's keep this issue opened for further improvements. Thanks :D

Sylph commented 12 years ago

You're welcome.

The scaling I did still allows the graphic designer to create for every devices, because it give them the option to draw to the black bar area as well. Before that, Moai clips the area to the same aspect ratio as the graphic design. With this, I could for example create an oversized background that'll cover most devices, or create device-independent positioning of the game sprites/GUI. So there's no loss there.

Anyway thanks for the responses and the tips about 'RNScreen:getObjectWithHighestLevelOn', which I haven't looked at. :)

MattiaFortunati commented 12 years ago

What is going to be there, instead of black bars? Will the whole content be resized? Also, did you tested it on devices and landscape mode?

The change seems to be between lines 105 and 130, plus an add in the config.lua, right?

The code seems to be safe, it shouldn't cause any problems to letterbox. I'll test this and let you know ;D

MattiaFortunati commented 12 years ago

What happened to previous comment? Is something wrong? Why did you deleted it together with the link to your trunk? Did the code was wrong?

Let me know!

Sylph commented 12 years ago

Sorry! Seems you saw that a little too quick. ;) I noticed that

local gx = config.graphicsDesign.w
local gy = config.graphicsDesign.h

in the "function RNScreen:getObjectWithHighestLevelOn(x, y) " was causing touch event locations to be off, which I had to replace with

local gx = RNFactory.screenUnitsX
local gy = RNFactory.screenUnitsY

to remove the dependency on config variables. So I removed the comment, hoping to edit that quick before resubmitting it. :) I'll just add to it next time to avoid confusion.


original message: I decided to reopen my github fork so others could use my changes.

Anyway I made my fork automatically remove the black bar on the sides, but it give the option to keep it.

Feel free to check it at https://github.com/Sylph/rapanui/blob/rapanuidev/rapanui-sdk/RNFactory.lua and see if you like it

Reenabling letterbox clipping is done by simply adding the following line in config.lua config.letterBoxClipping = true

Basically I just use any of the following

local screenW, screenH, halfW, halfH = RNFactory.letterboxWidth, RNFactory.letterboxHeight, RNFactory.letterboxWidth/2, RNFactory.letterboxHeight/2
local screenFW, screenFH, halfFW, halfFH = RNFactory.outWidth, RNFactory.outHeight, RNFactory.outWidth/2, RNFactory.outHeight/2
local offsetX, offsetY = RNFactory.letterboxXOffset, RNFactory.letterboxYOffset

if I need any data on screen size/offset

MattiaFortunati commented 12 years ago

Mh... It won't be easy to test all your changes ...

So, basically, you only changed config.lua (one line), RNFactory(105-130) and RNScreen (gx,gy) to improve the letterbox,right?

What should I do to test your letterBoxClipping and add it to RapaNui? Can you explain this to me better? Do I simply need to replace config.lua, RNFactory and RNScreen with the ones in your trunk? Or maybe I need to change something else? (that's because your trunk has many differences with ours, I just don't know which ones of them I need)

Secondly what are :

local screenW, screenH, halfW, halfH = RNFactory.letterboxWidth, RNFactory.letterboxHeight, RNFactory.letterboxWidth/2, RNFactory.letterboxHeight/2 local screenFW, screenFH, halfFW, halfFH = RNFactory.outWidth, RNFactory.outHeight, RNFactory.outWidth/2, RNFactory.outHeight/2 local offsetX, offsetY = RNFactory.letterboxXOffset, RNFactory.letterboxYOffset

?

Sylph commented 12 years ago

That's correct. Basically just copy those lines you mentioned "config.lua (one line), RNFactory(105-130) and RNScreen (gx,gy)" line

I would recommend adding the following helper vars too though (up to the last line of change on RNFactory), as the letterboxXOffset & letterboxYOffset are especially important in positioning.

        RNFactory.letterboxWidth = config.graphicsDesign.w
        RNFactory.letterboxHeight = config.graphicsDesign.h
        RNFactory.letterboxXOffset = (SCREEN_UNITS_X - RNFactory.letterboxWidth) * 0.5
        RNFactory.letterboxYOffset = (SCREEN_UNITS_Y - RNFactory.letterboxHeight) * 0.5

As for the second question, those few lines are just examples of how Rapanui users could get values for their positioning/scaling game codes.

So for testing you could just copy those, use RNFactory.createRect(5, 5, screenFW-10, screenFH-10, { rgb = { 55, 0, 0 } }) to see that the entire screen is filled with the rect (except for some small space on the side), and just place in some buttons in to test the touch.

MattiaFortunati commented 12 years ago

I had a little test of your code. I had problems with regular letterbox feature, I think due to gx and gy in RNScreen, since they no longer take graphicsDesign. There should be a check there on config.letterBoxClipping I think.

But, I can understand how to fix your problem now.

We should have a boolean for activating letterbox in config.lua. Like "config.blackbars". Then, when creating the stretched viewport we should create it as usual, then stretch it if blackbars are true or create the viewport larger than screen ,then stretch it. In the second case, it has to been larger enough to cover blackbars.

The second case is what you need, so you can draw on blackbars space, but, also you need to care also of other sprites going over that space.

This way it should be simpler to handle your issue, I'll open an issue to refractor stretch with the choose of letterbox and this sub-option.

Sylph commented 12 years ago

Ah interesting. The config.letterBoxClipping is actually the boolean to activate that black bars, but renaming it to config.blackbars would work as well. By default it's false, so stretched would not have the black bars, unless it's set to true.

Interesting that the gx/gy have problem with that. I thought I made sure there was no error.

Sylph commented 12 years ago

Okay the error is i accidentally removed the *.5 on the 'else' (line 123-128), so the offset is too far

        if SCREEN_WIDTH < DEVICE_WIDTH then
            SCREEN_X_OFFSET = (DEVICE_WIDTH - SCREEN_WIDTH)*.5
        end
        if SCREEN_HEIGHT < DEVICE_HEIGHT then
            SCREEN_Y_OFFSET = (DEVICE_HEIGHT - SCREEN_HEIGHT)*.5
        end

would fix it. I've just recommited.

So the RNScreen is fine the way I have it.

MattiaFortunati commented 12 years ago

Check this issue, I created it as a reminder: https://github.com/ymobe/rapanui/issues/77

Sylph commented 12 years ago

Sounds good. :)

Sylph commented 12 years ago

Ah yeah the way i do it is basically just scaling graphic design upward to follow the screen aspect ratio, and then let moai stretch that. That way nothing get lost, and the entire screen get used. Though that may be obvious.

MattiaFortunati commented 12 years ago

Yo!

I close this issue, since we moved to issue #77. ;D

Ps: wow! Great! Github automatically linked it !