不同的opengl上下文是不是有不同的opengl扩展?
Posted
技术标签:
【中文标题】不同的opengl上下文是不是有不同的opengl扩展?【英文标题】:Does different opengl context has different opengl extension?不同的opengl上下文是否有不同的opengl扩展? 【发布时间】:2016-09-17 16:55:49 【问题描述】:我正在做一个使用opengl离屏渲染的项目。但是在我创建opengl上下文后,我发现一些opengl扩展无法使用。例如:
#include <windows.h>
#include <GL/glew.h>
#include <iostream>
#include <gl/gl.h>
#include <gl/glu.h>
#include <string>
#include <time.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
void mGLRender()
glClearColor(0.9f, 0.9f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(30.0, 1.0, 1.0, 10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 0, -5, 0, 0, 0, 0, 1, 0);
glBegin(GL_TRIANGLES);
glColor3d(1, 0, 0);
glVertex3d(0, 1, 0);
glColor3d(0, 1, 0);
glVertex3d(-1, -1, 0);
glColor3d(0, 0, 1);
glVertex3d(1, -1, 0);
glEnd();
glFlush(); // remember to flush GL output!
void mGLRender1()
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(30.0, 1.0, 1.0, 10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 0, -5, 0, 0, 0, 0, 1, 0);
glBegin(GL_TRIANGLES);
glColor3d(1, 0, 0);
glVertex3d(0, 1, 0);
glColor3d(0, 1, 0);
glVertex3d(-1, -1, 0);
glColor3d(0, 0, 1);
glVertex3d(1, -1, 0);
glEnd();
glFlush(); // remember to flush GL output!
int main(int argc, char* argv[])
clock_t clockBegin, clockEnd;
const int WIDTH = 400;
const int HEIGHT = 400;
// Create a memory DC compatible with the screen
HDC hdc = CreateCompatibleDC(0);
if (hdc == 0) cout << "Could not create memory device context";
// Create a bitmap compatible with the DC
// must use CreateDIBSection(), and this means all pixel ops must be synchronised
// using calls to GdiFlush() (see CreateDIBSection() docs)
BITMAPINFO bmi =
sizeof(BITMAPINFOHEADER), WIDTH, HEIGHT, 1, 32, BI_RGB, 0, 0, 0, 0, 0 ,
0
;
unsigned char *pbits; // pointer to bitmap bits
HBITMAP hbm = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void **)&pbits,
0, 0);
if (hbm == 0) cout << "Could not create bitmap";
//HDC hdcScreen = GetDC(0);
//HBITMAP hbm = CreateCompatibleBitmap(hdcScreen,WIDTH,HEIGHT);
// Select the bitmap into the DC
HGDIOBJ r = SelectObject(hdc, hbm);
if (r == 0) cout << "Could not select bitmap into DC";
// Choose the pixel format
PIXELFORMATDESCRIPTOR pfd =
sizeof(PIXELFORMATDESCRIPTOR), // struct size
1, // Version number
PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL, // use OpenGL drawing to BM
PFD_TYPE_RGBA, // RGBA pixel values
32, // color bits
0, 0, 0, // RGB bits shift sizes...
0, 0, 0, // Don't care about them
0, 0, // No alpha buffer info
0, 0, 0, 0, 0, // No accumulation buffer
32, // depth buffer bits
0, // No stencil buffer
0, // No auxiliary buffers
PFD_MAIN_PLANE, // Layer type
0, // Reserved (must be 0)
0, // No layer mask
0, // No visible mask
0, // No damage mask
;
int pfid = ChoosePixelFormat(hdc, &pfd);
if (pfid == 0) cout << "Pixel format selection failed";
// Set the pixel format
// - must be done *after* the bitmap is selected into DC
BOOL b = SetPixelFormat(hdc, pfid, &pfd);
if (!b) cout << "Pixel format set failed";
// Create the OpenGL resource context (RC) and make it current to the thread
HGLRC hglrc = wglCreateContext(hdc);
if (hglrc == 0) cout << "OpenGL resource context creation failed";
wglMakeCurrent(hdc, hglrc);
GLenum err = glewInit();
if (GLEW_OK != err)
/* Problem: glewInit failed, something is seriously wrong. */
std::cout << "glew init error" << std::endl;
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
std::cout << (glewGetExtension("GL_ARB_fragment_shader") == GL_TRUE);
std::cout << (glewGetExtension("GL_ARB_shader_objects") == GL_TRUE);
std::cout << (glewGetExtension("GL_ARB_shading_language_100") == GL_TRUE);
// Draw using GL - remember to sync with GdiFlush()
clockBegin = clock();
GdiFlush();
mGLRender();
//SaveBmp(hbm,"output.bmp");
clockEnd = clock();
printf("%d\n", clockEnd - clockBegin);
clockBegin = clock();
GdiFlush();
mGLRender1();
//SaveBmp(hbm,"output1.bmp");
clockEnd = clock();
printf("%d\n", clockEnd - clockBegin);
//opencv show img
Mat img(HEIGHT, WIDTH, CV_8UC4, (void *)pbits);
imshow("img", img);
waitKey();
destroyWindow("img");
// Clean up
wglDeleteContext(hglrc); // Delete RC
SelectObject(hdc, r); // Remove bitmap from DC
DeleteObject(hbm); // Delete bitmap
DeleteDC(hdc); // Delete DC
system("pause");
return 0;
以上代码在 vs2015 中运行良好。但是行:
std::cout << (glewGetExtension("GL_ARB_fragment_shader") == GL_TRUE);
原来 GL_ARB_fragment_shader 扩展是不可用的。但我确信我的 gpu 支持这个扩展。因为在一个简单的 freeglut 应用程序中,glewGetExtension("GL_ARB_fragment_shader") 返回 True。代码在这里:
#include <stdlib.h>
#include <GL/glew.h>
#include <GL/glut.h>
#include <iostream>
// Window attributes
static const unsigned int WIN_POS_X = 30;
static const unsigned int WIN_POS_Y = WIN_POS_X;
static const unsigned int WIN_WIDTH = 512;
static const unsigned int WIN_HEIGHT = WIN_WIDTH;
void glInit(int, char **);
int main(int argc, char * argv[])
// Initialize OpenGL
glInit(argc, argv);
// A valid OpenGL context has been created.
// You can call OpenGL functions from here on.
GLenum err = glewInit();
if (GLEW_OK != err)
/* Problem: glewInit failed, something is seriously wrong. */
std::cout << "glew init error" << std::endl;
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
std::cout << (glewGetExtension("GL_ARB_fragment_shader") == GL_TRUE);
std::cout << (glewGetExtension("GL_ARB_shader_objects") == GL_TRUE);
std::cout << (glewGetExtension("GL_ARB_shading_language_100") == GL_TRUE);
glutMainLoop();
return 0;
void Display()
// end Display()
void glInit(int argc, char ** argv)
// Initialize GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE);
glutInitWindowPosition(WIN_POS_X, WIN_POS_Y);
glutInitWindowSize(WIN_WIDTH, WIN_HEIGHT);
glutCreateWindow("Hello OpenGL!");
glutDisplayFunc(Display);
return;
以上代码在 vs2015 中运行良好。以及 glewGetExtension("GL_ARB_fragment_shader") 的值 是真的。那么不同的opengl上下文有不同的opengl扩展吗?请帮帮我。
【问题讨论】:
您要求的是最基本的上下文,而 GLEW 可能会要求更新的上下文。glFlush(); // remember to flush GL output!
你几乎不需要这样做。
【参考方案1】:
是的,不同的 OpenGL 上下文可能支持不同的 OpenGL 版本和/或扩展。在您的特定情况下,您正在创建的屏幕外上下文将使用 GDI 软件光栅化器后备。 你创建上下文的方式永远不会被 GPU 加速!
如果你想创建一个 GPU 加速的 OpenGL 上下文,你要么必须这样做
使用 PBuffer(它为您提供没有窗口的 HDC)或
在隐藏窗口上创建 OpenGL 上下文并渲染到 FBO(目前最常用的方法)或
使用一种新的独立于操作系统的纯屏幕外上下文创建方法(例如,请参阅 https://devblogs.nvidia.com/parallelforall/egl-eye-opengl-visualization-without-x-server/ 了解如何在 NVidia 上执行此操作 - 也适用于 Windows)然而,即使 OpenGL 上下文是 GPU 加速的,即使它们碰巧是在同一台机器和 GPU 上创建的,它们的版本和扩展支持也可能不同。
【讨论】:
以上是关于不同的opengl上下文是不是有不同的opengl扩展?的主要内容,如果未能解决你的问题,请参考以下文章
在 OS X 上的 OpenGL 上下文之间共享数据(不同的版本/配置文件)