Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use advance opengl 3.0 inaccurate display #1273

Open
luohuiiqng opened this issue Nov 16, 2023 · 16 comments
Open

use advance opengl 3.0 inaccurate display #1273

luohuiiqng opened this issue Nov 16, 2023 · 16 comments

Comments

@luohuiiqng
Copy link

Now I want to use advanced opengl in 3.7.0, but there are some issues. After running the example, the model did not display correctly. Is there a problem with my code? I enable advanced opengl attributes when compiling the source code.


#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include <osg/GraphicsContext>
#include <osg/Camera>
#include <osg/Viewport>
#include <osg/StateSet>
#include <osg/Program>
#include <osg/Shader>
#include <osgUtil/Optimizer>

#include <osgGA/StateSetManipulator>
#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TerrainManipulator>
#include <osgGA/DriveManipulator>

#include <osgViewer/ViewerEventHandlers>

void configureShaders(osg::StateSet* stateSet)
{
const std::string vertexSource =
"#version 130 \n"
" \n"
"uniform mat4 osg_ModelViewProjectionMatrix; \n"
"uniform mat3 osg_NormalMatrix; \n"
"uniform vec3 ecLightDir; \n"
" \n"
"in vec4 osg_Vertex; \n"
"in vec3 osg_Normal; \n"
"out vec4 color; \n"
" \n"
"void main() \n"
"{ \n"
" vec3 ecNormal = normalize( osg_NormalMatrix * osg_Normal ); \n"
" float diffuse = max( dot( ecLightDir, ecNormal ), 0. ); \n"
" color = vec4( vec3( diffuse ), 1. ); \n"
" \n"
" gl_Position = osg_ModelViewProjectionMatrix * osg_Vertex; \n"
"} \n";
osg::Shader* vShader = new osg::Shader(osg::Shader::VERTEX, vertexSource);

const std::string fragmentSource =
    "#version 130 \n"
    " \n"
    "in vec4 color; \n"
    "out vec4 fragData; \n"
    " \n"
    "void main() \n"
    "{ \n"
    "    fragData = color; \n"
    "} \n";
osg::Shader* fShader = new osg::Shader(osg::Shader::FRAGMENT, fragmentSource);

osg::Program* program = new osg::Program;
program->addShader(vShader);
program->addShader(fShader);
stateSet->setAttribute(program);

osg::Vec3f lightDir(0., 0.5, 1.);
lightDir.normalize();
stateSet->addUniform(new osg::Uniform("ecLightDir", lightDir));

}

int main(int argc, char** argv)
{
std::vectorstd::string fileList;
fileList.push_back("glider.osg");
// 创建节点.
osg::ref_ptrosg::Node root = osgDB::readRefNodeFiles(fileList);
if (root == NULL)
{
osg::notify(osg::FATAL) << "Unable to load model from command line." << std::endl;
return(1);
}

osgUtil::Optimizer optimizer;
optimizer.optimize(root.get(), osgUtil::Optimizer::ALL_OPTIMIZATIONS | osgUtil::Optimizer::TESSELLATE_GEOMETRY);

// 应该初始化gl变量的值.
configureShaders(root->getOrCreateStateSet());

const int width(800), height(450);
const std::string version("3.0");

// 应该是创并配置设备(画板).
osg::ref_ptr< osg::GraphicsContext::Traits > traits = new osg::GraphicsContext::Traits();
// 渲染窗口的x坐标.
traits->x = 20;
// 渲染窗口的y坐标.
traits->y = 30;
// 渲染窗口的宽.
traits->width = width;
// 渲染窗口的高.
traits->height = height;
// 是否出现工具栏.
traits->windowDecoration = true;
// 是否启用双缓冲.
traits->doubleBuffer = true;
// 设置gl版本.
traits->glContextVersion = version;
// unknow 注释掉也未观察到影响.
traits->readDISPLAY();
// unknow 注释掉也未观察到影响.
traits->setUndefinedScreenDetailsToDefaultScreen();
// 应是创并gl上下文.
osg::ref_ptr< osg::GraphicsContext > gc = osg::GraphicsContext::createGraphicsContext(traits.get());
if (!gc.valid())
{
    osg::notify(osg::FATAL) << "Unable to create OpenGL v" << version << " context." << std::endl;
    return(1);
}

// osg观察器.
osgViewer::Viewer viewer;

// Create a Camera that uses the above OpenGL context.
osg::Camera* cam = viewer.getCamera();

// 添加状态事件.
viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));

// 窗口大小变化事件.
viewer.addEventHandler(new osgViewer::WindowSizeHandler);

// 添加一些常用状态设置
viewer.addEventHandler(new osgViewer::StatsHandler);

// 设置操作器
{
    osg::ref_ptr<osgGA::KeySwitchMatrixManipulator>keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;

    keyswitchManipulator->addMatrixManipulator('1', "Trackball", new osgGA::TrackballManipulator());
    keyswitchManipulator->addMatrixManipulator('2', "Flight", new osgGA::FlightManipulator());
    keyswitchManipulator->addMatrixManipulator('3', "Drive", new osgGA::DriveManipulator());
    keyswitchManipulator->addMatrixManipulator('4', "Terrain", new osgGA::TrackballManipulator());
    viewer.setCameraManipulator(keyswitchManipulator.get());
}

viewer.addEventHandler(new osgViewer::RecordCameraPathHandler);


cam->setGraphicsContext(gc.get());
// Must set perspective projection for fovy and aspect.
cam->setProjectionMatrix(osg::Matrix::perspective(30., (double)width / (double)height, 1., 100.));
// Unlike OpenGL, OSG viewport does *not* default to window dimensions.
cam->setViewport(new osg::Viewport(0, 0, width, height));

viewer.setSceneData(root);

// for non GL3/GL4 and non GLES2 platforms we need enable the osg_ uniforms that the shaders will use,
// you don't need thse two lines on GL3/GL4 and GLES2 specific builds as these will be enable by default.
gc->getState()->setUseModelViewAndProjectionUniforms(true);
gc->getState()->setUseVertexAttributeAliasing(true);


viewer.realize();
return(viewer.run());

微信图片_20231116161459
微信图片_20231116161454

}

@luohuiiqng
Copy link
Author

The first image is generator from the problem code..

@luohuiiqng
Copy link
Author

My idea is that even with advanced opengl, the material of the model can still be obtained from the OSG file normally, and the model can be rendered in the shader through built-in OSG variables. Is this idea feasible?

@xarray
Copy link

xarray commented Nov 16, 2023

The result seems to be correct. The shader code you provided uses diffuse lighting as the fragment color. And the image shows the same thing.

@luohuiiqng
Copy link
Author

The result seems to be correct. The shader code you provided uses diffuse lighting as the fragment color. And the image shows the same thing.

How can I reference the model colors set in the OSG file in the shader? I tried using osg_ Color is still invalid in the shader. Thank you!

@robertosfield
Copy link
Collaborator

If want want to use advanced graphics functionality then OpenGL/OpenSceneGraph isn't the best tool. You will likely find it easier to using modern APIs like Vulkan/VulkanSceneGraph.

@luohuiiqng
Copy link
Author

If want want to use advanced graphics functionality then OpenGL/OpenSceneGraph isn't the best tool. You will likely find it easier to using modern APIs like Vulkan/VulkanSceneGraph.

Yes, but I currently want to quickly implement something similar to Google Earth. After searching for some information, I learned that OSG and OSgEarth can quickly help me achieve it, so I am currently trying to understand OSG

@robertosfield
Copy link
Collaborator

Alternatives to osgEarth:

vsgCs
rocky

@luohuiiqng
Copy link
Author

I think my current problem is that after reading the OSG file, I cannot easily extract the colors specified in the file and use them in the shader.

@luohuiiqng
Copy link
Author

Alternatives to osgEarth:

vsgCs rocky

Alternatives to osgEarth:

vsgCs rocky

Is there an example of integrating with QT? I would like to integrate it into an existing QT program. Thank you!

@robertosfield
Copy link
Collaborator

The VulkanSceneGraph README.md provides links to a number of related projects including vsgQt:

https://github.com/vsg-dev/VulkanSceneGraph

vsgQt itself:

https://github.com/vsg-dev/vsgQt

@xarray
Copy link

xarray commented Nov 17, 2023

The result seems to be correct. The shader code you provided uses diffuse lighting as the fragment color. And the image shows the same thing.

How can I reference the model colors set in the OSG file in the shader? I tried using osg_ Color is still invalid in the shader. Thank you!

osg_Color should work as an alternative of gl_Color. Make sure it's vec4

@luohuiiqng
Copy link
Author

The result seems to be correct. The shader code you provided uses diffuse lighting as the fragment color. And the image shows the same thing.

How can I reference the model colors set in the OSG file in the shader? I tried using osg_ Color is still invalid in the shader. Thank you!

osg_Color should work as an alternative of gl_Color. Make sure it's vec4

Thank you! This plan is feasible. Where can I find any built-in opengl variables for OSG?

@luohuiiqng
Copy link
Author

The result seems to be correct. The shader code you provided uses diffuse lighting as the fragment color. And the image shows the same thing.

How can I reference the model colors set in the OSG file in the shader? I tried using osg_ Color is still invalid in the shader. Thank you!

osg_Color should work as an alternative of gl_Color. Make sure it's vec4

Thank you! This plan is feasible. Where can I find any built-in opengl variables for OSG?

For example, textures

@xarray
Copy link

xarray commented Nov 17, 2023

osg_Color should work as an alternative of gl_Color. Make sure it's vec4

Thank you! This plan is feasible. Where can I find any built-in opengl variables for OSG?

OSG replaces gl_* attributes for convience under core profile. Have a look at State::resetVertexAttributeAlias():
osg_Vertex, osg_Normal, osg_Color, osg_SecondaryColor, osg_FogCoord, osg_MultiTexCoord0, osg_MultiTexCoord1, ...

And some necessary uniforms, at State::convertVertexShaderSourceToOsgBuiltIns():
osg_ModelViewMatrix, osg_ModelViewProjectionMatrix, osg_ProjectionMatrix, osg_NormalMatrix

FYI, don't forget those uniforms that work under both core and compatible profiles. See them at SceneView::updateUniforms():
osg_FrameNumber, osg_FrameTime, osg_SimulationTime, osg_ViewMatrix, osg_ViewMatrixInverse

@luohuiiqng
Copy link
Author

osg_Color should work as an alternative of gl_Color. Make sure it's vec4

Thank you! This plan is feasible. Where can I find any built-in opengl variables for OSG?

OSG replaces gl_* attributes for convience under core profile. Have a look at State::resetVertexAttributeAlias(): osg_Vertex, osg_Normal, osg_Color, osg_SecondaryColor, osg_FogCoord, osg_MultiTexCoord0, osg_MultiTexCoord1, ...

And some necessary uniforms, at State::convertVertexShaderSourceToOsgBuiltIns(): osg_ModelViewMatrix, osg_ModelViewProjectionMatrix, osg_ProjectionMatrix, osg_NormalMatrix

FYI, don't forget those uniforms that work under both core and compatible profiles. See them at SceneView::updateUniforms(): osg_FrameNumber, osg_FrameTime, osg_SimulationTime, osg_ViewMatrix, osg_ViewMatrixInverse

Thank you! I found it.

@luohuiiqng
Copy link
Author

The VulkanSceneGraph README.md provides links to a number of related projects including vsgQt:

https://github.com/vsg-dev/VulkanSceneGraph

vsgQt itself:

https://github.com/vsg-dev/vsgQt

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants