glUseProgram() GL_INVALID_OPERATION 1282 on Ubuntu Gnome 17.04 Intel HD4000 - linux

I'm trying to learn openGL 3.0 by following the example on https://open.gl/drawing (It just draws a coloured rectangle on the screen).
I am using SDL2.0.5 and glew 2.0.0 with VS2015 community and it works perfectly on my i5 skylake HD4000 laptop running Win7 pro x64. However when I compile the exact same source on Ubuntu Gnome 17.04 x64 on the same laptop (dual booting Win and Linux) with gcc and glew 2.0.0, I get a GL_INVALID_OPERATION 1282 error at glUseProgram(shaderProgram).
Compiler runs with no warnings:
g++ main.cpp -Wall -I/usr/include/SDL2 -lGL -lGLEW -lSDL2 -lSDL2_image -lSDL2_mixer -o game
There are no errors before this function, (I removed the error checking code for clarity).
Also the screen goes from normal desktop to a blank black screen, then repeats until I quit the app. The screen blanking does not happen if I comment out the SDL_GL_SwapWindow(gameWindow), but the error is still there.
I have tried changing the context to 3.3 and shader versions to #version 330 core - same problem.
I also used the Intel Graphics Update Tool to get the latest drivers.
Some system info below:
product: Intel(R) Core(TM) i5-3340M CPU # 2.70GHz
vendor: Intel Corp.
physical id: 1
bus info: cpu#0
size: 3199MHz
capacity: 3400MHz
width: 64 bits
capabilities: fpu fpu_exception wp vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp x86-64 constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm epb tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt dtherm ida arat pln pts cpufreq
description: VGA compatible controller
product: 3rd Gen Core processor Graphics Controller
vendor: Intel Corporation
physical id: 2
bus info: pci#0000:00:02.0
version: 09
width: 64 bits
clock: 33MHz
capabilities: msi pm vga_controller bus_master cap_list rom
configuration: driver=i915 latency=0
resources: irq:29 memory:f6400000-f67fffff memory:e0000000-efffffff ioport:f000(size=64) memory:c0000-dffff
OpenGL vendor string: Intel Open Source Technology Center
OpenGL renderer string: Mesa DRI Intel(R) Ivybridge Mobile
OpenGL core profile version string: 3.3 (Core Profile) Mesa 17.0.3
OpenGL core profile shading language version string: 3.30
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile
OpenGL core profile extensions:
OpenGL version string: 3.0 Mesa 17.0.3
OpenGL shading language version string: 1.30
OpenGL context flags: (none)
OpenGL extensions:
OpenGL ES profile version string: OpenGL ES 3.0 Mesa 17.0.3
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.00
OpenGL ES profile extensions:
Source code:
#define GLEW_STATIC
#include <GL/glew.h>
#include <SDL.h>
#include <SDL_opengl.h>
#include <iostream>
// SDL2 global pointers
SDL_Window* gameWindow = NULL;
SDL_GLContext context = NULL;
SDL_Surface* screenSurface = NULL;
SDL_Renderer* gameRenderer = NULL;
// Shader sources
const GLchar* vertexSource = R"glsl(
#version 150 core
in vec2 position;
in vec3 color;
out vec3 Color;
void main()
{
Color = color;
gl_Position = vec4(position, 0.0, 1.0);
}
)glsl";
const GLchar* fragmentSource = R"glsl(
#version 150 core
in vec3 Color;
out vec4 outColor;
void main()
{
outColor = vec4(Color, 1.0);
}
)glsl";
int main(int argc, char *argv[])
{
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
if(SDL_Init(SDL_INIT_EVERYTHING) != 0)
{
printf("SDL_Init failed! Error: %s\n", SDL_GetError());
return -1;
}
else printf("SDL_Init OK.\n");
gameWindow = SDL_CreateWindow("OpenGL", 100, 100, 400, 300, SDL_WINDOW_OPENGL);
if (gameWindow == NULL)
{
printf("SDL_CreateWindow failed! Error: %s\n", SDL_GetError());
SDL_Delay(1000);
SDL_Quit();
return -1;
}
else printf("SDL_CreateWindow OK.\n");
context = SDL_GL_CreateContext(gameWindow);
if(context == NULL)
{
printf("SDL_CreateWindow failed! Error: %s\n", SDL_GetError());
SDL_Delay(1000);
SDL_DestroyWindow(gameWindow);
SDL_Quit();
return -1;
}
else printf("SDL_GL_CreateContext OK.\n");
glewExperimental=GL_TRUE;
GLenum glew_init_error = glewInit();
if (GLEW_OK != glew_init_error)
{
fprintf(stderr, "glewInit failed! Error: %s\n", glewGetErrorString(glew_init_error));
SDL_Delay(1000);
SDL_GL_DeleteContext(context);
SDL_DestroyWindow(gameWindow);
SDL_Quit();
return -1;
}
else fprintf(stdout, "glewInit OK. Version: %s\n", glewGetString(GLEW_VERSION));
// Create Vertex Array Object
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Create a Vertex Buffer Object and copy the vertex data to it
GLuint vbo;
glGenBuffers(1, &vbo);
GLfloat vertices[] = {
-0.5f, 0.5f, 1.0f, 0.0f, 0.0f, // Top-left
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // Top-right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Bottom-right
-0.5f, -0.5f, 1.0f, 1.0f, 1.0f // Bottom-left
};
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// Create an element array
GLuint ebo;
glGenBuffers(1, &ebo);
GLuint elements[] = {
0, 1, 2,
2, 3, 0
};
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
// Create and compile the vertex shader
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexSource, NULL);
glCompileShader(vertexShader);
// Create and compile the fragment shader
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
glCompileShader(fragmentShader);
// Link the vertex and fragment shader into a shader program
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glBindFragDataLocation(shaderProgram, 0, "outColor");
glLinkProgram(shaderProgram);
// ************** THE NEXT FUNCTION CALL FAILS WITH GL_INVALID_OPERATION *********************************
glUseProgram(shaderProgram);
// Specify the layout of the vertex data
GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), 0);
GLint colAttrib = glGetAttribLocation(shaderProgram, "color");
glEnableVertexAttribArray(colAttrib);
glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));
SDL_Event windowEvent;
while (true)
{
if (SDL_PollEvent(&windowEvent))
{
if (windowEvent.type == SDL_QUIT) break;
if (windowEvent.type == SDL_KEYUP && windowEvent.key.keysym.sym == SDLK_ESCAPE) break;
}
// Clear the screen to black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Draw a rectangle from the 2 triangles using 6 indices
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
SDL_GL_SwapWindow(gameWindow);
}
glDeleteProgram(shaderProgram);
glDeleteShader(fragmentShader);
glDeleteShader(vertexShader);
glDeleteBuffers(1, &ebo);
glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);
SDL_GL_DeleteContext(context);
SDL_Delay(1000);
SDL_Quit();
return 0;
}

Check whether the shaders compiled and linked successfully with glGetShaderiv/InfoLog and glGetProgramiv/InfoLog – pleluron
Thanks to Pleluron I added shader and linker error log code and found that, on my core i5 HD4000 Linux, the GPU driver did not support the 1.5 (#version 150) shader version I was using. When I changed the vertex & fragment shader versions to 1.3 (#version 130) and the major/minor SDL context attributes to 3.0 it cured the problem. (Although I did have to modify the shader code for GL3.0/GLSL1.3).
What confuses me is that glxinfo reports OpenGL3.3 and GLSL 3.3 below so I expected to be able to use precisely that...
OpenGL vendor string: Intel Open Source Technology Center
OpenGL renderer string: Mesa DRI Intel(R) Ivybridge Mobile
OpenGL core profile version string: 3.3 (Core Profile) Mesa 17.0.3
OpenGL core profile shading language version string: 3.30
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile
OpenGL core profile extensions:
... but also reports OpenGL 3.0 & GLSL 1.30 below, which seems to be the one being used when the context is created through SDL despite being asked for a higer version?
OpenGL version string: 3.0 Mesa 17.0.3
OpenGL shading language version string: 1.30
OpenGL context flags: (none)
I will dig into this and update this answer.

Related

OpenGL Without GUI

Let's say I run a Linux and I have no desktop environment installed. I boot up my system and all I have is my shell.
Is it possible to compile a program that uses the OpenGL libraries or directly uses the GPU driver to draw to the screen?
As far as I could understand I would always need some kind of desktop environment that would provide me a window that I can draw on. To keep it
simple let's say I just want to draw a simple 2d shape like a triangle in the middle of the screen for example.
And if that's possible how can I do it and where can I read more about the topic? If I am able to draw directly over my terminal does this mean that I would be able to run my app on a system that has a desktop environment and still be able to see my triangle?
Is it possible to compile a program that uses the OpenGL libraries or directly uses the GPU driver to draw to the screen?
Yes. With the EGL API this has been formalized and works most well with NVidia GPUs and their proprietary drivers. NVidia has it described on their dev blog here https://devblogs.nvidia.com/egl-eye-opengl-visualization-without-x-server/
Essentially the steps are:
Create a OpenGL context for a PBuffer
#include <EGL/egl.h>
static const EGLint configAttribs[] = {
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_RED_SIZE, 8,
EGL_DEPTH_SIZE, 8,
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
EGL_NONE
};
static const int pbufferWidth = 9;
static const int pbufferHeight = 9;
static const EGLint pbufferAttribs[] = {
EGL_WIDTH, pbufferWidth,
EGL_HEIGHT, pbufferHeight,
EGL_NONE,
};
int main(int argc, char *argv[])
{
// 1. Initialize EGL
EGLDisplay eglDpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
EGLint major, minor;
eglInitialize(eglDpy, &major, &minor);
// 2. Select an appropriate configuration
EGLint numConfigs;
EGLConfig eglCfg;
eglChooseConfig(eglDpy, configAttribs, &eglCfg, 1, &numConfigs);
// 3. Create a surface
EGLSurface eglSurf = eglCreatePbufferSurface(eglDpy, eglCfg,
pbufferAttribs);
// 4. Bind the API
eglBindAPI(EGL_OPENGL_API);
// 5. Create a context and make it current
EGLContext eglCtx = eglCreateContext(eglDpy, eglCfg, EGL_NO_CONTEXT,
NULL);
eglMakeCurrent(eglDpy, eglSurf, eglSurf, eglCtx);
// from now on use your OpenGL context
// 6. Terminate EGL when finished
eglTerminate(eglDpy);
return 0;
}
and then go about the rest as per usual. Or you can even ditch the PBuffer completely and just use OpenGL manages resources, i.e. render to framebuffer objects. For that end you can omit creating the surface and just make the context current.
Here's an example for using EGL without display, no EGL surface, with OpenGL managed framebuffer.
#include <GL/glew.h>
#include <GL/glut.h>
#include <EGL/egl.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <math.h>
#include <stdio.h>
using namespace std;
namespace render
{
int width, height;
float aspect;
void init();
void display();
int const fbo_width = 512;
int const fbo_height = 512;
GLuint fb, color, depth;
void *dumpbuf;
int dumpbuf_fd;
};
static const EGLint configAttribs[] = {
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_RED_SIZE, 8,
EGL_DEPTH_SIZE, 8,
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
EGL_NONE
};
int main(int argc, char *argv[])
{
// 1. Initialize EGL
EGLDisplay eglDpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
EGLint major, minor;
eglInitialize(eglDpy, &major, &minor);
// 2. Select an appropriate configuration
EGLint numConfigs;
EGLConfig eglCfg;
eglChooseConfig(eglDpy, configAttribs, &eglCfg, 1, &numConfigs);
// 3. Bind the API
eglBindAPI(EGL_OPENGL_API);
// 3. Create a context and make it current
EGLContext eglCtx = eglCreateContext(eglDpy, eglCfg, EGL_NO_CONTEXT,
NULL);
eglMakeCurrent(eglDpy, EGL_NO_SURFACE, EGL_NO_SURFACE, eglCtx);
glewInit();
// from now on use your OpenGL context
render::init();
render::display();
// 4. Terminate EGL when finished
eglTerminate(eglDpy);
return 0;
}
void CHECK_FRAMEBUFFER_STATUS()
{
GLenum status;
status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
switch(status) {
case GL_FRAMEBUFFER_COMPLETE:
break;
case GL_FRAMEBUFFER_UNSUPPORTED:
/* choose different formats */
break;
default:
/* programming error; will fail on all hardware */
throw "Framebuffer Error";
}
}
namespace render
{
float const light_dir[]={1,1,1,0};
float const light_color[]={1,0.95,0.9,1};
void init()
{
glGenFramebuffers(1, &fb);
glGenTextures(1, &color);
glGenRenderbuffers(1, &depth);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glBindTexture(GL_TEXTURE_2D, color);
glTexImage2D( GL_TEXTURE_2D,
0,
GL_RGB8,
fbo_width, fbo_height,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
glBindRenderbuffer(GL_RENDERBUFFER, depth);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, fbo_width, fbo_height);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);
GLint red_bits, green_bits, blue_bits, alpha_bits;
glGetIntegerv(GL_RED_BITS, &red_bits);
glGetIntegerv(GL_GREEN_BITS, &green_bits);
glGetIntegerv(GL_BLUE_BITS, &blue_bits);
glGetIntegerv(GL_ALPHA_BITS, &alpha_bits);
fprintf(stderr, "FBO format R%dG%dB%dA%d\n",
(int)red_bits,
(int)green_bits,
(int)blue_bits,
(int)alpha_bits );
CHECK_FRAMEBUFFER_STATUS();
dumpbuf_fd = open("/tmp/fbodump.rgb", O_CREAT|O_SYNC|O_RDWR, S_IRUSR|S_IWUSR);
assert(-1 != dumpbuf_fd);
dumpbuf = malloc(fbo_width*fbo_height*3);
assert(dumpbuf);
}
void render()
{
static float a=0, b=0, c=0;
glBindTexture(GL_TEXTURE_2D, 0);
glEnable(GL_TEXTURE_2D);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glViewport(0,0,fbo_width, fbo_height);
glClearColor(0,0,0,0);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1, 1, -1, 1, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBegin(GL_TRIANGLES);
glColor3f(1,0,0);
glVertex3f(1,0,0);
glColor3f(0,1,0);
glVertex3f(0,1,0);
glColor3f(0,0,1);
glVertex3f(0,0,1);
glEnd();
glReadBuffer(GL_COLOR_ATTACHMENT0);
glReadPixels(0,0,fbo_width,fbo_height,GL_RGB,GL_UNSIGNED_BYTE,dumpbuf);
lseek(dumpbuf_fd, SEEK_SET, 0);
write(dumpbuf_fd, dumpbuf, fbo_width*fbo_height*3);
}
}

Error CL_DEVICE_NOT_AVAILABLE when calling clCreateContext (Intel Core2Duo, Intel OCL SDK 3.0 beta)

I'm trying to get started with OpenCL (Intel opencl-1.2-3.0.56860). I managed to install the OpenCL SDK from Intel under Ubuntu 12.05 (using "alien" to convert the rpm packages to *.deb packages). Now I try to get my first simple OpenCL program running... To run the program I need to use set the LD_LIBRARY_PATH:
export LD_LIBRARY_PATH=/opt/intel/opencl/lib64/
My Problem is, that I always get the error "CL_DEVICE_NOT_AVAILABLE" when calling clCreateContext(...).
Here is my source code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <CL/cl.h>
#include <CL/cl_platform.h>
#include <string.h>
// Enable double precision values
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
// OpenCL kernel. Each work item takes care of one element of c
const char *kernelSource = "\n" \
"__kernel void vecAdd( __global double *a, \n" \
" __global double *b, \n" \
" __global double *c, \n" \
" const unsigned int n) \n" \
"{ \n" \
" //Get our global thread ID \n" \
" int id = get_global_id(0); \n" \
" \n" \
" //Make sure we do not go out of bounds \n" \
" if (id < n) \n" \
" c[id] = a[id] + b[id]; \n" \
"} \n" \
"\n" ;
const char* err2str(cl_int err) {
switch(err) {
case CL_SUCCESS: return "CL_SUCCESS";
case CL_INVALID_PROGRAM: return "CL_INVALID_PROGRAM";
case CL_INVALID_VALUE: return "CL_INVALID_VALUE";
case CL_INVALID_DEVICE: return "CL_INVALID_DEVICE";
case CL_INVALID_BINARY: return "CL_INVALID_BINARY";
case CL_INVALID_BUILD_OPTIONS: return "CL_INVALID_BUILD_OPTIONS";
case CL_INVALID_OPERATION: return "CL_INVALID_OPERATION";
case CL_DEVICE_NOT_AVAILABLE: return "CL_DEVICE_NOT_AVAILABLE";
default: return "unknown";
}
}
void pfn_notify(const char *errinfo, const void *private_info, size_t cb, void *user_data)
{
fprintf(stderr, "OpenCL Error (via pfn_notify): %s\n", errinfo);
}
cl_platform_id GetIntelOCLPlatform()
{
cl_platform_id pPlatforms[10] = { 0 };
char pPlatformName[128] = { 0 };
cl_uint uiPlatformsCount = 0;
cl_int err = clGetPlatformIDs(10, pPlatforms, &uiPlatformsCount);
for (cl_uint ui = 0; ui < uiPlatformsCount; ++ui)
{
err = clGetPlatformInfo(pPlatforms[ui], CL_PLATFORM_NAME, 128 * sizeof(char), pPlatformName, NULL);
if ( err != CL_SUCCESS )
{
printf("ERROR: Failed to retreive platform vendor name.\n", ui);
return NULL;
}
if (!strcmp(pPlatformName, "Intel(R) OpenCL"))
return pPlatforms[ui];
}
return NULL;
}
int main( int argc, char* argv[] )
{
cl_platform_id cpPlatform; // OpenCL platform
cl_device_id device_id; // device ID
cl_context context; // context
cl_command_queue queue; // command queue
cl_program program; // program
cl_kernel kernel; // kernel
size_t cb;
cl_device_id devices[100];
cl_uint devices_n = 0;
cl_int err;
cl_platform_id intel_platform_id = GetIntelOCLPlatform();
if( intel_platform_id == NULL ) {
printf("ERROR: Failed to find Intel OpenCL platform.\n");
return -1;
}
// Get Device Info...
err = clGetDeviceIDs(intel_platform_id, CL_DEVICE_TYPE_ALL, 100, devices, &devices_n);
printf("ERR(clGetDeviceIDs) = %d\n", err);
printf("#DEVICES: %d\n", devices_n);
for (int i=0; i<devices_n; i++) {
char buffer[10240];
cl_uint buf_uint;
cl_ulong buf_ulong;
printf(" -- %d --\n", i);
err = clGetDeviceInfo(devices[i], CL_DEVICE_NAME, sizeof(buffer), buffer, NULL);
printf(" DEVICE_NAME = %s\n", buffer);
err = clGetDeviceInfo(devices[i], CL_DEVICE_VENDOR, sizeof(buffer), buffer, NULL);
printf(" DEVICE_VENDOR = %s\n", buffer);
err = clGetDeviceInfo(devices[i], CL_DEVICE_VERSION, sizeof(buffer), buffer, NULL);
printf(" DEVICE_VERSION = %s\n", buffer);
err = clGetDeviceInfo(devices[i], CL_DRIVER_VERSION, sizeof(buffer), buffer, NULL);
printf(" DRIVER_VERSION = %s\n", buffer);
err = clGetDeviceInfo(devices[i], CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(buf_uint), &buf_uint, NULL);
printf(" DEVICE_MAX_COMPUTE_UNITS = %u\n", (unsigned int)buf_uint);
err = clGetDeviceInfo(devices[i], CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof(buf_uint), &buf_uint, NULL);
printf(" DEVICE_MAX_CLOCK_FREQUENCY = %u\n", (unsigned int)buf_uint);
err = clGetDeviceInfo(devices[i], CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(buf_ulong), &buf_ulong, NULL);
printf(" DEVICE_GLOBAL_MEM_SIZE = %llu\n", (unsigned long long)buf_ulong);
}
context = clCreateContext(NULL, 1, devices, &pfn_notify, NULL, &err);
printf("ERR(clCreateContext) = %d [%s]\n", err, err2str(err));
// Create a context
cl_context_properties context_properties[3] = {CL_CONTEXT_PLATFORM, (cl_context_properties)intel_platform_id, (cl_context_properties)NULL };
// context = clCreateContext(0, 1, &device_id, NULL, NULL, &err);
context = clCreateContextFromType(context_properties, CL_DEVICE_TYPE_CPU, NULL, NULL, &err);
printf("ERR(clCreateContextFromType) = %d [%s]\n", err, err2str(err));
if (err != CL_SUCCESS) exit(0);
if (context == (cl_context)0) {
printf("Illegal context?");
exit(0);
}
return 0;
}
The Output is:
ERR(clGetDeviceIDs) = 0
#DEVICES: 1
-- 0 --
DEVICE_NAME = Intel(R) Core(TM)2 Duo CPU P7450 # 2.13GHz
DEVICE_VENDOR = Intel(R) Corporation
DEVICE_VERSION = OpenCL 1.2 (Build 56860)
DRIVER_VERSION = 1.2
DEVICE_MAX_COMPUTE_UNITS = 2
DEVICE_MAX_CLOCK_FREQUENCY = 2130
DEVICE_GLOBAL_MEM_SIZE = 3152510976
ERR(clCreateContext) = -2 [CL_DEVICE_NOT_AVAILABLE]
ERR(clCreateContextFromType) = -2 [CL_DEVICE_NOT_AVAILABLE]
Any Ideas how to solve that?
Regards,
Stefan
---- EDIT -----
The CPU has the sse4_1 flag (also: sse, sse2, sss3).
cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 23
model name : Intel(R) Core(TM)2 Duo CPU P7450 # 2.13GHz
stepping : 6
microcode : 0x60c
cpu MHz : 800.000
cache size : 3072 KB
physical id : 0
siblings : 2
core id : 0
cpu cores : 2
apicid : 0
initial apicid : 0
fpu : yes
fpu_exception : yes
cpuid level : 10
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good nopl aperfmperf pni dtes64 monitor ds_cpl est tm2 ssse3 cx16 xtpr pdcm sse4_1 lahf_lm dtherm
bogomips : 4255.56
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:
[ same for the other core]
Intel OpenCL CPU needs at least SSE 4.1. The Core 2 Duo only goes up to SSSE3.
http://software.intel.com/en-us/articles/opencl-sdk-frequently-asked-questions#14
Edit: some version of the Core 2 Duo support SSE 4.1
Here is the list of supported processors for the Intel OpenCL drivers
http://software.intel.com/en-us/articles/opencl-release-notes#2
Some versions of Core 2 are not supported. " All other versions of Intel® Core™ 2 processors are not supported"
You can use, for example, CPU-Z to find out what version of SSE you CPU supports.
Install the AMD OpenCL CPU driver. It only needs SSE2. On windows I installed the Radeon GPU drivers even though I did not have a AMD GPU. It still installed the AMD OpenCL CPU drivers and it did not conflict with the Nvidia drivers. I don't know on Linux. But now I can use Intel CPU, AMD CPU, and Nvidia GPU OpenCL drivers.

openGL MSAA does not work on linux with nouveau drivers

Recently I have tried using MSAA (multisample anti-aliasing) under Linux. The result was surprising: everything worked like a charm with Nvidia proprietary drivers, however with nouveau drivers it does not work. The strange thing about this is that glxingo says that GLX_ARB_multisample is supported and I am able to get the appropriate FBConfig with GLX_SAMPLE_BUFFERS set to 1 and GLX_SAMPLES set to 4 (or 8). But when it comes to rendering, the picture is as no anti-aliasing is applied. The problem exists in both my project and freeglut, so I will provide a small glut-based program that demonstarates the problem:
/*
* Test multisampling and polygon smoothing.
*
* Brian Paul
* 4 November 2002
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
static GLfloat Zrot = 0;
static GLboolean Anim = GL_TRUE;
static GLboolean HaveMultisample = GL_TRUE;
static GLboolean DoMultisample = GL_TRUE;
static void
PrintString(const char *s)
{
while (*s) {
glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
s++;
}
}
static void
Polygon( GLint verts, GLfloat radius, GLfloat z )
{
int i;
for (i = 0; i < verts; i++) {
float a = (i * 2.0 * 3.14159) / verts;
float x = radius * cos(a);
float y = radius * sin(a);
glVertex3f(x, y, z);
}
}
static void
DrawObject( void )
{
glLineWidth(3.0);
glColor3f(1, 1, 1);
glBegin(GL_LINE_LOOP);
Polygon(12, 1.2, 0);
glEnd();
glLineWidth(1.0);
glColor3f(1, 1, 1);
glBegin(GL_LINE_LOOP);
Polygon(12, 1.1, 0);
glEnd();
glColor3f(1, 0, 0);
glBegin(GL_POLYGON);
Polygon(12, 0.4, 0.3);
glEnd();
glColor3f(0, 1, 0);
glBegin(GL_POLYGON);
Polygon(12, 0.6, 0.2);
glEnd();
glColor3f(0, 0, 1);
glBegin(GL_POLYGON);
Polygon(12, 0.8, 0.1);
glEnd();
glColor3f(1, 1, 1);
glBegin(GL_POLYGON);
Polygon(12, 1.0, 0);
glEnd();
}
static void
Display( void )
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glColor3f(1, 1, 1);
if (HaveMultisample) {
glRasterPos2f(-3.1, -1.6);
if (DoMultisample)
PrintString("MULTISAMPLE");
else
PrintString("MULTISAMPLE (off)");
}
glRasterPos2f(-0.8, -1.6);
PrintString("No antialiasing");
glRasterPos2f(1.6, -1.6);
PrintString("GL_POLYGON_SMOOTH");
/* multisample */
if (HaveMultisample) {
glEnable(GL_DEPTH_TEST);
if (DoMultisample)
glEnable(GL_MULTISAMPLE_ARB);
glPushMatrix();
glTranslatef(-2.5, 0, 0);
glPushMatrix();
glRotatef(Zrot, 0, 0, 1);
DrawObject();
glPopMatrix();
glPopMatrix();
glDisable(GL_MULTISAMPLE_ARB);
glDisable(GL_DEPTH_TEST);
}
/* non-aa */
glEnable(GL_DEPTH_TEST);
glPushMatrix();
glTranslatef(0, 0, 0);
glPushMatrix();
glRotatef(Zrot, 0, 0, 1);
DrawObject();
glPopMatrix();
glPopMatrix();
glDisable(GL_DEPTH_TEST);
/* polygon smooth */
glEnable(GL_POLYGON_SMOOTH);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
glPushMatrix();
glTranslatef(2.5, 0, 0);
glPushMatrix();
glRotatef(Zrot, 0, 0, 1);
DrawObject();
glPopMatrix();
glPopMatrix();
glDisable(GL_LINE_SMOOTH);
glDisable(GL_POLYGON_SMOOTH);
glDisable(GL_BLEND);
glutSwapBuffers();
}
static void
Reshape( int width, int height )
{
GLfloat ar = (float) width / (float) height;
glViewport( 0, 0, width, height );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho(-2.0*ar, 2.0*ar, -2.0, 2.0, -1.0, 1.0);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
}
static void
Idle( void )
{
Zrot = 0.01 * glutGet(GLUT_ELAPSED_TIME);
glutPostRedisplay();
}
static void
Key( unsigned char key, int x, int y )
{
const GLfloat step = 1.0;
(void) x;
(void) y;
switch (key) {
case 'a':
Anim = !Anim;
if (Anim)
glutIdleFunc(Idle);
else
glutIdleFunc(NULL);
break;
case 'm':
DoMultisample = !DoMultisample;
break;
case 'z':
Zrot = (int) (Zrot - step);
break;
case 'Z':
Zrot = (int) (Zrot + step);
break;
case 27:
exit(0);
break;
}
glutPostRedisplay();
}
static void
Init( void )
{
/* GLUT imposes the four samples/pixel requirement */
int s;
glGetIntegerv(GL_SAMPLES_ARB, &s);
if (!glutExtensionSupported("GL_ARB_multisample") || s < 1) {
printf("Warning: multisample antialiasing not supported.\n");
HaveMultisample = GL_FALSE;
}
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
printf("GL_SAMPLES_ARB = %d\n", s);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_ONE);
glGetIntegerv(GL_MULTISAMPLE_ARB, &s);
printf("GL_MULTISAMPLE_ARB = %d\n", s);
}
int
main( int argc, char *argv[] )
{
glutInit( &argc, argv );
glutInitWindowPosition( 0, 0 );
glutInitWindowSize( 600, 300 );
glutInitDisplayMode( GLUT_RGB | GLUT_ALPHA | GLUT_DOUBLE |
GLUT_DEPTH | GLUT_MULTISAMPLE );
glutCreateWindow(argv[0]);
glutReshapeFunc( Reshape );
glutKeyboardFunc( Key );
glutDisplayFunc( Display );
if (Anim)
glutIdleFunc( Idle );
Init();
glutMainLoop();
return 0;
}
Here is glxinfo output (excluding the visuals info):
name of display: :0.0
display: :0 screen: 0
direct rendering: Yes
server glx vendor string: SGI
server glx version string: 1.4
server glx extensions:
GLX_ARB_multisample, GLX_EXT_import_context, GLX_EXT_texture_from_pixmap,
GLX_EXT_visual_info, GLX_EXT_visual_rating, GLX_MESA_copy_sub_buffer,
GLX_OML_swap_method, GLX_SGI_swap_control, GLX_SGIS_multisample,
GLX_SGIX_fbconfig, GLX_SGIX_pbuffer, GLX_SGIX_visual_select_group,
GLX_INTEL_swap_event
client glx vendor string: Mesa Project and SGI
client glx version string: 1.4
client glx extensions:
GLX_ARB_create_context, GLX_ARB_create_context_profile,
GLX_ARB_get_proc_address, GLX_ARB_multisample, GLX_EXT_import_context,
GLX_EXT_visual_info, GLX_EXT_visual_rating, GLX_EXT_framebuffer_sRGB,
GLX_EXT_create_context_es2_profile, GLX_MESA_copy_sub_buffer,
GLX_MESA_multithread_makecurrent, GLX_MESA_swap_control,
GLX_OML_swap_method, GLX_OML_sync_control, GLX_SGI_make_current_read,
GLX_SGI_swap_control, GLX_SGI_video_sync, GLX_SGIS_multisample,
GLX_SGIX_fbconfig, GLX_SGIX_pbuffer, GLX_SGIX_visual_select_group,
GLX_EXT_texture_from_pixmap, GLX_INTEL_swap_event
GLX version: 1.4
GLX extensions:
GLX_ARB_get_proc_address, GLX_ARB_multisample, GLX_EXT_import_context,
GLX_EXT_visual_info, GLX_EXT_visual_rating, GLX_MESA_copy_sub_buffer,
GLX_MESA_multithread_makecurrent, GLX_MESA_swap_control,
GLX_OML_swap_method, GLX_OML_sync_control, GLX_SGI_make_current_read,
GLX_SGI_swap_control, GLX_SGI_video_sync, GLX_SGIS_multisample,
GLX_SGIX_fbconfig, GLX_SGIX_pbuffer, GLX_SGIX_visual_select_group,
GLX_EXT_texture_from_pixmap
OpenGL vendor string: nouveau
OpenGL renderer string: Gallium 0.4 on NVC1
OpenGL version string: 2.1 Mesa 8.0.4
OpenGL shading language version string: 1.30
OpenGL extensions:
GL_ARB_multisample, GL_EXT_abgr, GL_EXT_bgra, GL_EXT_blend_color,
GL_EXT_blend_minmax, GL_EXT_blend_subtract, GL_EXT_copy_texture,
GL_EXT_polygon_offset, GL_EXT_subtexture, GL_EXT_texture_object,
GL_EXT_vertex_array, GL_EXT_compiled_vertex_array, GL_EXT_texture,
GL_EXT_texture3D, GL_IBM_rasterpos_clip, GL_ARB_point_parameters,
GL_EXT_draw_range_elements, GL_EXT_packed_pixels, GL_EXT_point_parameters,
GL_EXT_rescale_normal, GL_EXT_separate_specular_color,
GL_EXT_texture_edge_clamp, GL_SGIS_generate_mipmap,
GL_SGIS_texture_border_clamp, GL_SGIS_texture_edge_clamp,
GL_SGIS_texture_lod, GL_ARB_framebuffer_sRGB, GL_ARB_multitexture,
GL_EXT_framebuffer_sRGB, GL_IBM_multimode_draw_arrays,
GL_IBM_texture_mirrored_repeat, GL_ARB_texture_cube_map,
GL_ARB_texture_env_add, GL_ARB_transpose_matrix,
GL_EXT_blend_func_separate, GL_EXT_fog_coord, GL_EXT_multi_draw_arrays,
GL_EXT_secondary_color, GL_EXT_texture_env_add,
GL_EXT_texture_filter_anisotropic, GL_EXT_texture_lod_bias,
GL_INGR_blend_func_separate, GL_NV_blend_square, GL_NV_light_max_exponent,
GL_NV_texgen_reflection, GL_NV_texture_env_combine4,
GL_SUN_multi_draw_arrays, GL_ARB_texture_border_clamp,
GL_ARB_texture_compression, GL_EXT_framebuffer_object,
GL_EXT_texture_env_combine, GL_EXT_texture_env_dot3, GL_MESA_window_pos,
GL_NV_packed_depth_stencil, GL_NV_texture_rectangle, GL_ARB_depth_texture,
GL_ARB_occlusion_query, GL_ARB_shadow, GL_ARB_texture_env_combine,
GL_ARB_texture_env_crossbar, GL_ARB_texture_env_dot3,
GL_ARB_texture_mirrored_repeat, GL_ARB_window_pos,
GL_EXT_stencil_two_side, GL_EXT_texture_cube_map, GL_NV_depth_clamp,
GL_NV_fog_distance, GL_APPLE_packed_pixels, GL_APPLE_vertex_array_object,
GL_ARB_draw_buffers, GL_ARB_fragment_program, GL_ARB_fragment_shader,
GL_ARB_shader_objects, GL_ARB_vertex_program, GL_ARB_vertex_shader,
GL_ATI_draw_buffers, GL_ATI_texture_env_combine3, GL_EXT_shadow_funcs,
GL_EXT_stencil_wrap, GL_MESA_pack_invert, GL_NV_primitive_restart,
GL_ARB_depth_clamp, GL_ARB_fragment_program_shadow,
GL_ARB_half_float_pixel, GL_ARB_occlusion_query2, GL_ARB_point_sprite,
GL_ARB_shading_language_100, GL_ARB_sync, GL_ARB_texture_non_power_of_two,
GL_ARB_vertex_buffer_object, GL_ATI_blend_equation_separate,
GL_EXT_blend_equation_separate, GL_OES_read_format,
GL_ARB_color_buffer_float, GL_ARB_pixel_buffer_object,
GL_ARB_texture_compression_rgtc, GL_ARB_texture_rectangle,
GL_ATI_texture_compression_3dc, GL_EXT_packed_float,
GL_EXT_pixel_buffer_object, GL_EXT_texture_compression_rgtc,
GL_EXT_texture_mirror_clamp, GL_EXT_texture_rectangle,
GL_EXT_texture_sRGB, GL_EXT_texture_shared_exponent,
GL_ARB_framebuffer_object, GL_EXT_framebuffer_blit,
GL_EXT_framebuffer_multisample, GL_EXT_packed_depth_stencil,
GL_ARB_vertex_array_object, GL_ATI_separate_stencil,
GL_ATI_texture_mirror_once, GL_EXT_draw_buffers2, GL_EXT_draw_instanced,
GL_EXT_gpu_program_parameters, GL_EXT_texture_array,
GL_EXT_texture_compression_latc, GL_EXT_texture_integer,
GL_EXT_texture_sRGB_decode, GL_EXT_timer_query, GL_OES_EGL_image,
GL_MESA_texture_array, GL_ARB_copy_buffer, GL_ARB_depth_buffer_float,
GL_ARB_draw_instanced, GL_ARB_half_float_vertex, GL_ARB_instanced_arrays,
GL_ARB_map_buffer_range, GL_ARB_texture_rg, GL_ARB_texture_swizzle,
GL_ARB_vertex_array_bgra, GL_EXT_separate_shader_objects,
GL_EXT_texture_swizzle, GL_EXT_vertex_array_bgra,
GL_NV_conditional_render, GL_AMD_conservative_depth,
GL_AMD_draw_buffers_blend, GL_ARB_ES2_compatibility,
GL_ARB_draw_buffers_blend, GL_ARB_draw_elements_base_vertex,
GL_ARB_explicit_attrib_location, GL_ARB_fragment_coord_conventions,
GL_ARB_provoking_vertex, GL_ARB_sampler_objects, GL_ARB_seamless_cube_map,
GL_ARB_shader_texture_lod, GL_EXT_provoking_vertex, GL_EXT_texture_snorm,
GL_MESA_texture_signed_rgba, GL_NV_texture_barrier, GL_ARB_robustness,
GL_ARB_transform_feedback2, GL_ARB_conservative_depth,
GL_ARB_texture_storage, GL_EXT_transform_feedback
glewIsSupported says the extension is available, glGetIntegerv says the number of samples is 4, as specified when getting the FBConfig.
I have no idea of what is going on.
Edit: Here is the output of glXQueryExtensionsString:
GLX_ARB_get_proc_address GLX_ARB_multisample GLX_EXT_import_context GLX_EXT_visual_info GLX_EXT_visual_rating GLX_MESA_copy_sub_buffer GLX_MESA_multithread_makecurrent GLX_MESA_swap_control GLX_OML_swap_method GLX_OML_sync_control GLX_SGI_make_current_read GLX_SGI_swap_control GLX_SGI_video_sync GLX_SGIS_multisample GLX_SGIX_fbconfig GLX_SGIX_pbuffer GLX_SGIX_visual_select_group GLX_EXT_texture_from_pixmap
FORGET ABOUT MSAA. On nouveau UNLESS you have very fresh MESA + kernel + X.org.
MSAA is requirement for OpenGL 3.0 and up. So it was not high on priority list, up until recently. You need Mesa 9.0 for that.
(If you want tips on what to do to get those needed software, pls post your hardware, and software - distro, kernel, mesa, xorg - versions).

Any GLES examples, in C++, on x86 Linux?

I'm looking for a good source of GLES2 samples for C++ (or C) on x86 Linux with Xorg.
The samples I can find are all in Objective C for iOS, or Java for Android, or JavaScript for WebGL.
The Kronos web site has a "tutorials" section that contains two lines saying "our tutorials index will go here." Given that GLES2 is 5 years old, I don't have much hope on a sudden surge of content there.
I already know OpenGL pretty well. I'd just like some convenient source for copy-and-paste context set-up code, really. Where can I find something like that?
Mesa demos!
http://cgit.freedesktop.org/mesa/demos
http://cgit.freedesktop.org/mesa/demos/tree/src/egl/opengles2
http://cgit.freedesktop.org/mesa/demos/tree/src/egl/opengles2/es2tri.c
GLFW, Mesa, Ubuntu 16.04 AMD64
I'm not sure if GLUT supports GLES, but GLFW does, greatly simplifying window management.
sudo apt-get install libglfw3-dev libgles2-mesa-dev
gcc glfw_triangle.c -lGLESv2 -lglfw
Output:
Source:
#include <stdio.h>
#include <stdlib.h>
#define GLFW_INCLUDE_ES2
#include <GLFW/glfw3.h>
static const GLuint WIDTH = 800;
static const GLuint HEIGHT = 600;
static const GLchar* vertex_shader_source =
"#version 100\n"
"attribute vec3 position;\n"
"void main() {\n"
" gl_Position = vec4(position, 1.0);\n"
"}\n";
static const GLchar* fragment_shader_source =
"#version 100\n"
"void main() {\n"
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n";
static const GLfloat vertices[] = {
0.0f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
};
GLint common_get_shader_program(const char *vertex_shader_source, const char *fragment_shader_source) {
enum Consts {INFOLOG_LEN = 512};
GLchar infoLog[INFOLOG_LEN];
GLint fragment_shader;
GLint shader_program;
GLint success;
GLint vertex_shader;
/* Vertex shader */
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL);
glCompileShader(vertex_shader);
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertex_shader, INFOLOG_LEN, NULL, infoLog);
printf("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n%s\n", infoLog);
}
/* Fragment shader */
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL);
glCompileShader(fragment_shader);
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragment_shader, INFOLOG_LEN, NULL, infoLog);
printf("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n%s\n", infoLog);
}
/* Link shaders */
shader_program = glCreateProgram();
glAttachShader(shader_program, vertex_shader);
glAttachShader(shader_program, fragment_shader);
glLinkProgram(shader_program);
glGetProgramiv(shader_program, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shader_program, INFOLOG_LEN, NULL, infoLog);
printf("ERROR::SHADER::PROGRAM::LINKING_FAILED\n%s\n", infoLog);
}
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
return shader_program;
}
int main(void) {
GLuint shader_program, vbo;
GLint pos;
GLFWwindow* window;
glfwInit();
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
window = glfwCreateWindow(WIDTH, HEIGHT, __FILE__, NULL, NULL);
glfwMakeContextCurrent(window);
printf("GL_VERSION : %s\n", glGetString(GL_VERSION) );
printf("GL_RENDERER : %s\n", glGetString(GL_RENDERER) );
shader_program = common_get_shader_program(vertex_shader_source, fragment_shader_source);
pos = glGetAttribLocation(shader_program, "position");
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glViewport(0, 0, WIDTH, HEIGHT);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(pos, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
glEnableVertexAttribArray(pos);
glBindBuffer(GL_ARRAY_BUFFER, 0);
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shader_program);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
}
glDeleteBuffers(1, &vbo);
glfwTerminate();
return EXIT_SUCCESS;
}
The key line lines of code are:
#define GLFW_INCLUDE_ES2
#include <GLFW/glfw3.h>
GLFW_INCLUDE_ES2 is documented at: http://www.glfw.org/docs/latest/build_guide.html#build_macros and a quick look at the source shows that it forwards to GLES:
#elif defined(GLFW_INCLUDE_ES2)
#include <GLES2/gl2.h>
#if defined(GLFW_INCLUDE_GLEXT)
#include <GLES2/gl2ext.h>
#endif
This source seems to be is in the common subset of GLES and OpenGL (like much of GLES), and also compiles with -lGL if we remove the #define GLFW_INCLUDE_ES2.
If we add things which are not in GLES like immediate rendering glBegin, link fails as expected.
See also: How to develop OpenGL ES (GLES) 2.0 applications on Linux?
Credits: genpfult made the code much more correct.
ARM Mali OpenGL ES SDK
download from: http://malideveloper.arm.com/resources/sdks/opengl-es-sdk-for-linux/
open the documentation HTML on a browser
follow the "Quick Start Guide", it's simple
Contains several interesting open source examples + windowing system boilerplate (X11 + EGL).
The build system supports easy cross compilation for ARM / Mali SoCs, but I haven't tested that yet.
The key component included seems to be the "OpenGL ES Emulator" http://malideveloper.arm.com/resources/tools/opengl-es-emulator/ which "maps OpenGL ES 3.2 API calls to the OpenGL API". But that does not ship with source, only precompiled.
Uses a custom enterprisey EULA that appears to be permissive, but yeah, ask your lawyer.
Tested on SDK v2.4.4.

How to develop OpenGL ES (GLES) 2.0 applications on Linux?

I would like to develop OpenGL ES 2.0 apps on my Ubuntu machine. I could not find any libraries/emulators that support GLES 2.0 yet. Any suggestions?
GLFW, Mesa, Ubuntu 16.04 AMD64
This was not easy to setup on Ubuntu 14.04, but now it just works.
sudo apt-get install libglfw3-dev libgles2-mesa-dev
gcc glfw_triangle.c -lGLESv2 -lglfw
Output:
glfw_triangle.c
#include <stdio.h>
#include <stdlib.h>
#define GLFW_INCLUDE_ES2
#include <GLFW/glfw3.h>
static const GLuint WIDTH = 800;
static const GLuint HEIGHT = 600;
static const GLchar* vertex_shader_source =
"#version 100\n"
"attribute vec3 position;\n"
"void main() {\n"
" gl_Position = vec4(position, 1.0);\n"
"}\n";
static const GLchar* fragment_shader_source =
"#version 100\n"
"void main() {\n"
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n";
static const GLfloat vertices[] = {
0.0f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
};
GLint common_get_shader_program(const char *vertex_shader_source, const char *fragment_shader_source) {
enum Consts {INFOLOG_LEN = 512};
GLchar infoLog[INFOLOG_LEN];
GLint fragment_shader;
GLint shader_program;
GLint success;
GLint vertex_shader;
/* Vertex shader */
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL);
glCompileShader(vertex_shader);
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertex_shader, INFOLOG_LEN, NULL, infoLog);
printf("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n%s\n", infoLog);
}
/* Fragment shader */
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL);
glCompileShader(fragment_shader);
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragment_shader, INFOLOG_LEN, NULL, infoLog);
printf("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n%s\n", infoLog);
}
/* Link shaders */
shader_program = glCreateProgram();
glAttachShader(shader_program, vertex_shader);
glAttachShader(shader_program, fragment_shader);
glLinkProgram(shader_program);
glGetProgramiv(shader_program, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shader_program, INFOLOG_LEN, NULL, infoLog);
printf("ERROR::SHADER::PROGRAM::LINKING_FAILED\n%s\n", infoLog);
}
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
return shader_program;
}
int main(void) {
GLuint shader_program, vbo;
GLint pos;
GLFWwindow* window;
glfwInit();
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
window = glfwCreateWindow(WIDTH, HEIGHT, __FILE__, NULL, NULL);
glfwMakeContextCurrent(window);
printf("GL_VERSION : %s\n", glGetString(GL_VERSION) );
printf("GL_RENDERER : %s\n", glGetString(GL_RENDERER) );
shader_program = common_get_shader_program(vertex_shader_source, fragment_shader_source);
pos = glGetAttribLocation(shader_program, "position");
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glViewport(0, 0, WIDTH, HEIGHT);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(pos, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
glEnableVertexAttribArray(pos);
glBindBuffer(GL_ARRAY_BUFFER, 0);
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shader_program);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
}
glDeleteBuffers(1, &vbo);
glfwTerminate();
return EXIT_SUCCESS;
}
The key line lines of code are:
#define GLFW_INCLUDE_ES2
#include <GLFW/glfw3.h>
GLFW_INCLUDE_ES2 is documented at: http://www.glfw.org/docs/latest/build_guide.html#build_macros and a quick look at the source shows that it forwards to GLES:
#elif defined(GLFW_INCLUDE_ES2)
#include <GLES2/gl2.h>
#if defined(GLFW_INCLUDE_GLEXT)
#include <GLES2/gl2ext.h>
#endif
This source seems to be written in the common subset of GLES and OpenGL (like much of GLES), and also compiles with -lGL if we remove the #define GLFW_INCLUDE_ES2.
If we add things which are not in GLES like immediate rendering glBegin, link fails as expected.
See also: https://askubuntu.com/questions/244133/how-do-i-get-egl-and-opengles-libraries-for-ubuntu-running-on-virtualbox
Credits: genpfult made the code much more correct.
ARM Mali OpenGL ES SDK
download from: http://malideveloper.arm.com/resources/sdks/opengl-es-sdk-for-linux/
open the documentation HTML on a browser
follow the "Quick Start Guide", it's simple
Contains several interesting open source examples + windowing system boilerplate (X11 + EGL).
The build system supports easy cross compilation for ARM / Mali SoCs, but I haven't tested that yet.
The key component included seems to be the "OpenGL ES Emulator" http://malideveloper.arm.com/resources/tools/opengl-es-emulator/ which "maps OpenGL ES 3.2 API calls to the OpenGL API". But that does not ship with source, only precompiled.
Uses a custom enterprisey EULA that appears to be permissive, but yeah, ask your lawyer.
Tested on SDK v2.4.4.
Mesa supports it. If you want to restrict yourself to OpenGL ES only then you'll need to build it into a separate directory and then add the appropriate include and library directories.
Update:
You can (still) use PowerVR SDK and now it supports Vulkan as well. Updated links:
PowerVR SDK page: https://www.imgtec.com/developers/powervr-sdk-tools/powervr-sdk/
Installers download page: https://www.imgtec.com/developers/powervr-sdk-tools/installers/
Github repo: https://github.com/powervr-graphics/Native_SDK
At the time of my original answer, PowerVR SDK was the most complete solution (Mesa gained full OpenGL ES 2.0 support with its 3.1 release according to its Wikipedia page).
Now, Mesa and Mali SDK can also be a choice. For detailed info on those, please refer to this detailed answer by Ciro Santilli 冠状病毒审查六四事件法轮功
Original Answer:
You can use POWERVR SDK to emulate Opengl es on your PC. You can download the SDK here. The archive provides the necessary steps to install the emulation libraries as a documentation file and includes tutorials and demo applications with source codes.
Develop to the OpenGL 2.0 standard, and don't use immediate mode or fixed function mode. Essentially your program will be ES 2.0 compliant.
you can generate a header that has only those functions that you really need. And with glfw you can create an opengl es context. So you can't accidently use functions that you do not want to use, because they won't be defined in this way. I found this that might help you here.
gl load from the unofficial opengl sdk

Resources