linux下使用opengL Glad + EGL问题记录

为什么写这篇博客

我在linux下想使用Glad + EGL来实现一个程序,对Glad的学习使用基本都是通过LearnOpenGL这个网站,由于其中使用的窗口库是glfw,当我将窗口库换成EGL碰到很多问题,所以写一篇博客记录一下,怕以后忘记,是我第一次写,也希望能帮助到大家。最后回贴上代码。

Glad

Glad不过多介绍,可以帮助我们更方便的使用openGL。
由于要我要使用EGL,偶然在glad文件生成网站发现可以生成EGL的glad封装库,目前还没尝试去使用。

EGL

一个窗口库,需要和平台窗口连接才能使用,比如我在Linux,就和linux的X11创建的窗口进行连接(linux下应该有很多创建窗口的方法,这一块我不太清楚)

第一问:gladLoadGLLoader

我一开始以为这个函数和glfw有关,所以直接删掉了,后来排查问题的时候发现想要使用glad就必须要先调用这个函数。在glfw中是:
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)

那么EGL怎么办呢?一开始各种网上冲浪搜索,都不知道冲到那个洋去了,其实很简单:
gladLoadGLLoader((GLADloadproc)eglGetProcAddress)
哈哈!!!

第二问:GLSL 3.30 is not supported. Supported versions are: 1.00 ES,3.00ES

因为我是根据learnOpenGL网站上写的,那个网站上用的就是GLSL 3.30,这一下好了,不支持,我一搜这个问题,有人说是openGL版本的问题,也没有个解决办法,后面仔细一想,这不对啊。我从learnOpenGL网站上复制的代码能运行,上面用的就是3.3啊。关于这个问题,个人觉得是跟窗口的平台、gladLoadGLLoader函数有关,因为使用glfw的时候,就可以正常使用。

那我是怎么解决的呢
先学习一下ES 3.0,了解和GLSL3.30有什么区别
,可参考:
https://www.jianshu.com/p/2ce67644eae8
最后发现着色器的写法有些不一样。

第三问:编译能通过,运行的时候出现Segmentation fault

我第一次出现这个问题是执行到glCreateShader这个函数这里(通过gdb调试),此函数生成一个着色器,但是我的着色器是从learnOpenGL上复制的,就是vertexShaderSource 和 fragmentShaderSource ,我不明白为什么会生成失败,现在发现是由于版本的问题的,各个版本的这个写法好像有些不一样,这一块还不太清楚。

代码

#include <glad/glad.h>
#include  <iostream>
#include  <cstdlib>
#include  <cstring>
#include  <cmath>
#include  <sys/time.h>
#include  <X11/Xlib.h>
#include  <EGL/egl.h>

using namespace std;
// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;

const char *vertexShaderSource = "#version 300 es\n"
    "layout (location = 0) in vec3 aPos;\n"
    "void main()\n"
    "{\n"
    "   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
    "}\0";
const char *fragmentShaderSource = "#version 300 es\n"
	"precision mediump float;                     \n"
    "out vec4 FragColor;\n"
    "void main()\n"
    "{\n"
    "   FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
    "}\n\0";

int main()
{
	// in the first part the program opens a connection to the X11 window manager
	Display* x_display = XOpenDisplay ( NULL );   // open the standard display (the primary screen)
	if ( x_display == NULL ) {
		cerr << "cannot connect to X server" << endl;
		return 1;
	}
	Window root  =  DefaultRootWindow( x_display );   // get the root window (usually the whole screen)
	XSetWindowAttributes  swa;
	swa.event_mask  =  ExposureMask | PointerMotionMask | KeyPressMask;
	Window win  =  XCreateWindow (   // create a window with the provided parameters
												 x_display, root,
												 0, 0, 800, 480,   0,
												 CopyFromParent, InputOutput,
												 CopyFromParent, CWEventMask,
												 &swa );
	/* 选择一种感兴趣的事件进行监听 */
    XSelectInput(x_display, win, ExposureMask | KeyPressMask);
    /* 显示窗口 */
    XMapWindow(x_display, win);
	
///  the egl part  //
	EGLDisplay  egl_display;
	EGLContext  egl_context;
	EGLSurface  egl_surface;
	egl_display  =  eglGetDisplay( (EGLNativeDisplayType) x_display );
	if ( egl_display == EGL_NO_DISPLAY ) {
		cerr << "Got no EGL display." << endl;
		return 1;
	}
	if ( !eglInitialize( egl_display, NULL, NULL ) ) {
		cerr << "Unable to initialize EGL" << endl;
		return 1;
	}
	EGLint attr[] = {       // some attributes to set up our egl-interface
		EGL_BUFFER_SIZE, 16,
		EGL_RENDERABLE_TYPE,
		EGL_OPENGL_ES2_BIT,
		EGL_NONE
	};
	EGLConfig  ecfg;
	EGLint     num_config;
	if ( !eglChooseConfig( egl_display, attr, &ecfg, 1, &num_config ) ) {
		cerr << "Failed to choose config (eglError: " << eglGetError() << ")" << endl;
		return 1;
	}
	if ( num_config != 1 ) {
		cerr << "Didn't get exactly one config, but " << num_config << endl;
		return 1;
	}
	egl_surface = eglCreateWindowSurface ( egl_display, ecfg, win, NULL );
	if ( egl_surface == EGL_NO_SURFACE ) {
		cerr << "Unable to create EGL surface (eglError: " << eglGetError() << ")" << endl;
		return 1;
	}
	// egl-contexts collect all state descriptions needed required for operation
	EGLint ctxattr[] = {
		EGL_CONTEXT_CLIENT_VERSION, 2,
		EGL_NONE
	};
	egl_context = eglCreateContext ( egl_display, ecfg, EGL_NO_CONTEXT, ctxattr );
	if ( egl_context == EGL_NO_CONTEXT ) {
		cerr << "Unable to create EGL context (eglError: " << eglGetError() << ")" << endl;
		return 1;
	}
	eglMakeCurrent( egl_display, egl_surface, egl_surface, egl_context );

    // glad: load all OpenGL function pointers
    // ---------------------------------------
    if (!gladLoadGLLoader((GLADloadproc)eglGetProcAddress))
    {
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }

    // build and compile our shader program
    // ------------------------------------
    // vertex shader
    unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);
    // check for shader compile errors
    int success;
    char infoLog[512];
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
    }
    // fragment shader
    unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);
    // check for shader compile errors
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
    }
    // link shaders
    unsigned int shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    // check for linking errors
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
    if (!success) {
        glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
    }
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    float vertices[] = {
        -0.5f, -0.5f, 0.0f, // left  
         0.5f, -0.5f, 0.0f, // right 
         0.0f,  0.5f, 0.0f  // top   
    }; 
	glUseProgram(shaderProgram);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices);
    glEnableVertexAttribArray(0);
    
    XEvent xev;
	bool quit = false;
	while ( !quit ) {    // the main loop
		XNextEvent(x_display, &xev);
		if ( xev.type == KeyPress )   quit = true;
	 	glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
         glClear(GL_COLOR_BUFFER_BIT);
         // draw our first triangle
         glUseProgram(shaderProgram);
         glDrawArrays(GL_TRIANGLES, 0, 3);
         eglSwapBuffers ( egl_display, egl_surface );  // get the rendered buffer to the screen

	}
	eglDestroyContext ( egl_display, egl_context );
	eglDestroySurface ( egl_display, egl_surface );
	eglTerminate      ( egl_display );
	XDestroyWindow    ( x_display, win );
	XCloseDisplay     ( x_display );
    glDeleteProgram(shaderProgram);
    return 0;
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值