Problems with OpenGl_View and OpenCascade 7.3

Hi,

I am using OpenCascade since Version 6.8 and currently 7.0.
Now I am facing some problems when updating to 7.3
The problem is the usage of a UserView as recommended in the Upgrade notes to OpenCascade Version 7.0 for an own OpenGL-Drawing

class UserView : public OpenGl_View
void UserView :: render(...) {
    // OpenCascade rendering
    OpenGl_View::render(theProjection, theReadDrawFbo, theOitAccumFbo, theToDrawImmediate);
    glPushMatrix();
    glLightfv(...);
    pOwnOpenGLDrawer->Draw();
    glPopMatrix();
}

This works fine with OCC 7.0 but not with OCC 7.3. All of my own OpenGL-Drawings do not move anymore and seem to be fixed to a [0,1]-area.
It seems that the OpenGL-matrices are not available (applied) anymore. Perhaps this has to do with the change in the OpenGL-Shader:
"OpenGl_Context::ApplyModelViewMatrix() now checks if a matrix differs from the  already  set  one  before  modifying  state  in  Shader  Manager.  This  avoids  redundant state changes; matrix uploads onto GPU and recomputation of inverted matrices."
Does anyone face the same problem or know a methode to force the updating of the OpenGL-matrices?
Thanks in advance,
Alex

Kirill Gavrilov's picture

Fixed-function pipeline is deprecated in OpenGL for a long time, and OCCT doesn't use it anymore by default (see OCCT release notes history).
The best approach will be porting your code to use GLSL programs (see existing code in OpenGl package as a reference/hint),
As a fast workaround you may, however, enabled FFP code in OCCT via OpenGl_GraphicDriver Caps, but this functionality might be completely removed in next releases..
 

924112424_150196's picture

Hello Kirill​,

I am learning how to use shader in opencascade.

I have read the code about vshaderprog in ViewerTest_OpenGlCommands.cxx. I tried to write a program but failed. 

Here is my code:

Handle(AIS_Shape) s = new AIS_Shape(mb.Shape());

Handle(Graphic3d_ShaderProgram) ashaderprog = new Graphic3d_ShaderProgram();

Handle(Graphic3d_ShaderObject) vs = Graphic3d_ShaderObject::CreateFromFile(Graphic3d_TOS_VERTEX, "D:\\ppm\\Vertex.vs");

Handle(Graphic3d_ShaderObject) fs = Graphic3d_ShaderObject::CreateFromFile(Graphic3d_TOS_FRAGMENT, "D:\\ppm\\Fragment.fs");

ashaderprog->AttachShader(vs);

ashaderprog->AttachShader(fs);

s->Attributes()->ShadingAspect()->Aspect()->SetShaderProgram(ashaderprog);

I have some questions:

Will the shader object be compiled when calling the function Graphic3d_ShaderObject::CreateFromFile()? How can i verify the compile status?

Do i need to link the shader program after attaching the shader objects to it?

Is there any other example about using shader in opencascade?

Thanks in advance.

Sorry for my poor English.

Best regards.

X WY

Kirill Gavrilov's picture

You can start from playing with customer shaders via Draw Harness interface using command vshaderprog (consider also taking a look into command source code).
Tcl script v3d/glsl/texture_multi1 shows very simple shader to start with,
and src/Shaders/PhongShading.fs + src/Shaders/PhongShading.vs pair shows sample GLSL program with lighting.

924112424_150196's picture

Hi, Kirill.

I am facing another problem.

I am trying to render shadows with shaders by shadow mapping, which means i need generate a frame buffer object to store the shadow map. I wonder how to generate a frame buffer in OpenCasCade. Or is there a better way to render shadows? 

Thanks in advance. 

Kirill Gavrilov's picture

I'm afraid that Graphic3d API is not flexible enough to define auxiliary off-screen frame buffers.
You will have to falling down to lower-level API like it is done in vuserdraw command (this is just a Hello World sample - you will need to learn classes or OpenGl package)
or patching TKOpenGl itself (after all, rendering shadows is nice to have feature in general).

P.S.: could you delete duplicated posts and avoid tripple-posting in future?

924112424_150196's picture

Thank you for your reply. It is very helpful.

And sorry about the duplicated posts. I have no idea why there are three posts. It seems that something went wrong when i posted the reply. 

I will be very careful next time i post a reply to avoid this. 

924112424_150196's picture

Hello,

i have read the source code of vuserdraw command in ViewerTest_OpenGlCommands.cxx.  I want to draw something using the Render() function, which means i need to create a OpenGl_Workspace as the parameter of the Render() function.  So i create a OpenGl_Workspace using a WNT_Window which is created by a dialog item in MFC. The problem is that i cannot see the view while the program runs successfully. Here is my code.

//create a window in a Dialog 

CWnd* cpwnd = GetDlgItem(IDC_STATIC_CP);

Handle(WNT_Window) cp_wnt_wnd = new WNT_Window(cpwnd->m_hWnd);

//create a OpenGl_Workspace

Handle(OpenGl_GraphicDriver) myglGraphicDriver = theApp.GetGraphicDriver();

Handle(OpenGl_Window) myglWindow = myglGraphicDriver->CreateRenderWindow(cp_wnt_wnd, (Aspect_RenderingContext)0);

Handle(OpenGl_Caps) myglCaps = &myglGraphicDriver->ChangeOptions();

Handle(Graphic3d_StructureManager) myG3dStructureCanager = new Graphic3d_StructureManager(myglGraphicDriver);

OpenGl_StateCounter* myglStateCounter = new OpenGl_StateCounter();

Handle(OpenGl_View) myglView = new OpenGl_View(myG3dStructureCanager, myglGraphicDriver, myglCaps, myglStateCounter);

Handle(OpenGl_Workspace) myglWorkSpace = new OpenGl_Workspace(myglView, myglWindow);

// the code below is the same as the code in Render().

Handle(OpenGl_Context) myglContext myglContext = myglWorkSpace->GetGlContext();

const OpenGl_AspectMarker* aMA = myglWorkSpace->AspectMarker();

aMA->Aspect()->Type();

const OpenGl_AspectText* aTA = myglWorkSpace->AspectText();

aTA->Aspect()->Font();

OpenGl_Vec4 aColor=myglWorkSpace->LineColor();

myglContext->ShaderManager()->BindLineProgram(Handle(OpenGl_TextureSet)(), Aspect_TOL_SOLID, Graphic3d_TOSM_UNLIT, Graphic3d_AlphaMode_Opaque, false, Handle(OpenGl_ShaderProgram)());

myglContext->SetColor4fv(aColor);

const OpenGl_Vec3 aVertArray[4] =

{

OpenGl_Vec3(-10.0,-20.0,-30.0),

OpenGl_Vec3(10.0, 20.0, -30.0),

OpenGl_Vec3(10.0, 20.0, 30.0),

OpenGl_Vec3(-10.0,-20.0,30.0),

};

Handle(OpenGl_VertexBuffer) aVertBuffer = new OpenGl_VertexBuffer();

aVertBuffer->Init(myglContext, 3, 4, aVertArray[0].GetData());

aVertBuffer->BindAttribute(myglContext, Graphic3d_TOA_POS);

glDrawArrays(GL_LINE_LOOP, 0, aVertBuffer->GetElemsNb());

aVertBuffer->UnbindAttribute(myglContext, Graphic3d_TOA_POS);

aVertBuffer->Release(myglContext.get());

The result has been uploaded as a png. It seems that the way i create a OpenGl_Workspace  is wrong. 

Thanks in advance.

Attachments: 
924112424_150196's picture

Hi, Kirill.

I am facing another problem.

I am trying to render shadows with shaders by shadow mapping, which means i need generate a frame buffer object to store the shadow map. I wonder how to generate a frame buffer in OpenCasCade. Or is there a better way to render shadows? 

Thanks in advance. 

924112424_150196's picture

Hi, Kirill.

I am facing another problem.

I am trying to render shadows with shaders by shadow mapping, which means i need generate a frame buffer object to store the shadow map. I wonder how to generate a frame buffer in OpenCasCade. Or is there a better way to render shadows? 

Thanks in advance. 

924112424_150196's picture

OK, i will read the command source code of vshaderprog and try again.

Thank you for your reply. It is very helpful.