Comments (9)
And this is the def for world3dA:
def world3dA(inHeightmap, inWidth, inDepth, inHeight, inTextureMap, inBumpMap, inSeaLevel):
DISPLAY = pi3d.Display.create(0, 0, 1280, 1024)
CAMERA = pi3d.Camera.instance()
base_tex = np.array(Image.open(inTextureMap))
# texture for land
base_gr = base_tex.copy()
ix = np.where(base_gr[:,:,2] > 20) # i.e. was blue
base_gr[ix[0], ix[1], 1] += 50 # increase green
base_gr[ix[0], ix[1], 2] = 0 # reduce blue
texg = pi3d.Texture(base_gr)
# texture for water
base_bl = base_tex.copy()
base_bl[:,:] = [0, 0, 60, 170] # uniform slightly transparent
texb = pi3d.Texture(base_bl)
grass_tex = pi3d.Texture('textures/grasstile_n.jpg')
w_norm = pi3d.Texture('textures/n_norm000.png')
shader = pi3d.Shader("uv_bump")
rshader = pi3d.Shader("uv_reflect")
mapwidth = inWidth
mapdepth = inDepth
mapheight = inHeight
mymap = pi3d.ElevationMap(inBumpMap, width=mapwidth, depth=mapdepth, height=mapheight, divx=199, divy=199,
ntiles=1, name="sub")
mymap.set_draw_details(shader, [texg, grass_tex], 200.0)
wmap = pi3d.ElevationMap(inBumpMap, width=mapwidth, depth=mapdepth, height=mapheight * 0.1, divx=199, divy=199,
ntiles=1, name="water", y=inSeaLevel)
wmap.set_draw_details(rshader, [texb, w_norm, texg], 50.0, 0.2)
rot = 0.0
tilt = 0.0
height = 20.0
viewHeight = 4
sky = 200
xm, ym, zm = 0.0, height, 0.0
onGround = False
mykeys = pi3d.Keyboard()
mymouse = pi3d.Mouse(restrict=False)
mymouse.start()
omx, omy = mymouse.position()
while DISPLAY.loop_running():
mx, my = mymouse.position()
rot -= (mx - omx) * 0.2
tilt -= (my - omy) * 0.2
omx = mx
omy = my
CAMERA.reset()
CAMERA.rotate(-tilt, rot, 0)
CAMERA.position((xm, ym, zm))
mymap.draw()
wmap.draw()
k = mykeys.read()
if k > -1:
if k == 48: # ESCAPE key - '0' Key
mykeys.close()
mymouse.stop()
DISPLAY.destroy()
break
elif k == 87 or k == 119: # FORWARDS key - 'W' Key
xm -= sin(radians(rot))
zm += cos(radians(rot))
elif k == 83 or k == 115: # BACKWARDS key - 'S' Key
xm += sin(radians(rot))
zm -= cos(radians(rot))
elif k == 82 or k == 114: # UPWARDS key - 'R' Key
ym += 2
onGround = False
elif k == 84 or k == 116: # DOWNWARDS key - 'T' Key
ym -= 2
ym -= 0.1
xm = limit(xm, -(mapwidth / 2), (mapwidth / 2))
zm = limit(zm, -(mapdepth / 2), (mapdepth / 2))
if ym >= sky:
ym = sky
ground = mymap.calcHeight(xm, zm) + viewHeight
if (onGround is True) or (ym <= ground):
ym = mymap.calcHeight(xm, zm) + viewHeight
onGround = True
from pi3d.
Hi, I will try too have a look at this later today. What hardware are you running on?
from pi3d.
Hi, I've had a quick look and there are a couple of things: 1. The argument naming (the diffuse texture is called '..elevation' and the elevation texture is called '..normal')! 2. I haven't really understood why you want to close and recreate the display window rather than just regenerate mymap
and wmap
, which would be much quicker and wouldn't cause any errors.
world3dA is effectively the main()
function and calling that from inside itself seem fraught with unnecessary problems. Maybe explain a bit more why you need to do that. If it turns out to be the only way they you probably should open and close each instance as a subprocess.
Paddy
from pi3d.
Hey Paddy, thanks for the quick reply.
I probably didn't explain myself too well :(
- I'm running on a Ryzen 7 with inbuilt Radeon graphics on Windows 10 (I do also have a GeForce GTX1650 in the same machine, but haven't tried with that yet)
- The naming is due to me creating a Grayscale Heightmap, a Normal Map and an Elevation Map (a coloured view of the world). These maps are generated (except the Normal Map) to be displayed in my graphical WorldEngine GUI, which generates worlds using plate tectonics etc.
- The 3D View is generated when the user clicks a button in the GUI and is meant to give them an idea what the world would look like in 3D. This is the reason I need to close and reopen the pi3d instance, as I can't leave the 3D view running when they are generating a different world.
The file I attached was just a test that I did to ensure that the blue screen always happened on the 2nd and subsequent attempts to create a new view. In my actual code, it's called from a main file where all my gui code is.
Hope that explains a bit more?
Thanks again
Shando
from pi3d.
OK. It sounds to be an interesting idea. I think you will have problems trying to close and reopen pi3d.Display
. It might be possible to do but the OpenGL side is all C function calls and that means 'unsafety' is built in! Especially calling from python through ctypes, which tends to have a go at doing what it thinks you want... fine until it stops working.
I think my approach would be to have my main()
function creating and holding an instance of the pi3d scene stuff as a class which would have the key checking as a public method and the texture and environment map creation as a public method. I will hack the code into an approximation of what I mean, as an example. If you don't want the pi3d window showing you can have a method to move it out of the way so you can't see it.
from pi3d.
Hi, this is a superficial re-structure of your zipped file. I've not done too much and not even tried running it so there are probably typos and other bugs/mistakes. However it gives you the idea of the approach I might take. You mention a button on the GUI so it will be critical what event loop you are using for that. Generally speaking I find it much better to hang pi3d off the GUI event loop rather than getting the two fighting. i.e. the while world.loop_running():
below would be a tk or pygame loop.
from math import sin, cos, radians
import pi3d
from PIL import Image
import numpy as np
WORLDS = (
('Maps/seed_32829_grayscale.png', 1024, 1024, 200, 'Maps/seed_32829_elevation.png', 'Maps/seed_32829_normal.png', 100),
('Maps/seed_11111_grayscale.png', 1024, 1024, 200, 'Maps/seed_11111_elevation.png', 'Maps/seed_11111_normal.png', 100),
('Maps/seed_42958_grayscale.png', 1024, 1024, 200, 'Maps/seed_42958_elevation.png', 'Maps/seed_42958_normal.png', 100),
('Maps/seed_2593_grayscale.png', 1024, 1024, 200, 'Maps/seed_2593_elevation.png', 'Maps/seed_2593_normal.png', 100),
('Maps/seed_32829_grayscale.png', 1024, 1024, 200, 'Maps/seed_32829_elevation.png', 'Maps/seed_32829_normal.png', 100)
)
def limit(value, inMin, inMax):
if value < inMin:
value = inMin
elif value > inMax:
value = inMax
return value
class World3dA:
def__init__(self, inHeightmap, inWidth, inDepth, inHeight, inTextureMap, inBumpMap, inSeaLevel):
self.DISPLAY = pi3d.Display.create(0, 0, 1280, 1024)
self.CAMERA = pi3d.Camera.instance()
self.grass_tex = pi3d.Texture('textures/grasstile_n.jpg')
self.w_norm = pi3d.Texture('textures/n_norm000.png')
self.shader = pi3d.Shader("uv_bump")
self.rshader = pi3d.Shader("uv_reflect")
self.viewHeight = 4
self.sky = 200
self.mykeys = pi3d.Keyboard()
self.mymouse = pi3d.Mouse(restrict=False)
self.mymouse.start()
self.create_world(inHeightmap, inWidth, inDepth, inHeight, inTextureMap, inBumpMap, inSeaLevel)
self.keep_looping = True
def create_world(self, inHeightmap, inWidth, inDepth, inHeight, inTextureMap, inBumpMap, inSeaLevel):
base_tex = np.array(Image.open(inTextureMap))
# texture for land
base_gr = base_tex.copy()
ix = np.where(base_gr[:,:,2] > 20) # i.e. was blue
base_gr[ix[0], ix[1], 1] += 50 # increase green
base_gr[ix[0], ix[1], 2] = 0 # reduce blue
texg = pi3d.Texture(base_gr)
# texture for water
base_bl = base_tex.copy()
base_bl[:,:] = [0, 0, 60, 170] # uniform slightly transparent
texb = pi3d.Texture(base_bl)
self.mapwidth = inWidth
self.mapdepth = inDepth
self.mapheight = inHeight
self.mymap = pi3d.ElevationMap(inBumpMap, width=self.mapwidth, depth=self.mapdepth, height=self.mapheight, divx=199, divy=199,
ntiles=1, name="sub")
self.mymap.set_draw_details(self.shader, [texg, grass_tex], 200.0)
self.wmap = pi3d.ElevationMap(inBumpMap, width=self.mapwidth, depth=self.mapdepth, height=self.mapheight * 0.1, divx=199, divy=199,
ntiles=1, name="water", y=inSeaLevel)
self.wmap.set_draw_details(self.rshader, [texb, w_norm, texg], 50.0, 0.2)
self.rot = 0.0
self.tilt = 0.0
self.height = 20.0
self.xm, self.ym, self.zm = 0.0, self.height, 0.0
self.onGround = False
self.omx, self.omy = self.mymouse.position()
def loop_running(self):
if self.keep_looping and self.DISPLAY.loop_running():
mx, my = mymouse.position()
self.rot -= (mx - self.omx) * 0.2
self.tilt -= (my - self.omy) * 0.2
self.omx = mx
self.omy = my
self.CAMERA.reset()
self.CAMERA.rotate(-self.tilt, self.rot, 0)
self.CAMERA.position((self.xm, self.ym, self.zm))
self.mymap.draw()
self.wmap.draw()
return True
else:
return False
def stop_looping(self):
self.keep_looping = False
self.mykeys.close()
self.mymouse.stop()
self.DISPLAY.destroy()
def read_key_and_move(self):
k = self.mykeys.read()
if k > -1:
if k == 48: # ESCAPE key - '0' Key
return k # return early and do scene change or stop
elif k == 87 or k == 119: # FORWARDS key - 'W' Key
self.xm -= sin(radians(rot))
self.zm += cos(radians(rot))
elif k == 83 or k == 115: # BACKWARDS key - 'S' Key
self.xm += sin(radians(rot))
self.zm -= cos(radians(rot))
elif k == 82 or k == 114: # UPWARDS key - 'R' Key
self.ym += 2
self.onGround = False
elif k == 84 or k == 116: # DOWNWARDS key - 'T' Key
self.ym -= 2
# only do this if a move key was pressed?
self.ym -= 0.1
self.xm = limit(self.xm, -(self.mapwidth / 2), (self.mapwidth / 2))
self.zm = limit(self.zm, -(self.mapdepth / 2), (self.mapdepth / 2))
if self.ym >= self.sky:
self.ym = self.sky
self.ground = mymap.calcHeight(self.xm, self.zm) + self.viewHeight
if self.onGround or (self.ym <= self.ground):
self.ym = mymap.calcHeight(self.xm, self.zm) + self.viewHeight
self.onGround = True
return None
def main():
my_var = 0
world = World3dA(*WORLDS[my_var])
my_var += 1
while world.loop_running():
if world.read_key_and_move() == 48:
if my_var >= len(WORLDS):
world.stop_looping()
else:
world.create_world(*WORLDS[my_var])
my_var += 1
if __name__ == '__main__':
main()
from pi3d.
Hey Paddy,
Thanks for the help. It certainly pointed me in the right direction and, with some messing about with 'win32gui' and 'win32con' I now have the 3D window not only pausing and updating correctly every time the button is pressed, but also being moved in front of the main GUI window when running and back behind it when not :)
Thanks again for the help
Shando
from pi3d.
Great, look forward to seeing the finished product.
from pi3d.
Hey Paddy,
Not sure if you're a Windoze person, but my WorldEngine GUI is now complete (as far as I can tell!). You can access the GitHub repository here https://github.com/Shando/WorldEngine_UI. In the 'WorldEngine/worldengine/dist/wegui' folder there is the 'wegui.exe' file that should run the whole shebang without needing to set up any special environments.
There is one prebuilt "World" included (seed_11111.world), which you can load up to view the Maps / 3D. Unfortunately, due to its size, I've had to use the GitHub LFS, so not sure if I still have any bandwidth left? If it doesn't download, you can also download it from here https://1drv.ms/u/s!Au7DMGV6totzgsA7TIAjmXee_3HegA?e=CIm8Kt
Thanks for your help with this.
Shando
from pi3d.
Related Issues (20)
- problems running on fedora28 HOT 8
- position a gui element in corner of windows - track resizes? HOT 2
- "X11 needs to be running" on Ubuntu Desktop 19.10 (intel cpu/gpu) HOT 4
- Name only shows for 1 second, and disappears. HOT 2
- Memory not freed when free_after_load is True HOT 5
- How to add touchscreen support HOT 2
- 'assert r' error due to old API usage and advice on latest API usage HOT 16
- pi3d on Ubuntu 20.04 HOT 11
- DISPLAY_CONFIG_NO_RESIZE makes the window resizable
- pi3d.Slice() unexpected angle HOT 4
- gltf support? HOT 2
- problem running examples in CLI mode (no context) HOT 2
- Run PictureFrame.py without indexing? HOT 1
- Win 10 not every example is working HOT 6
- AttributeError: 'NoneType' object has no attribute 'glActiveTexture' HOT 6
- AttributeError: 'DisplayOpenGL' object has no attribute 'context' HOT 1
- Not work on Win 10 Py 3.11 HOT 2
- pi3d 2.49 not working with Pillow 10.0.0
- Windows Exception in DisplayOpenGL.py HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pi3d.