求教关于opengl函数glGetFloatv(GL_MODELVIEW_MATRIX, m)效率问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求教关于opengl函数glGetFloatv(GL_MODELVIEW_MATRIX, m)效率问题相关的知识,希望对你有一定的参考价值。

用glut编程,使用glGetFloatv查询当前模型视图矩阵(在主循环中调用,之后还调用了glutPostRedisplay)发现速度很慢。。问glGet*函数的效率。如果需要频繁获得当前模型视图矩阵有没有更高效的方法?还是说我需要改变设计策略。。。还是说其实这是其他的问题。。
求高手解答

参考技术A 压栈,或者用显示列表保存追问

不解···
压栈,就是说不用他的模型视图堆栈,自己建栈么?
显示列表不能存储glGet函数吧,再说显示列表里的内容似乎不能改变吧,我要查经常改变的值

追答

额。。。只是用glpushmatrix压入当前堆栈
不过一定要查询么,那要读到内存中,肯定快不起来吧,最好在显卡里处理了比较好

本回答被提问者采纳
参考技术B CGLView::CGLView()

// TODO: add construction code here
m_bleftMouseButtonPress=false;
m_fXAngleDiff=0;
m_fYAngleDiff=0;
m_fZAngleDiff=0;
m_nRotWay=-1;
m_MousePoint=0;



CGLView::~CGLView()



BOOL CGLView::PreCreateWindow(CREATESTRUCT& cs)

// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN ;
return CView::PreCreateWindow(cs);


/////////////////////////////////////////////////////////////////////////////
// CGLView drawing

void CGLView::OnDraw(CDC* pDC)

CGLDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
glClearColor(0,0,0,0);
glClear( GL_COLOR_BUFFER_BIT );
glLoadIdentity();
/*
glColor3f(0.0,0.8,0.8);
for (float i=0.1;i<2;i+=0.01)

display.GL_Vertex(0,0.5,1,i,0.4,0.3);


display.GL_Line(1,2,1,-0.5,0.4,0.1,0.5,0.8,0.8);

display.GL_Triangle(0.8,0.5,0.5,-0.5,0.5,0.5,0.5,-0.5,0.5,0.3,0.3,0.5);

glTranslatef(0,0.0,0);
glRotatef(45,1,1,1);
glColor3f(0.2,0.4,0.8);
// auxWireTeapot(0.5);

glRotatef(45,1,1,1);
glColor3f(0.8,0.7,0.3);
// auxWireCube(1.0);*/

// display.GL_Quad(0,1,0,0.5,0.5,0.5,0.2,3,0,4,3,1,4,0,0);
GLfloat mat_specular[] = ;
GLfloat mat_shininess[] = ;
GLfloat light_position[] = ;
GLfloat white_light[] = ;
GLfloat lmodel_ambient[]=;

glClearColor(0.0,0.6,0.0,0.0);

glShadeModel(GL_SMOOTH);
glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);
glLightfv(GL_LIGHT0,GL_POSITION,light_position);
glLightfv(GL_LIGHT0,GL_DIFFUSE,white_light);
glLightfv(GL_LIGHT0,GL_SPECULAR,white_light);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,lmodel_ambient);

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);

glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
// glRotatef(45,1,1,1);
glRotatef(m_fYAngleDiff/3,1,0,0);
glRotatef(m_fXAngleDiff/3,0,1,0);

glTranslatef(0,-0.3,0.0);
// glutSolidTeapot(0.5);
glutSolidCube(0.8);
glTranslatef(0.0,0.9,0.0);
GLfloat white_light0[] = ;
glLightfv(GL_LIGHT0,GL_DIFFUSE,white_light0);
glLightfv(GL_LIGHT0,GL_SPECULAR,white_light0);
glScalef(1.5,1.0,1.0);
glColor4f(0.0,0.8,0.0,0.2);
glutSolidSphere(0.5,16,16);
glTranslatef(-0.8,0,0);
// glutSolidCube(0.8);

// glTranslatef(0.5,-0.5,0.0);
glRotatef(m_fYAngleDiff/3,1,0,0);
glRotatef(m_fXAngleDiff/3,0,1,0);
GLfloat white_light1[] = ;
glLightfv(GL_LIGHT0,GL_DIFFUSE,white_light1);
glLightfv(GL_LIGHT0,GL_SPECULAR,white_light1);
// glutSolidCube(0.8);
GLfloat a[10];
glGetFloatv(GL_SMOOTH_LINE_WIDTH_GRANULARITY,a);

//glFlush();
SwapBuffers(m_hDC );


/////////////////////////////////////////////////////////////////////////////
// CGLView printing

BOOL CGLView::OnPreparePrinting(CPrintInfo* pInfo)

// default preparation
return DoPreparePrinting(pInfo);


void CGLView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)

// TODO: add extra initialization before printing


void CGLView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)

// TODO: add cleanup after printing


/////////////////////////////////////////////////////////////////////////////
// CGLView diagnostics

#ifdef _DEBUG
void CGLView::AssertValid() const

CView::AssertValid();


void CGLView::Dump(CDumpContext& dc) const

CView::Dump(dc);


CGLDoc* CGLView::GetDocument() // non-debug version is inline

ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CGLDoc)));
return (CGLDoc*)m_pDocument;

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CGLView message handlers

int CGLView::OnCreate(LPCREATESTRUCT lpCreateStruct)

if (CView::OnCreate(lpCreateStruct) == -1)
return -1;

// TODO: Add your specialized creation code here
//设置像素格式
PIXELFORMATDESCRIPTOR pfd =

sizeof( PIXELFORMATDESCRIPTOR ),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
24,
0,0,0,0,0,0,
0,0,0,
0,0,0,0,
8,
0,
0,
PFD_MAIN_PLANE,
0,
0,0,0
;
m_hDC = GetDC()->GetSafeHdc();
//选择匹配的像素格式
int nPixelFormat = ::ChoosePixelFormat( m_hDC, &pfd );
//设置像素格式
::SetPixelFormat( m_hDC, nPixelFormat, &pfd );
//建立新的图形操作描述表
m_hRC = ::wglCreateContext( m_hDC );
//设置当前新的图形操作描述表
::wglMakeCurrent( m_hDC, m_hRC );
return 0;


void CGLView::OnDestroy()

CView::OnDestroy();

// TODO: Add your message handler code here
//设置当前图形操作表为空
::wglMakeCurrent( NULL,NULL );
//销毁图形操作描述表
::wglDeleteContext( m_hRC );


BOOL CGLView::OnEraseBkgnd(CDC* pDC)

// TODO: Add your message handler code here and/or call default
//返回真,不再重绘背景
return true;
// return CView::OnEraseBkgnd(pDC);


void CGLView::OnSize(UINT nType, int cx, int cy)

CView::OnSize(nType, cx, cy);

// TODO: Add your message handler code here

//视口变换:根据客户区的几何比例,定义客户区的中央为视口
display.GL_Resize(cx,cy);



void CGLView::OnLButtonDown(UINT nFlags, CPoint point)

// TODO: Add your message handler code here and/or call default
m_bleftMouseButtonPress=true;
m_MousePoint=point;

CView::OnLButtonDown(nFlags, point);


void CGLView::OnLButtonUp(UINT nFlags, CPoint point)

// TODO: Add your message handler code here and/or call default
m_bleftMouseButtonPress=false;

CView::OnLButtonUp(nFlags, point);
this->Invalidate(false);


void CGLView::OnMouseMove(UINT nFlags, CPoint point)

// TODO: Add your message handler code here and/or call default
float xDiff,yDiff;
if(m_bleftMouseButtonPress)

xDiff=(float)(m_MousePoint.x-point.x);
yDiff=(float)(m_MousePoint.y-point.y);

m_fYAngleDiff+=yDiff;
m_fXAngleDiff+=xDiff;
m_nRotWay=0;
m_MousePoint=point;


CView::OnMouseMove(nFlags, point);

另外,虚机团上产品团购,超级便宜
参考技术C 额,好像没有,我目前也是这样用的

资源泄露 opengl/win32

【中文标题】资源泄露 opengl/win32【英文标题】:Resource Leak opengl/win32 【发布时间】:2016-09-16 23:13:55 【问题描述】:

您好,我最近开始学习 win32/opengl,并设法编写了一个在窗口中显示多色立方体的函数。我的问题是存在资源泄漏,但我很困惑,不确定我到底忘记删除什么。

注意我已经把它缩小到这个函数内

void display() 

    g.hglrc = wglCreateContext(g.hdc);
    wglMakeCurrent(g.hdc, g.hglrc);

    // make the color a white hue  
    glClearColor(1.0F, 1.0F, 1.0F, 1.0F);

    //  Clear screen and Z-buffer
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Reset transformations
    glLoadIdentity();

    // Rotate when user changes rotate_x and rotate_y
    glRotatef(rotate_x, 1.0, 0.0, 0.0);
    glRotatef(rotate_y, 0.0, 1.0, 0.0);

    //Multi-colored side - FRONT
    glBegin(GL_POLYGON);
    glColor3f(1.0, 0.0, 0.0);     glVertex3f(0.5, -0.5, -0.5);      // P1 is red
    glColor3f(0.0, 1.0, 0.0);     glVertex3f(0.5, 0.5, -0.5);      // P2 is green
    glColor3f(0.0, 0.0, 1.0);     glVertex3f(-0.5, 0.5, -0.5);      // P3 is blue
    glColor3f(1.0, 0.0, 1.0);     glVertex3f(-0.5, -0.5, -0.5);      // P4 is purple
    glEnd();

    // White side - BACK
    glBegin(GL_POLYGON);
    glColor3f(1.0, 1.0, 1.0);
    glVertex3f(0.5, -0.5, 0.5);
    glVertex3f(0.5, 0.5, 0.5);
    glVertex3f(-0.5, 0.5, 0.5);
    glVertex3f(-0.5, -0.5, 0.5);
    glEnd();

    // Purple side - RIGHT
    glBegin(GL_POLYGON);
    glColor3f(1.0, 0.0, 1.0);
    glVertex3f(0.5, -0.5, -0.5);
    glVertex3f(0.5, 0.5, -0.5);
    glVertex3f(0.5, 0.5, 0.5);
    glVertex3f(0.5, -0.5, 0.5);
    glEnd();

    // Green side - LEFT
    glBegin(GL_POLYGON);
    glColor3f(0.0, 1.0, 0.0);
    glVertex3f(-0.5, -0.5, 0.5);
    glVertex3f(-0.5, 0.5, 0.5);
    glVertex3f(-0.5, 0.5, -0.5);
    glVertex3f(-0.5, -0.5, -0.5);
    glEnd();

    // Blue side - TOP
    glBegin(GL_POLYGON);
    glColor3f(0.0, 0.0, 1.0);
    glVertex3f(0.5, 0.5, 0.5);
    glVertex3f(0.5, 0.5, -0.5);
    glVertex3f(-0.5, 0.5, -0.5);
    glVertex3f(-0.5, 0.5, 0.5);
    glEnd();

    // Red side - BOTTOM
    glBegin(GL_POLYGON);
    glColor3f(1.0, 0.0, 0.0);
    glVertex3f(0.5, -0.5, -0.5);
    glVertex3f(0.5, -0.5, 0.5);
    glVertex3f(-0.5, -0.5, 0.5);
    glVertex3f(-0.5, -0.5, -0.5);
    glEnd();

    wglMakeCurrent(NULL, NULL);

    SwapBuffers(g.hdc);
    ReleaseDC(g.hwnd, g.hdc);
    wglDeleteContext(g.hglrc);

【问题讨论】:

是什么让你认为存在“资源泄漏”? 如果我让程序与显示调用一起运行,内存使用量很容易上升到 100 mb 并继续增长。如果我删除对这个函数的调用,无论它运行多长时间,使用量都会保持在 27-28mbs 左右。所以我认为这是资源泄漏的结果,因为我没有看到任何其他会导致这种行为的东西。 注释掉函数的内容,验证问题是否消失,然后逐渐取消注释一行/部分,直到问题再次出现。 请停止更改问题。 当您怀疑有泄漏时,更好的工作方法是使用名为 Valgrind 的工具。它将缩小到特定的呼叫。将该工具的输出粘贴到 SO 问题可能会得到更快的答案。 【参考方案1】:
g.hglrc = wglCreateContext(g.hdc);

不要那样做。

您不必在每次需要重绘屏幕时都创建渲染上下文。你创建它一次;只有当你的 window 消失时它才会消失。

现在,这并不一定能证明为什么创建和销毁渲染上下文会留下资源。但这无关紧要;由于性能,你不应该这样做。渲染上下文创建和销毁不是一个快速的过程,也不是这样。

【讨论】:

你说得对,当我将它从函数中取出时,性能会得到显着提升,但资源泄漏仍然存在。 不只是您指出的那一行,而且显示循环中的所有 wgl 调用,尤其是靠近底部的其他 win32 行,它们使当前上下文为空并释放 DC 无疑会导致一些资源颠簸。

以上是关于求教关于opengl函数glGetFloatv(GL_MODELVIEW_MATRIX, m)效率问题的主要内容,如果未能解决你的问题,请参考以下文章

求教OpenGL中GLM库的使用方法有哪些?

求教OpenGL中GLM库的使用方法有哪些?

获取当前 ModelView 矩阵

将 OpenGL 4x4 矩阵转换为旋转角度

关于C语言的语法中类型转换的一个问题。求教C语言高手。

求教关于被调函数中的malloc与free