• Advertisement
Sign in to follow this  

OpenGL glm/opengl orbital camera C++

This topic is 1251 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi there,


I have a gl project with a first person camera that uses glm to do it's math.

My question is thus and I'm sorry for it's quite poor construction: 

Do I need to use/do glm::quat things or do I need rotX, rotY, rotZ, for some code where the camera spins around on a sphere centred on the model?

So, the end goal is that moving the mouse makes it look like the model is spinning, when actually the camera is spinning?

And how would I do that?

For example, how different would this class declaration be?

I'd like to throw a 'orbit-cam' in there, then extract a base class, etc.

class GLCamera

float   _mx, _my;
float   m_frameTime, // how much time has passed
m_moveSpeed, // how many units to move per second
m_mouseSpeed; // how many degrees to rotate per second of

glm::vec3 m_real_up;
glm::vec3 m_origin;

float m_horizontalAngle, m_verticalAngle, m_initFoV;

glm::vec3 position;

glm::vec3 m_direction;
glm::vec3 m_right;
glm::vec3 m_up;

glm::mat4 m_viewMatrix;

Share this post

Link to post
Share on other sites

You can do that in zillion ways. You need to make a point floating around your model at desired hieght (if your Up vector is Y, then use X = cos(time) and Z = sin(time) to have a circle flying camera). then you need just to build a lookAt matrix camera (position is the point and lookAt is the model feet).

To build the matrix search around the web but I think GLM already have those functionalities

Share this post

Link to post
Share on other sites

Hi, thanks for replying.


Y is my real up, and my existing camera is using glm::lookAt(position, position + direction, up)


This is a cool idea, I'll try this tomorrow:

use X = cos(time) and Z = sin(time)


I guess orbit is the wrong word, my bad; what I'm looking for is a kind of 3D editor camera - so the models at 0,0,0 but I can 'spin it around on it's origin'.


So what I need is glm::lookAt(position, origin, up), and I use the mouse to update something like this?

dx = mouse.dx; // change in
dy = mouse.dy;

//rotate on y axis
rotY += dx;
position = (cos(rotY), 0, sin(rotY));

//rotate on x axis ?? 
rotX += dy;
// ? // position.x += cos(rotX);
// ? // position.y = sin(rotX)
// ? // position.z += cos(rotX);

Share this post

Link to post
Share on other sites

I would probably do something like this:

// Get the rotation matrix from rotY and rotX
glm::mat4 rotation = glm::rotate(glm::mat4(), rotY, glm::vec3(0,1,0)) * glm::rotate(glm::mat4(), rotX, glm::vec3(1,0,0));

// origin * rotation * distance_offset
glm::mat4 final_transform = glm::translate(glm::mat4(), origin) * rotation * glm::translate(glm::mat4(), glm::vec3(0,0,distance));

// And the view matrix is the inverse of whatever's transform
glm::mat4 view = glm::inverse(final_transform);

Not as fast as doing the math directly by yourself, but should work nicely.

Share this post

Link to post
Share on other sites

Depends if you need to orbit camera only left right or also up/down. You need to move camera position around a circle or on the surface of a sphere then.


You could use a quaternion (rotation around 1 axis) but the faster way is to compute directly the coordinate(and it is also simple)


Given the camera startin position is on XY plane (Z=0)


first rotate around Z axis for vertical scrolling.

currentY+=mouseY*speed; //vertical angle

if(currentY >89.f)
    currentY = 89.f;

    currentY = -89.f;

camPos.x = range*cos(currentY*DEG_TO_RAD);
camPos.y = range*sin(currentY*DEG_TO_RAD);
camPos.z = 0;

camPos = glm::rotate(camPos, rotX ,glm::vec3(0,1,0)); //rotate around vertical axis now
Edited by DemonDar

Share this post

Link to post
Share on other sites

RE: Do I need to use/do glm::quat things or do I need rotX, rotY, rotZ, for some code where the camera spins around on a sphere centred on the model?

You can use either strategy (i.e. quaternions or euler angles ala degrees). Some people argue about the pros and cons of each too (there is always arguing going on somewhere [mostly?] in the world so we'll leave that alone).


I just so happen to have been playing around with an FPS and Orbit cameras recently, so this might help: It's one in a zillion! ..I mean It's one of those zillion.

glm can be a great tool. You can save yourself a smidge of code by calling something like:

glm::mat4 R = glm::yawPitchRoll(yawf,pitchf,0.0f);

to rotate using quaternions euler angles as input.


Then you could do the following to Update() a camera transformation:

glm::vec3 T = glm::vec3(0,0,dist);
T = glm::vec3(R*glm::vec4(T,0.0f));
*position = *target + T;
*look = glm::normalize(*target-*position);
*up = glm::vec3(R*glm::vec4(*UP,0.0f));
*right = glm::cross(*look,*up);
*V = glm::lookAt(*position, *target, *up);

That was easy! A Spam of code!
Now we just have to translate that into english. anyone?


But lets back up a bit. As far as I can tell you are describing an orbit camera! Let me try and paraphrase your stated goal:

The orbit camera works the opposite way to FPS, ...yeah?. Rather than the position of the camera

staying fixed, the target remains fixed, while the camera moves or rotates around the target.

How does that sound? That's an orbit camera. An obviously good analogy so let's use it?

Since you don't seem very sure about it, I suggest we just stick with that analogy. Sound OK?


Then think about this:


Say we have a target position (the centre of a model..say)
We get the distance(dist) between the target position(target) and the camera position(position) and

turn it into a vector:

glm::vec3 T = glm::vec3(0,0,dist); // turn it into a vector

Then translate this vector by the current rotation matrix:

T = glm::vec3(R*glm::vec4(T,0.0f));

Then adding this translation vector to the target position gives us the new camera position:

*position = *target + T;

That's it.. well almost. So far, we have the new position for the camera to moved to. All we do next is update the camera look, up and right vectors(re-orientate the camera) and view matrix or to be really dry we can say "Recalculate the orthonormal basis and then the view matrix" and its done (ready for the next frame).


The problem with giving code examples is that sometimes there are diminishing returns from explanations of them.. or maybe not... if you can figure it out yourself ... like a puzzle. Trying to figure out what a piece of code does is all part of programming (and lets me off the hook for being lazy!).


You might ask some interesting questions like " What is T or  V or UP"? No,.. just kidding!

They are obvious questions, with hopefully obvious answers.


Something a little more interesting you might ask is:


* How do we get the distance(dist) between the target position(target) and the camera position(position) ?

//First set the position then the target and use glm::distance():
 void SetPosition(const glm::vec3& p) 
{  *position = p; }
 void SetTarget(const glm::vec3& tgt) 
{  *target = tgt;
   distance = glm::distance(*position, *target); 

glm::distance() is like most bits of code: you can do internals of them yourself instead of using glm if you wish.


So, most of this (I think) comes from The targetcamera section of an Opengl Cookbook: http://www.packtpub.com/opengl-development-cookbook/book

Nothing particularly new in there, Mainly fairly neat code examples using glm that is good to play with. Not sure if I remember it being very "beginner friendly" though. But it does spell out the full code per class that is very easy to modify and to drop into something suitable. Among other things it contains an (FPS) free camera and (orbit/turntable/arcball?) target camera both derived from a base camera class: just what you seem to be starting on, it seems, from your post.


*Another question: What if you wanted to use good ol' fashion degrees (euler angles) ? (that, I assume is your mention of rotX, rotY, rotZ?).
Just replace the quaternion form with the euler form at this line:

An alternative to using glm::yawPitchRoll() is to do it ourselves using glm::rotate():

// correction: this is not quaternions. This is a euler angles version also..sorry 
//glm::mat4 R = glm::yawPitchRoll(yawf,pitchf,0.0f);
// produce equivalent effect using glm::rotate()
float xr = pitchDegrees; 
float yr = yawDegrees;
glm::mat4 ViewTranslate = glm::mat4(1.0f); 
glm::mat4 RY = glm::rotate(ViewTranslate,yr,glm::vec3(0.0f,1.0f,0.0f));//yaw 
glm::mat4 RX = glm::rotate(RY,xr,glm::vec3(1.0f,0.0f,0.0f));//pitch   
glm::mat4 R = glm::rotate(RX,0.0f,glm::vec3(0.0f,0.0f,1.0f));//no roll, currently redundant but exists anyway

Both methods depend on how you get your input angles with something like camera->Rotate() method like so:

Rotate(const float yaw, const float pitch, const float roll)
	// and/or you can store angles in degrees.        
	yawDegrees = yaw; 
	pitchDegrees = pitch; 
	rollDegrees = roll;

What is passed to Rotate can be the mouse Delta positions i.e.The position relative to its last position (or some filtered value thereof). 


Getting you hands on the Cookbook may help.  A source code download comes with this bit of leisurely reading. With this target camera you have the added bonus of setting the target to any position you desire (a staple of any good 3D model editor I imagine). Hence the authors' emphasis on this orbit camera being a target camera.

Cameras are fun.

The hard part might be figuring out how to build this into your achitecture? 

Edited by steven katic

Share this post

Link to post
Share on other sites

I have decent target / orbit cam following this thread but how do I now use the View code onto the camera object itself? I have an obj file that is modelled to be a camera and from above is basically my ViewMatrix

glm::vec3 T = glm::vec3(0,0,dist);
T = glm::vec3(R*glm::vec4(T,0.0f));
*position = *target + T;
*look = glm::normalize(*target-*position);
*up = glm::vec3(R*glm::vec4(*UP,0.0f));
*right = glm::cross(*look,*up);
*V = glm::lookAt(*position, *target, *up);

Share this post

Link to post
Share on other sites
Okay, I broke my collarbone, apologies for the lack of input.

I shall have a read then edit this post (..surface of a sphere please)..

Steven Katic right on! That analogy is exactly what was in my head. Would you believe I'm a graphics programmer by day as well? Hahaha terrible!

Indeed a target is just a translation of the origin; I haven't got a mesh hierarchy or the right matrix from assimp yet, so just one matrix/position to spin the camera around at the moment.

I got my FPS camera from opengl-tutorials.com. also I bought the blue book instead of the red one and I'm regretting it now.

[keeps reading]

Share this post

Link to post
Share on other sites

Okay! It kind of works!


I'm now suffering from a kind of 'bad handling', where i get some interference and then a big camera jump.. it's not exactly smooth..


Here's my messy work in progress :


Get mouse position:

		POINT p;

		// move into rect/window space
		p.x -= rWindow.left;
		p.y -= rWindow.top;

		// relative to rect/window centre
		//p.x -= (rWindow.right - rWindow.left)/2;
		//p.y -= (rWindow.bottom-rWindow.top)/2;

Then update the camera:

	if( pMouse->bRight == true )
		POINT mPos = pMouse->pos; // pixels
		mPos.x -= pMouse->prev.x;
		mPos.y -= pMouse->prev.y;

		if(mPos.x != 0 || mPos.y != 0)
			float hMag = _radians(millisElapsed * m_mouseSpeed * mPos.x);
			float vMag = _radians(millisElapsed * m_mouseSpeed * mPos.y);

			if( fabs(hMag) > _pi || fabs(vMag) > _pi)

			m_horizontalAngle -= hMag;
			m_verticalAngle -= vMag;

	//to rotate using quaternions euler angles as input.
	glm::mat4 R = glm::yawPitchRoll(m_horizontalAngle, m_verticalAngle, 0.0f);		
	//Then you could do the following to Update() a camera transformation:
	glm::vec3 T = glm::vec3(0, 0, -dist);
	position = glm::vec3(R * glm::vec4(T, 0.0f));

	m_direction = origin;// glm::normalize(position);
	m_up = glm::vec3(R * glm::vec4(m_real_up, 0.0f));
	m_right = glm::cross(m_direction, m_up);

	m_viewMatrix = glm::lookAt(position, m_direction, m_up);

Any suggestions?

Edited by mynameisnafe

Share this post

Link to post
Share on other sites

Hi nate?(oops) mynameisnafe,

I see you've worked out the correct angles of rotation input to the camera rotate method: It is the total angle since its creation, and not

the delta angle, as I incorrectly suggested in my first post.

I do not understand what your code is doing. It can get tricky fine tuning the operation of a camera so it's a good idea to come up with a plan.

So, for example, I think about the following:

Decouple the input angles from the input source. Looks like you have done that with the m_horizontalAngle and m_verticalAngle variables. So that's good.

Next, How do we update them? This is not clear to me from the code you posted.
Here is a typical usecase/scenario I would expect to see for the user rotating the camera with the mouse:

Operation: The user presses and holds down a designated mouse button, then drags the mouse to move the camera view around.

The recipe:

// two new variables to add to the current camera rotation angles.
//(Perhaps a little overengineering going on here. But it does indicate our explicit intent for now).
int m_pitchDelta;// = 0; member vars: init somewhere else or make static?
int m_yawDelta;// = 0;

On mouse button down (say typically the left button): Intialise the camera system input parameters for the next rotation.

I see this line "if( pMouse->bRight == true )" in your code and assume it means "if the right mouse button is down"?.

// on right button down set the start position of the new transformation
// values that will modify the current values (in m_horizontalAngle and m_verticalAngle variables) 
if( pMouse->bRight == true) 
	POINT p;  
	m_pitchDelta = p.x;  
 	m_yawDelta = p.y;  

Note: That's all you need at this stage. I would keep it simple until it works, then add all your other bells & whistles (i.e. stuff related to the angle restrictions

and filtered/timing speeds) they just get in the way for me at the moment.

So, ideally at this moment in the process the Modelview Matrix *V has already been initialized and typically the full MVP has also already been constructed and now all

that is happening each frame is The MVP is passed to the shader, the shader is activated and scene drawn.

Oh,...And you are holding that right mouse button down....(ready to move the mouse).

Now the only change we are interested in is when the mouse moves (with that right button down, basically dragging the camera view around).
We want the Camera to move around relative to the mouse pointer position as it moves.

I cannot quite see this happening in your code. But you can put the camera update code in the WM_MOUSEMOVE case section to make this intention explicit:

case WM_MOUSEMOVE:  {  
 POINT p;  
// get the amount of the last mouse movement  
m_pitchDelta -= p.x; 
m_yawDelta -= p.y; 
// modify the current angles   
m_horizontalAngle -= m_yawDelta; 
m_verticalAngle -= m_pitchDelta;     
// ?please explain? I wouldn't modify the source of our input(yet, if ever?)  
// move into rect/window space   
//p.x -= rWindow.left; 
//p.y -= rWindow.top;   
// relative to rect/window centre 
//p.x -= (rWindow.right - rWindow.left)/2;   
//p.y -= (rWindow.bottom-rWindow.top)/2;   
//********* Camera->Update()********************************************// 
//to rotate using euler angles as input.   
glm::mat4 R = glm::yawPitchRoll(m_horizontalAngle, m_verticalAngle,0.0f);      
//Then you could do the following to Update() a camera transformation:   
glm::vec3 T = glm::vec3(0, 0,-dist);   
position = glm::vec3(R * glm::vec4(T,0.0f)); 
m_direction = origin;//glm::normalize(position);  
m_up = glm::vec3(R * glm::vec4(m_real_up, 0.0f)); 
m_right = glm::cross(m_direction,m_up);   
m_viewMatrix = glm::lookAt(position, m_direction,m_up);  
 //then update the MVP that typically goes to the shader at render time  

Four important lines here are:

The 2 lines that update the mouse movement since the last movement (would typically be one raw pixel on a responsive ui thread) and,

The 2 lines that Just modify the current angles of camera rotation.

Can you see them?

That makes sense to me so far, what do you think?

Have I missed anything? Give it a go, and let us know maybe.


ps. Ok. Heres's one minor part I missed: where the parameters m_horizontalAngle, m_verticalAngle are converted to radians before being fed to glm::yawPitchRoll() ?

Could be more I missed.

Edited by steven katic

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
  • Advertisement
  • Popular Tags

  • Advertisement
  • Popular Now

  • Similar Content

    • By reenigne
      For those that don't know me. I am the individual who's two videos are listed here under setup for https://wiki.libsdl.org/Tutorials
      I also run grhmedia.com where I host the projects and code for the tutorials I have online.
      Recently, I received a notice from youtube they will be implementing their new policy in protecting video content as of which I won't be monetized till I meat there required number of viewers and views each month.

      Frankly, I'm pretty sick of youtube. I put up a video and someone else learns from it and puts up another video and because of the way youtube does their placement they end up with more views.
      Even guys that clearly post false information such as one individual who said GLEW 2.0 was broken because he didn't know how to compile it. He in short didn't know how to modify the script he used because he didn't understand make files and how the requirements of the compiler and library changes needed some different flags.

      At the end of the month when they implement this I will take down the content and host on my own server purely and it will be a paid system and or patreon. 

      I get my videos may be a bit dry, I generally figure people are there to learn how to do something and I rather not waste their time. 
      I used to also help people for free even those coming from the other videos. That won't be the case any more. I used to just take anyone emails and work with them my email is posted on the site.

      I don't expect to get the required number of subscribers in that time or increased views. Even if I did well it wouldn't take care of each reoccurring month.
      I figure this is simpler and I don't plan on putting some sort of exorbitant fee for a monthly subscription or the like.
      I was thinking on the lines of a few dollars 1,2, and 3 and the larger subscription gets you assistance with the content in the tutorials if needed that month.
      Maybe another fee if it is related but not directly in the content. 
      The fees would serve to cut down on the number of people who ask for help and maybe encourage some of the people to actually pay attention to what is said rather than do their own thing. That actually turns out to be 90% of the issues. I spent 6 hours helping one individual last week I must have asked him 20 times did you do exactly like I said in the video even pointed directly to the section. When he finally sent me a copy of the what he entered I knew then and there he had not. I circled it and I pointed out that wasn't what I said to do in the video. I didn't tell him what was wrong and how I knew that way he would go back and actually follow what it said to do. He then reported it worked. Yea, no kidding following directions works. But hey isn't alone and well its part of the learning process.

      So the point of this isn't to be a gripe session. I'm just looking for a bit of feed back. Do you think the fees are unreasonable?
      Should I keep the youtube channel and do just the fees with patreon or do you think locking the content to my site and require a subscription is an idea.

      I'm just looking at the fact it is unrealistic to think youtube/google will actually get stuff right or that youtube viewers will actually bother to start looking for more accurate videos. 
    • By Balma Alparisi
      i got error 1282 in my code.
      sf::ContextSettings settings; settings.majorVersion = 4; settings.minorVersion = 5; settings.attributeFlags = settings.Core; sf::Window window; window.create(sf::VideoMode(1600, 900), "Texture Unit Rectangle", sf::Style::Close, settings); window.setActive(true); window.setVerticalSyncEnabled(true); glewInit(); GLuint shaderProgram = createShaderProgram("FX/Rectangle.vss", "FX/Rectangle.fss"); float vertex[] = { -0.5f,0.5f,0.0f, 0.0f,0.0f, -0.5f,-0.5f,0.0f, 0.0f,1.0f, 0.5f,0.5f,0.0f, 1.0f,0.0f, 0.5,-0.5f,0.0f, 1.0f,1.0f, }; GLuint indices[] = { 0,1,2, 1,2,3, }; GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); GLuint vbo; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); GLuint ebo; glGenBuffers(1, &ebo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices,GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(float) * 5, (void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, false, sizeof(float) * 5, (void*)(sizeof(float) * 3)); glEnableVertexAttribArray(1); GLuint texture[2]; glGenTextures(2, texture); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); sf::Image* imageOne = new sf::Image; bool isImageOneLoaded = imageOne->loadFromFile("Texture/container.jpg"); if (isImageOneLoaded) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageOne->getSize().x, imageOne->getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageOne->getPixelsPtr()); glGenerateMipmap(GL_TEXTURE_2D); } delete imageOne; glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texture[1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); sf::Image* imageTwo = new sf::Image; bool isImageTwoLoaded = imageTwo->loadFromFile("Texture/awesomeface.png"); if (isImageTwoLoaded) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageTwo->getSize().x, imageTwo->getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageTwo->getPixelsPtr()); glGenerateMipmap(GL_TEXTURE_2D); } delete imageTwo; glUniform1i(glGetUniformLocation(shaderProgram, "inTextureOne"), 0); glUniform1i(glGetUniformLocation(shaderProgram, "inTextureTwo"), 1); GLenum error = glGetError(); std::cout << error << std::endl; sf::Event event; bool isRunning = true; while (isRunning) { while (window.pollEvent(event)) { if (event.type == event.Closed) { isRunning = false; } } glClear(GL_COLOR_BUFFER_BIT); if (isImageOneLoaded && isImageTwoLoaded) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture[0]); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texture[1]); glUseProgram(shaderProgram); } glBindVertexArray(vao); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr); glBindVertexArray(0); window.display(); } glDeleteVertexArrays(1, &vao); glDeleteBuffers(1, &vbo); glDeleteBuffers(1, &ebo); glDeleteProgram(shaderProgram); glDeleteTextures(2,texture); return 0; } and this is the vertex shader
      #version 450 core layout(location=0) in vec3 inPos; layout(location=1) in vec2 inTexCoord; out vec2 TexCoord; void main() { gl_Position=vec4(inPos,1.0); TexCoord=inTexCoord; } and the fragment shader
      #version 450 core in vec2 TexCoord; uniform sampler2D inTextureOne; uniform sampler2D inTextureTwo; out vec4 FragmentColor; void main() { FragmentColor=mix(texture(inTextureOne,TexCoord),texture(inTextureTwo,TexCoord),0.2); } I was expecting awesomeface.png on top of container.jpg

    • By khawk
      We've just released all of the source code for the NeHe OpenGL lessons on our Github page at https://github.com/gamedev-net/nehe-opengl. code - 43 total platforms, configurations, and languages are included.
      Now operated by GameDev.net, NeHe is located at http://nehe.gamedev.net where it has been a valuable resource for developers wanting to learn OpenGL and graphics programming.

      View full story
    • By TheChubu
      The Khronos™ Group, an open consortium of leading hardware and software companies, announces from the SIGGRAPH 2017 Conference the immediate public availability of the OpenGL® 4.6 specification. OpenGL 4.6 integrates the functionality of numerous ARB and EXT extensions created by Khronos members AMD, Intel, and NVIDIA into core, including the capability to ingest SPIR-V™ shaders.
      SPIR-V is a Khronos-defined standard intermediate language for parallel compute and graphics, which enables content creators to simplify their shader authoring and management pipelines while providing significant source shading language flexibility. OpenGL 4.6 adds support for ingesting SPIR-V shaders to the core specification, guaranteeing that SPIR-V shaders will be widely supported by OpenGL implementations.
      OpenGL 4.6 adds the functionality of these ARB extensions to OpenGL’s core specification:
      GL_ARB_gl_spirv and GL_ARB_spirv_extensions to standardize SPIR-V support for OpenGL GL_ARB_indirect_parameters and GL_ARB_shader_draw_parameters for reducing the CPU overhead associated with rendering batches of geometry GL_ARB_pipeline_statistics_query and GL_ARB_transform_feedback_overflow_querystandardize OpenGL support for features available in Direct3D GL_ARB_texture_filter_anisotropic (based on GL_EXT_texture_filter_anisotropic) brings previously IP encumbered functionality into OpenGL to improve the visual quality of textured scenes GL_ARB_polygon_offset_clamp (based on GL_EXT_polygon_offset_clamp) suppresses a common visual artifact known as a “light leak” associated with rendering shadows GL_ARB_shader_atomic_counter_ops and GL_ARB_shader_group_vote add shader intrinsics supported by all desktop vendors to improve functionality and performance GL_KHR_no_error reduces driver overhead by allowing the application to indicate that it expects error-free operation so errors need not be generated In addition to the above features being added to OpenGL 4.6, the following are being released as extensions:
      GL_KHR_parallel_shader_compile allows applications to launch multiple shader compile threads to improve shader compile throughput WGL_ARB_create_context_no_error and GXL_ARB_create_context_no_error allow no error contexts to be created with WGL or GLX that support the GL_KHR_no_error extension “I’m proud to announce OpenGL 4.6 as the most feature-rich version of OpenGL yet. We've brought together the most popular, widely-supported extensions into a new core specification to give OpenGL developers and end users an improved baseline feature set. This includes resolving previous intellectual property roadblocks to bringing anisotropic texture filtering and polygon offset clamping into the core specification to enable widespread implementation and usage,” said Piers Daniell, chair of the OpenGL Working Group at Khronos. “The OpenGL working group will continue to respond to market needs and work with GPU vendors to ensure OpenGL remains a viable and evolving graphics API for all its customers and users across many vital industries.“
      The OpenGL 4.6 specification can be found at https://khronos.org/registry/OpenGL/index_gl.php. The GLSL to SPIR-V compiler glslang has been updated with GLSL 4.60 support, and can be found at https://github.com/KhronosGroup/glslang.
      Sophisticated graphics applications will also benefit from a set of newly released extensions for both OpenGL and OpenGL ES to enable interoperability with Vulkan and Direct3D. These extensions are named:
      GL_EXT_memory_object GL_EXT_memory_object_fd GL_EXT_memory_object_win32 GL_EXT_semaphore GL_EXT_semaphore_fd GL_EXT_semaphore_win32 GL_EXT_win32_keyed_mutex They can be found at: https://khronos.org/registry/OpenGL/index_gl.php
      Industry Support for OpenGL 4.6
      “With OpenGL 4.6 our customers have an improved set of core features available on our full range of OpenGL 4.x capable GPUs. These features provide improved rendering quality, performance and functionality. As the graphics industry’s most popular API, we fully support OpenGL and will continue to work closely with the Khronos Group on the development of new OpenGL specifications and extensions for our customers. NVIDIA has released beta OpenGL 4.6 drivers today at https://developer.nvidia.com/opengl-driver so developers can use these new features right away,” said Bob Pette, vice president, Professional Graphics at NVIDIA.
      "OpenGL 4.6 will be the first OpenGL release where conformant open source implementations based on the Mesa project will be deliverable in a reasonable timeframe after release. The open sourcing of the OpenGL conformance test suite and ongoing work between Khronos and X.org will also allow for non-vendor led open source implementations to achieve conformance in the near future," said David Airlie, senior principal engineer at Red Hat, and developer on Mesa/X.org projects.

      View full story
    • By _OskaR
      I have an OpenGL application but without possibility to wite own shaders.
      I need to perform small VS modification - is possible to do it in an alternative way? Do we have apps or driver modifictions which will catch the shader sent to GPU and override it?
  • Advertisement