GeeXLab gh_polyline wideline

Started by Bat2K, September 26, 2019, 06:38:21 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Bat2K

Hi,

I'm trying to render sort of a gizmo (red, green, blue) axes tripod over the object and currently I achieved it with empty gh_object with 3 attached axis aligned lines. However what I want is to have lines with width. I tried to use gh_polyline's wideline but with no success - it does render the poly, however it is 1px thick.

Also it's not clear what is the meaning of the first argument of the wideline_create (num_vertices). If my poly is 4 segments and 5 vertices should i use 5? then what does method wideline_add_point does? (expectation is that I will be able to create poly with 0 vertices and add them one by one extending the vertex buffer, however what happening is segfault).

Absence of any example made me ask it here:)
GeeXLab 0.29.2 Python3 (3.6.9) on Ubuntu 19.04 Intel HD Graphics, Opengl 4.3 core.

Thanks in advance!


JeGX

There is a wideline demo in the new OpenGL 3.2 demopack:
https://www.geeks3d.com/hacklab/20190921/opengl-3-2-demopack-for-geexlab/

The demo d09-wide-line-geometry-shader should help you.

Indeed, the wideline API has some weird names. I should rework these functions one day.

gh_polyline.wideline_create() allocates memory for the specified number of points. Then you can set points with
gh_polyline.wideline_add_point().   wideline_set_point() would have been a better name!

And if you want a polyline with 1 seg and 2 points, you pass 2 to gh_polyline.wideline_create(). You can also pass a number of points greater than the number of points you really need.

GeeXLab - wideline demo







Bat2K

Thank you! Indeed I found the demo I've missed previously. As far as I understood the role of the wideline is to build vertex buffer resulting in line segments with certain thinkness, but in any way to get that thickness in the fragments I either need a proper fs or gs+fs shader.

I also see one more behavior that make ask a questions (if the rule is "new question - new forum topic" then pls let me know so i will rearrange): when I have a hieararchy of objects (gh_mesh->gh_object.create()->gh_utils.create_line, so i have a mesh with child pivot who has 3 lines attached as children) it looks like gh_object.render(topmost_parent_in_the_hierarchy) renders all the hierarchy at once.

Is it the expected behaviour? If so, then how to address the situation when i want to render children with different gpu program - guess there's a material system for that pupose?

Many thanks for help!

JeGX

Quote from: Bat2K on September 27, 2019, 09:20:46 AM
Thank you! Indeed I found the demo I've missed previously. As far as I understood the role of the wideline is to build vertex buffer resulting in line segments with certain thinkness, but in any way to get that thickness in the fragments I either need a proper fs or gs+fs shader.
yes! wideline functions of gh_polyline essentially build the vertex buffer with all necessary info (points to quad and adjacency). A GPU program with a geometry shader is then required to render the wideline.


Quote from: Bat2K on September 27, 2019, 09:20:46 AM
I also see one more behavior that make ask a questions (if the rule is "new question - new forum topic" then pls let me know so i will rearrange): when I have a hieararchy of objects (gh_mesh->gh_object.create()->gh_utils.create_line, so i have a mesh with child pivot who has 3 lines attached as children) it looks like gh_object.render(topmost_parent_in_the_hierarchy) renders all the hierarchy at once.

Is it the expected behaviour? If so, then how to address the situation when i want to render children with different gpu program - guess there's a material system for that pupose?

There are two ways to render a hierarchy:

1 - the simple way is to render the root node and the whole hierarchy is rendered using the GPU program and textures that are bound before. To have a particular GPU program per child, you have to create materials, assign GPU program to each material and then assign a material to a child.

- material API: https://www.geeks3d.com/geexlab/reference/scripting_material.php
- gh_object.add_material(): https://www.geeks3d.com/geexlab/reference/scripting_object.php#add_material

The material management currently works only for meshes and derivatives like polylines. That should be your case.


2 - the custom way: you render every object in your hierarchy manually with gh_object.render(). Parent-child transformation is handled by GeeXLab so you don't have to take care of this problem. Since you control the rendering of an object, you can bind any GPU program / texture before the rendering.

Do some tests and let me know if you have issues...

Bat2K

#4
Thanks!
Just one small detail regarding "2 - the custom way" - did you meant "gh_object.render_geometry" instead of "gh_object.render"?

EDIT:
I doublechecked myself and render_geometry worked for me :)
EDIT;

Because otherwise I didn't get how the "custom way" is different from the "simple way is to render the root node and the whole hierarchy is rendered using the GPU program and textures that are bound before".

Currently I use the gh_object.render on the root node of the hierarchy and all the hierarchy is render like as you described in the "simple way" scenario. So beyond the material system scenario i only see 2 workarounds - call the render function which doesn't go down the hierarchy (e.g. render_geometry probably is my guess) or disjoint hierarchy before rendering (which is senseless in terms of node system usability of course).

Small subquestion - I didn't find any function in the API for getting object bbox, while there's a function to check frustrum/aa bbox collision - which makes me think you have bboxes internally for all the meshes. Do you have a plan (if internally of course you do manage bboxes) to expose those as a part of the API?

Many thanks for the timely answers and a great tool!



JeGX

Quote from: Bat2K on September 27, 2019, 02:06:04 PM
Just one small detail regarding "2 - the custom way" - did you meant "gh_object.render_geometry" instead of "gh_object.render"?

Nope, the custom way is more something like:

INIT script

gizmo = gh_object.create()
box1 =gh_mesh.create_box(...)
box2 =gh_mesh.create_box(...)

gh_object.add_child(gizmo, box1)
gh_object.add_child(gizmo, box2)


FRAME script - simple way: the whole hierarchy will use the GPU program "prog" for rendering

-- You can render all hierarchy in one call:
gh_gpu_program.bind(prog)
gh_object.render(gizmo)


OR

FRAME script - custom way: each child is rendered manually:

gh_gpu_program.bind(prog01)
gh_object.render(box1)

gh_gpu_program.bind(prog02)
gh_object.render(box2)



And if you attach a material (with a GPU program) to an object, the GPU program of the material will be automatically bound:

FRAME script - simple way:

gh_object.render(gizmo)


OR

FRAME script - custom way:

gh_object.render(box1)

gh_object.render(box2)





Quote from: Bat2K on September 27, 2019, 02:06:04 PM
EDIT:
I doublechecked myself and render_geometry worked for me :)
EDIT;

gh_object.render_geometry() works but you need to call gh_object.update_automatic_uniforms() before in order to have automatic uniform like gxl3d_ViewMatrix properly correctly set.


Quote from: Bat2K on September 27, 2019, 02:06:04 PM
Small subquestion - I didn't find any function in the API for getting object bbox, while there's a function to check frustrum/aa bbox collision - which makes me think you have bboxes internally for all the meshes. Do you have a plan (if internally of course you do manage bboxes) to expose those as a part of the API?

Yes the doc is far from complete, sorry  :(  It takes a lot of time to maintain a tool like GeeXLab and the doc is often the first victim. But the forum is there!

Try:

gh_object.bounding_volume_update(obj_id)
x, y, z = gh_object.bounding_volume_get_size(obj_id)
x, y, z, radius = gh_object.bounding_volume_get_center_radius(obj_id)

state = gh_camera.frustum_check_object_aa_box(camera, object)
state = gh_camera.frustum_check_object_sphere(camera, object)
state = gh_camera.frustum_check_sphere(camera, radius, x, y, z)
state = gh_camera.frustum_check_point(camera, x, y, z)

and  maybe:
gh_camera.frustum_update(camera)


Let me know!

Bat2K

Indeed! I didn't think about it before myself, but dir(gh_package) showed me there's a lot of cool stuff available that was not documented :) Thanks for pointing this out.

JeGX

All public functions (documented and non-documented) are listed here:

http://www.geeks3d.com/geexlab/reference/scripting_all_functions.php

Don't hesitate to ask if you need details about a function.