openscenegraph / OpenSceneGraph

OpenSceneGraph git repository
http://www.openscenegraph.org
Other
3.21k stars 1.42k forks source link

use advance opengl 3.0 inaccurate display #1273

Open luohuiiqng opened 10 months ago

luohuiiqng commented 10 months ago

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::vector fileList; fileList.push_back("glider.osg"); // 创建节点. osg::ref_ptr 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 commented 10 months ago

The first image is generator from the problem code..

luohuiiqng commented 10 months ago

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 commented 10 months ago

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 commented 10 months ago

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 commented 10 months ago

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 commented 10 months ago

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 commented 10 months ago

Alternatives to osgEarth:

vsgCs rocky

luohuiiqng commented 10 months ago

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 commented 10 months ago

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 commented 10 months ago

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 commented 10 months ago

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 commented 10 months ago

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 commented 10 months ago

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 commented 10 months ago

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 commented 10 months ago

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 commented 10 months ago

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!