2

I have a problem in a program I am writing that shaders in correspondence to OpenGL ES 2.0 and EGL wont compile. Ive tried many things as of now.

I have shrunk down the stuff to a small example:

#include <X11/Xlib.h>

#include <EGL/egl.h>
#include <GLES2/gl2.h>

#include <stdio.h>
#include <stdlib.h>

Display *x11_disp = NULL;
EGLDisplay display = EGL_NO_DISPLAY;
EGLContext context = EGL_NO_CONTEXT;
EGLConfig config = NULL;

static const GLchar * sFragShader_Rect =
    "precision mediump float;\n"
    "varying vec4 v_color;\n"
    "void main() {\n"
    "   gl_FragColor = v_color;\n"
    "}\n";

static const GLchar * sVertShader_Rect =
    "uniform mat4 modelviewProjection;\n"
    "attribute vec4 pos;\n"
    "attribute vec4 color;\n"
    "varying vec4 v_color;\n"
    "void main() {\n"
    "   gl_Position = modelviewProjection * pos;\n"
    "   v_color = color;\n"
    "}\n";

static const GLchar * sFragShader_Texture =
    "precision mediump float;\n"
    "uniform sampler2D tex;\n"
    "varying vec2 v_texcoord;\n"
    "void main() {\n"
    "   gl_FragColor = texture2D(tex, v_texcoord);\n"
    "}\n";

static const GLchar * sVertShader_Texture =
    "uniform mat4 modelviewProjection;\n"
    "attribute vec4 pos;\n"
    "attribute vec2 texcoord;\n"
    "varying vec2 v_texcoord;\n"
    "void main() {\n"
    "   gl_Position = modelviewProjection * pos;\n"
    "   v_texcoord = texcoord;\n"
    "}\n";

uint32_t FragmentShaderRect = 0;
uint32_t VertexShaderRect = 0;
uint32_t FragmentShaderTexture = 0;
uint32_t VertexShaderTexture = 0;
uint32_t ProgramRext = 0;
uint32_t ProgramTexture = 0;

uint32_t createShader(uint32_t shader_type, const char *source)
{
    GLenum error;
    GLint status = GL_FALSE;
    GLuint shader = glCreateShader(shader_type);
    error = glGetError();
    if (error != GL_NO_ERROR)
    {
        printf("Error creating shader.");
        return 0;
    }
    glShaderSource(shader, 1, &source, NULL);
    error = glGetError();
    if (error != GL_NO_ERROR)
    {
        printf("Error setting shader source.");
        return 0;
    }
    glCompileShader(shader);
    error = glGetError();
    if (error != GL_NO_ERROR)
    {
        printf("Error compiling shader.");
        return 0;
    }
    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
    if (status != GL_TRUE)
    {
        char log[1000] = {};
        GLsizei len;
        glGetShaderInfoLog(shader, 1000, &len, log);
        printf("GL_Error (%d): %s\n", len, log);
    }
    else
    {
        printf("Shader compile success.\n");
    }
    return shader;
}

void initialize()
{
    XInitThreads();
    x11_disp = XOpenDisplay(NULL);
    if (x11_disp == NULL)
    {
        printf("Error opening display.\n");
        exit(-1);
    }
    display = eglGetDisplay(x11_disp);
    if (display == EGL_NO_DISPLAY)
    {
        printf("Error getting display.\n");
        exit(-1);
    }

    eglInitialize(display, NULL, NULL);

    EGLint n_config;
    EGLint attributes[] = {
        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_DEPTH_SIZE, 24,
        EGL_RED_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_BLUE_SIZE, 8,
        EGL_ALPHA_SIZE, 8,
        EGL_NONE
    };

    if (eglChooseConfig(display, attributes, &config, 1, &n_config) == EGL_FALSE)
    {
        printf("Error getting config.\n");
        exit(-1);
    }

    if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE)
    {
        printf("Could not bind api.\n");
        exit(-1);
    }

    EGLint ctx_attribs[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };

    context = eglCreateContext(display, config, EGL_NO_CONTEXT, ctx_attribs);
    if (context == EGL_NO_CONTEXT)
    {
        printf("Could not create context");
        exit(-1);
    }

    // GLES STUFF
    glGetError(); // clear the error

    GLenum error;

    FragmentShaderRect = createShader(GL_FRAGMENT_SHADER, sFragShader_Rect);
    VertexShaderRect = createShader(GL_VERTEX_SHADER, sVertShader_Rect);
    FragmentShaderTexture = createShader(GL_FRAGMENT_SHADER, sFragShader_Texture);
    VertexShaderTexture = createShader(GL_VERTEX_SHADER, sVertShader_Texture);    
}

int main()
{
    initialize();
    return 0;
}

Compile with gcc -o egltest egltest.c -lEGL -lGLESv2 -lX11

I don't get an error message either.

pgSystemTester
  • 8,979
  • 2
  • 23
  • 49
Nidhoegger
  • 4,973
  • 4
  • 36
  • 81
  • your shaders are missing the mandatory version directive: `#version 100`. From es glsl spec: "Each compilation unit should declare the version of the language it is written to using the #version directive: #version number where number must be 100 for this specification’s version of the language... The #version directive must occur in a compilation unit before anything else, except for comments and white space" – Andreas May 14 '19 at 07:47
  • 1
    I'm not familiar with *egl*, but do you have to make the contex current ([`eglMakeCurrent`](https://www.khronos.org/registry/EGL/sdk/docs/man/html/eglMakeCurrent.xhtml))? – Rabbid76 May 14 '19 at 07:50
  • That was it, thanks... The makeCurrent... – Nidhoegger May 14 '19 at 08:16
  • One quick question: Is a surface NEEDED in order to compile a shader or is a context enough? – Nidhoegger May 14 '19 at 08:19
  • @Nidhoegger You need the surface to get a context with Version OpenGL ES 2.0 – Rabbid76 May 14 '19 at 09:33
  • why? there is no surface involved in context creation – Nidhoegger May 14 '19 at 10:22
  • @Nidhoegger See [Creating OpenGL context without window](https://stackoverflow.com/questions/12482166/creating-opengl-context-without-window) – Rabbid76 May 14 '19 at 10:32

1 Answers1

1

Based on Rabbid76 comment:

eglCreateContext does not make the context current, you need to call eglMakeCurrent afterwards:

context = eglCreateContext(display, config, EGL_NO_CONTEXT, ctx_attribs);
eglMakeCurrent(display, surface, surface, context);

...where surface is created by one of eglCreateWindowSurface (XWindow) eglCreatePBufferSurface (more or less an OpenGL framebuffer), or eglCreatePixmapSurface (XPixmap).

Andreas
  • 5,086
  • 3
  • 16
  • 36