sciapp / gr

GR framework: a graphics library for visualisation applications
Other
327 stars 54 forks source link

How can I use gr3.drawcubemesh? #146

Closed Roy-Kid closed 2 years ago

Roy-Kid commented 2 years ago

I want to use drawcubemesh to draw a box frame, but it seems to not have an implementation. So did I use it wrong or didn't I finish it

FlorianRhiem commented 2 years ago

Hey @Roy-Kid,

by calling gr3.drawcubemesh you are adding a cube mesh to the scene. You can then render the scene with a command such as gr3.export or gr3.getimage. Try calling gr3.export("output.png", 1000, 1000) after calling gr3.drawcubemesh to export the scene as a 1000x1000 pixels PNG file.

Roy-Kid commented 2 years ago

Sorry for asking this stupid question. I am developing a molecule visualization package based on mogli. I also use glfw as the context of gr. I look up the docs but I don't find drawcubemesh API ref. I don't understand

GR3API void gr3_drawcubemesh(int n, const float *positions, const float *directions, const float *ups,
                             const float *colors, const float *scales)
{
  GR3_DO_INIT;
  gr3_drawmesh(context_struct_.cube_mesh, n, positions, directions, ups, colors, scales);
}

if I want to draw a cube box with (2,3,4) in origin or a Parallelepiped, how should I write commands?

FlorianRhiem commented 2 years ago

Are you using C or Python? As you wrote gr3.drawcubemesh in the title I assumed Python, but since you're quoting the C implementation, I will assume C for this reply.

Here's a fairly minimal demo for using gr3_drawcubemesh, gr3_cameralookat and gr3_export:

#include <gr3.h>

int main() {
    float positions[] = {2, 3, 4};
    float directions[] = {1, 0, 0};
    float ups[] = {0, 1, 0};
    float colors[] = {1, 0, 0};
    float scales[] = {1, 1, 1};
    gr3_drawcubemesh(1, positions, directions, ups, colors, scales);
    gr3_cameralookat(0, 0, 10, 2, 3, 4, 0, 1, 0);
    gr3_export("test.png", 1000, 1000);
}
  1. gr3_drawcubemesh adds a box to the scene at a specific position (positions), with an orientation (directions and ups), a color (colors) and scaling factors (scales).
  2. gr3_cameralookat sets the camera position (0, 0, 10), camera focus point (2, 3, 4 so that we look at the box) and camera up vector (0, 1, 0).
  3. gr3_export then creates a PNG file with the current scene viewed with that camera set up.

This results in the following picture: Test


Now, when you switch to using GLFW, you will need to use gr3_drawimage instead of gr3_export. For xmin, xmax, ymin and ymax set the region of the viewport that GR3 should draw in, for width and height set the resolution in pixels and for drawable_type set GR3_DRAWABLE_OPENGL or 1.

To draw a generic parallelepiped that doesn't have only right angles, you will need to define the mesh based on triangles using gr3_createmesh.

Roy-Kid commented 2 years ago

Thanks! That is enough for me to understand args' meaning. Because there are few references, I may not be able to solve the problem. Can I mix Python version GR3 with pyopengl? For example, if a method does not have GR implementation, can I directly use OpenGL instead of drawmesh?

FlorianRhiem commented 2 years ago

Somewhat. When you call gr3.drawimage, GR3 will fill the area of the framebuffer with that scene. If you want to use the framebuffer that is current with OpenGL, call gr3.usecurrentframebuffer() before calling drawimage. Any previous content will be cleared with glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);. So you cannot first draw content to the framebuffer, then draw on top of that with GR3 and expect the original content to stay shown. However if you draw with GR3 first, you can then use OpenGL to add on to the framebuffer as you wish.

Roy-Kid commented 2 years ago

OK, I understand. Thanks for your patient help. I learn the mogli example and the drawmolecule() in source code, and I can explore it slowly. I will follow this work and write some blogs if I can.