'拌和'不是' glm'的成员

时间:2014-05-27 06:47:36

标签: c++ opengl glm-math

我使用以下代码实现"缩放到鼠标点" c ++中opengl的功能。大部分代码来自 OpenGL Google maps style 2D camera / zoom to mouse cursor但由于GLM(http://glm.g-truc.net/0.9.5/index.html)代码库发生了变化,我不得不更改一些include语句。

#include <GL/freeglut.h>
#include <iostream>
using namespace std;
#define GLM_SWIZZLE_XYZW 
#define GLM_FORCE_RADIANS

#include "glm/glm.hpp"
#include "glm/detail/setup.hpp"
#include "glm/detail/_swizzle.hpp"
#include "glm/detail/_swizzle_func.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
glm::dvec3 Unproject( const glm::dvec3& win )
{
glm::ivec4 view;
glm::dmat4 proj, model;
glGetDoublev( GL_MODELVIEW_MATRIX, glm::value_ptr( model ) );
glGetDoublev( GL_PROJECTION_MATRIX, glm::value_ptr( proj ) );
glGetIntegerv( GL_VIEWPORT, glm::value_ptr( view ) );
glm::dvec3 world = glm::unProject( win, model, proj, view );
return world;
}
// unprojects the given window point
// and finds the ray intersection with the Z=0 plane
glm::dvec2 PlaneUnproject( const glm::dvec2& win )
{
glm::dvec3 world1 = Unproject( glm::dvec3( win, 0.01 ) );
glm::dvec3 world2 = Unproject( glm::dvec3( win, 0.99 ) );
// u is a value such that:
// 0 = world1.z + u * ( world2.z - world1.z )
double u = -world1.z / ( world2.z - world1.z );
// clamp u to reasonable values
if( u < 0 ) u = 0;
if( u > 1 ) u = 1;
return glm::swizzle< glm::X, glm::Y >( world1 + u * ( world2 - world1 ) );
}
// pixels per unit
const double ppu = 80.0;
glm::dvec2 center( 0 );
double scale = 1.0;
void ApplyCamera()
{
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
const double w = glutGet( GLUT_WINDOW_WIDTH ) / ppu;
const double h = glutGet( GLUT_WINDOW_HEIGHT ) / ppu;
glOrtho( -w/2, w/2, -h/2, h/2, -1, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glScaled( scale, scale, 1.0 );
glTranslated( -center[0], -center[1], 0 );
}
glm::dvec2 centerStart( 0 );
int btn = -1;
void mouse( int button, int state, int x, int y )
{
ApplyCamera();
y = glutGet( GLUT_WINDOW_HEIGHT ) - y;
btn = button;
if( GLUT_LEFT_BUTTON == btn && GLUT_DOWN == state )
{
centerStart = PlaneUnproject( glm::dvec2( x, y ) );
}
if( GLUT_LEFT_BUTTON == btn && GLUT_UP == state )
{
btn = -1;
}
glutPostRedisplay();
}
void motion( int x, int y )
{
y = glutGet( GLUT_WINDOW_HEIGHT ) - y;
if( GLUT_LEFT_BUTTON == btn )
{
ApplyCamera();
glm::dvec2 cur = PlaneUnproject( glm::dvec2( x, y ) );
center += ( centerStart - cur );
}
glutPostRedisplay();
}
void wheel( int wheel, int direction, int x, int y )
{
y = glutGet( GLUT_WINDOW_HEIGHT ) - y;
ApplyCamera();
glm::dvec2 beforeZoom = PlaneUnproject( glm::dvec2( x, y ) );
const double scaleFactor = 0.90;
if( direction == -1 ) scale *= scaleFactor;
if( direction == 1 ) scale /= scaleFactor;
ApplyCamera();
glm::dvec2 afterZoom = PlaneUnproject( glm::dvec2( x, y ) );
center += ( beforeZoom - afterZoom );
glutPostRedisplay();
}
void display()
{
glClearColor( 0, 0, 0, 1 );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
ApplyCamera();
glBegin( GL_QUADS );
glVertex2i( -1, -1 );
glVertex2i( 1, -1 );
glVertex2i( 1, 1 );
glVertex2i( -1, 1 );
glEnd();
glutSwapBuffers();
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
glutInitWindowSize( 600, 600 );
glutCreateWindow( "GLUT" );
glutMouseFunc( mouse );
glutMotionFunc( motion );
glutMouseWheelFunc( wheel );
glutDisplayFunc( display );
glutMainLoop();
return 0;
}

错误

error: 'swizzle' is not a member of 'glm'
error: 'X' is not a member of 'glm'
error: 'Y' is not a member of 'glm'

符合

return glm::swizzle< glm::X, glm::Y >( world1 + u * ( world2 - world1 ) );

我知道glm::swizzle显然是错误的,但glm::detail::_swizzle需要8个参数,相比之前glm::swizzle需要2个参数。新参数会是什么?另外,我不知道如何纠正glm::Xglm::Y。有人可以帮忙吗?

3 个答案:

答案 0 :(得分:3)

实际上,在这种情况下你根本不需要调配,因为有一个dvec2构造函数可以为你切割z坐标。

从此处更改PlaneUnproject()的最后一行:

return glm::swizzle< glm::X, glm::Y >( world1 + u * ( world2 - world1 ) );

到此:

return glm::dvec2( world1 + u * ( world2 - world1 ) );

我更新了original answer中的完整代码。


虽然你真的想要调侃:

削减#include s:

#define GLM_SWIZZLE
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

并从此处更改PlaneUnproject()的最后一行:

return glm::swizzle< glm::X, glm::Y >( world1 + u * ( world2 - world1 ) );

到此:

return ( world1 + u * ( world2 - world1 ) ).xy();

答案 1 :(得分:0)

我相信这很简单。在glm命名空间下,没有被称为“swizzle”的成员。请检查以下两点: -

  1. 只需检查是否存在嵌套命名空间,并按照glm::detail::swizzle
  2. 进行相应的引用
  3. 另请检查会员名称是swizzle还是_swizzle
  4. 谢谢!

答案 2 :(得分:0)

在较新版本的glm中,如果要使用swizzle运算符,则需要在包含glm之前定义GLM_FORCE_SWIZZLE。不推荐使用GLM_SWIZZLE。

#define GLM_FORCE_SWIZZLE
#include "glm/glm.hpp"

然后您可以像这样使用它:

return world1.yx();

在某些编译器上,您也可以这样做:

return world1.yx;

警告:请注意,如果启用它,将会对性能产生巨大影响。 在Visual Studio 2013上,我测量了运行时矩阵乘法中x150左右的速度差异。

进行细雨操作:每秒45万次乘法。

不进行任何麻烦的操作:每秒6500万次乘法。