Change screen resolution at runtime

I FINALLY GOT IT! So i was looking for an easy way to change game resolution while the game was running. I know no scrpting (yet :p) But for help, I posted my question on facebook and there ThaTimst3r gave me a script he got from tutorialsforblender3d.com :smiley: It’s so simple! just conect the script with any sensor you want with ‘Tap’ turned on! The game will get the resolution set in the script (make two or three copies, all with different resolutions if you want a lot of game resolutions for the gamer to play your game :D) Note: this affects the standalone player so you can check it’s working by running the standalone player
Here’s the script:

import bge
rend = bge.render

x = 640
y = 480

rend.setWindowSize( x, y)

here is what i use, and some extra render functions:


from bge import logic, render


def main():
    
    cont = logic.getCurrentController()
    own = cont.owner
    
    if not 'render_settings' in own:
        
        render.setMipmapping(2)
        render.setAnisotropicFiltering(16) # 1, 2, 4, 8, 16
        render.VSYNC_ON # OFF or ADAPTIVE
        render.setFullScreen(True)
        render.setWindowSize(1920, 1200)
        render.enableMotionBlur(1.0) # 0.0-1.0
        
        own['render_settings'] = True


def other_settings():
    
    render.KX_TEXFACE_MATERIAL
    #Materials as defined by the texture face settings.


    render.KX_BLENDER_MULTITEX_MATERIAL
    #Materials approximating blender materials with multitexturing.


    render.KX_BLENDER_GLSL_MATERIAL
    #Materials approximating blender materials with GLSL
    
    render.getWindowWidth()
    #Gets the width of the window (in pixels)
    #Return type:    integer
    
    render.getWindowHeight()
    #Gets the height of the window (in pixels)
    #Return type:    integer
    
    render.getFullScreen()
    #Returns whether or not the window is fullscreen.
    #Return type:    bool
    
    render.makeScreenshot(filename)
    #Writes a screenshot to the given filename.
    #If filename starts with // the image will be saved relative to the current directory. If the filename contains # it will be replaced with the frame number.
    #The standalone player saves .png files. It does not support color space conversion or gamma correction.
    #When run from Blender, makeScreenshot supports all Blender image file formats like PNG, TGA, Jpeg and OpenEXR. Gamma, Colorspace conversion and Jpeg compression are taken from the Render settings panels.


    render.enableVisibility(visible)
    #Doesn’t really do anything...


    render.showMouse(visible)
    #Enables or disables the operating system mouse cursor.


    render.setMousePosition(x, y)
    #Sets the mouse cursor position.


    render.setBackgroundColor(rgba)
    #Sets the window background color.


    render.setMistColor(rgb)
    #Sets the mist color.


    render.setAmbientColor(rgb)
    #Sets the color of ambient light.


    render.setMistStart(start)
    #Sets the mist start value. Objects further away than start will have mist applied to them.


    render.setMistEnd(end)
    #Sets the mist end value. Objects further away from this will be colored solid with the color set by setMistColor().


    render.disableMist()
    #Disables mist.
    #Note Set any of the mist properties to enable mist.
    
    render.setEyeSeparation(eyesep)
    #Sets the eye separation for stereo mode. Usually Focal Length/30 provides a confortable value.
    #Parameters:    eyesep (float) – The distance between the left and right eye.
    
    render.getEyeSeparation()
    #Gets the current eye separation for stereo mode.
    #Return type:    float
    
    render.setFocalLength(focallength)
    #Sets the focal length for stereo mode. It uses the current camera focal length as initial value.
    #Parameters:    focallength (float) – The focal length.
    
    render.getFocalLength()
    #Gets the current focal length for stereo mode.
    #Return type:    float
    
    render.setMaterialMode(mode)
    #Set the material mode to use for OpenGL rendering.
    #Note Changes will only affect newly created scenes.
    
    render.getMaterialMode(mode)
    #Get the material mode to use for OpenGL rendering.
    #Return type:    KX_TEXFACE_MATERIAL, KX_BLENDER_MULTITEX_MATERIAL, KX_BLENDER_GLSL_MATERIAL
    
    render.setGLSLMaterialSetting(setting, enable)
    #Enables or disables a GLSL material setting.


    render.getGLSLMaterialSetting(setting, enable)
    #Get the state of a GLSL material setting.
    #Return type:    boolean
    
    render.getAnisotropicFiltering()
    #Get the anisotropic filtering level used for textures.
    #Return type:    integer (one of 1, 2, 4, 8, 16)


    render.getMipmapping()
    #Get the current mipmapping setting.
    #Return type:    RAS_MIPMAP_NONE, RAS_MIPMAP_NEAREST, RAS_MIPMAP_LINEAR


    render.drawLine(fromVec, toVec, color)
    #Draw a line in the 3D scene.
    #Parameters:    
    #fromVec (list [x, y, z]) – the origin of the line
    #toVec (list [x, y, z]) – the end of the line
    #color (list [r, g, b]) – the color of the line


    render.disableMotionBlur() 
    #Disable the motion blur effect.
    
    render.getVsync()
    #Get the current vsync value
    #Return type:    One of VSYNC_OFF, VSYNC_ON, VSYNC_ADAPTIVE
    
main()

#edit

make two ar three copies, all with different resolutions if you want a lot of game resolutions for the gamer to play your game
you can use a property to define the resolution so you dont need a script for every resolution out there.

cool how can i attach it in the logic,
is it just like
if prop.“for ex” =1
rez = 800x600
if prop. “for ex”=2
rez = 1020x800

that is a way to do it yes. or trough a menu, so the user can select the resolution. or you can scan for window heigth/width and set those values as a resolution. in this case there are many options to handle it.

this is awesome, but i really prefer if you can show us a screen shoot of the logic brick if you don’t mind, ,it get really hard to attach it

One thing guys.The script I gave works on standalone only

nice script cotax by the way :smiley: that works too!

Great script cotax! Will be featured on www.blender-academy.com

this is awesome, but i really prefer if you can show us a screen shoot of the logic brick if you don’t mind, ,it get really hard to attach it

Ok, i extended the script a bit, use the code below, it will automatic detect the monitor resolution and sets it to the resolution used by the (windows)user, in other words you always have the correct resolution now

edit

i forgot to say: the script uses 2 variables (width, height), set those with a property and it does what you want(you can then remove the additional lines of code). If you dont know how that works, search for acces object properties, should put you into the right direction.

Great script cotax! Featured on www.blender-weekly.com

Thank you, glad you like it :slight_smile:


from bge import logic, render
import ctypes




def main():
    
    cont = logic.getCurrentController()
    own = cont.owner
    
    if not 'render_settings' in own:
        
        #sets the correct resolution for every Monitor
        user32 = ctypes.windll.user32
        monitor_width = user32.GetSystemMetrics(0)
        monitor_height = user32.GetSystemMetrics(1)
        
        render.setWindowSize(monitor_width, monitor_height)
        render.setFullScreen(True)
        
        render.setMipmapping(2)
        render.setAnisotropicFiltering(16) # 1, 2, 4, 8, 16
        render.VSYNC_ON # OFF or ADAPTIVE
        render.enableMotionBlur(1.0) # 0.0-1.0
        
        own['render_settings'] = True

cool ,man so i also want to do a fullscreen not fullscreen button but i never maneg,d to do it
but this is great man :slight_smile:

actually there’s a checkbox to automatically set the resolution as the windows screen resolution besides the “fullscreen” checkbox.
Anyways, this is a great script too

@cotax You can use getDisplayDimensions instead, which I have done two years ago. This way it also should work on Linux and Mac too.
https://www.blender.org/api/blender_python_api_2_77_1/bge.render.html?highlight=getdisplay#bge.render.getDisplayDimensions
https://developer.blender.org/D648

yes it looks good, but you need more calculations in order to detect if he is using 1 or multiple screens, due to the resoluton gets counted as 1 for all monitors.

I don’t understand you, getDisplayDimensions returns exactly the same values as in your example code. GetSystemMetrics(SM_CXSCREEN) = 0 and GetSystemMetrics(SM_CYSCREEN) = 1.


        #sets the correct resolution for every Monitor
        user32 = ctypes.windll.user32
        monitor_width = user32.GetSystemMetrics(0)
        monitor_height = user32.GetSystemMetrics(1)

I don’t understand you, getDisplayDimensions returns exactly the same values as in your example code

That can be but as far as i know user32 grabs the monitor screen size from the main monitor not from all of them.
while getDisplayDimensions() can grab em all at the same time, adding to the same value.

bge.render.getDisplayDimensions()Get the display dimensions, in pixels, of the display (e.g., the monitor). Can return the size of the entire view, so the combination of all monitors; for example, (3840, 1080) for two side-by-side 1080p monitors.
[TABLE=“class: docutils field-list”]
[TR=“class: field-odd field”]
[TH=“class: field-name, bgcolor: #EEDDEE, align: left”]Return type:[/TH]
tuple (width, height)
[/TR]
[/TABLE]

As I have written above getDisplayDimensions returns GetSystemMetrics(0) and GetSystemMetrics(1).
You can believe me because I have done this patch. Above is the link to my patch D648 where you can see that it gets the values from getMainDisplayDimensions(). Here is a sipped of the source code (GHOST_SystemWin32.cpp).


void GHOST_SystemWin32::getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const
{
    width = ::GetSystemMetrics(SM_CXSCREEN);
    height = ::GetSystemMetrics(SM_CYSCREEN);
}

So no matter which value you will get with user32.GetSystemMetrics(0)/(1), getDisplayDimensions will rerun the same.
There also some other getMainDisplayDimensions for the other OS. So maybe getDisplayDimensions will return other values on this OS. But I think not, because otherwise Blender won’t work correctly on the other OS.

I don’t know why the original API description (look at D648) has been changed.
But as I know GetSystemMetrics(SM_CXSCREEN)/(SM_CYSCREEN) returns the actual chosen desktop resolution (not the native physical maximum resolution) for the main display. https://msdn.microsoft.com/en-us/library/windows/desktop/ms724385(v=vs.85).aspx
It is possible to span the main monitor over two displays with some Nvidia drivers (not extened desktop). In this case it will return the spanned resolution.

The description was probably changed when xinerama was dropped.

Dual monitors on Linux:

print(bge.render.getDisplayDimensions())
(3840, 1080)

With xinerama patch (UPBGE)

print(bge.render.getDisplayDimensions())
(1920, 1080)

Shouldn’t affect Windows