int main() { int width = 640; int height = 480; UserData userdata; userdata.running = true; GLWTConfig glwt_config; glwt_config.red_bits = 8; glwt_config.green_bits = 8; glwt_config.blue_bits = 8; glwt_config.alpha_bits = 8; glwt_config.depth_bits = 24; glwt_config.stencil_bits = 8; glwt_config.samples = 0; glwt_config.sample_buffers = 0; glwt_config.api = GLWT_API_OPENGL | GLWT_PROFILE_CORE; glwt_config.api_version_major = 3; glwt_config.api_version_minor = 3; GLWTAppCallbacks app_callbacks; app_callbacks.error_callback = error_callback; app_callbacks.userdata = &userdata; if(glwtInit(&glwt_config, &app_callbacks) != 0) { std::cerr << "failed to init GLWT" << std::endl; return 1; } GLWTWindowCallbacks win_callbacks; win_callbacks.close_callback = close_callback; win_callbacks.expose_callback = 0; win_callbacks.resize_callback = 0; win_callbacks.show_callback = 0; win_callbacks.focus_callback = 0; win_callbacks.key_callback = key_callback, win_callbacks.motion_callback = 0; win_callbacks.button_callback = 0; win_callbacks.mouseover_callback = 0; win_callbacks.userdata = &userdata; // create a window GLWTWindow *window = glwtWindowCreate("", width, height, &win_callbacks, 0); if(window == 0) { std::cerr << "failed to open window" << std::endl; glwtQuit(); return 1; } if (glxwInit()) { std::cerr << "failed to init GLXW" << std::endl; glwtWindowDestroy(window); glwtQuit(); return 1; } glwtWindowShow(window, 1); glwtMakeCurrent(window); glwtSwapInterval(window, 1); // creation and initialization of stuff goes here while(userdata.running) { // update events glwtEventHandle(0); // drawing etc goes here // ... // check for errors GLenum error = glGetError(); if(error != GL_NO_ERROR) { userdata.running = false; } // finally swap buffers glwtSwapBuffers(window); } glwtWindowDestroy(window); glwtQuit(); return 0; }
int main() { int width = 640; int height = 480; UserData userdata; userdata.running = true; GLWTConfig glwt_config; glwt_config.red_bits = 8; glwt_config.green_bits = 8; glwt_config.blue_bits = 8; glwt_config.alpha_bits = 8; glwt_config.depth_bits = 24; glwt_config.stencil_bits = 8; glwt_config.samples = 0; glwt_config.sample_buffers = 0; glwt_config.api = GLWT_API_OPENGL | GLWT_PROFILE_CORE; glwt_config.api_version_major = 3; glwt_config.api_version_minor = 3; GLWTAppCallbacks app_callbacks; app_callbacks.error_callback = error_callback; app_callbacks.userdata = &userdata; if(glwtInit(&glwt_config, &app_callbacks) != 0) { std::cerr << "failed to init GLWT" << std::endl; return 1; } GLWTWindowCallbacks win_callbacks; win_callbacks.close_callback = close_callback; win_callbacks.expose_callback = 0; win_callbacks.resize_callback = 0; win_callbacks.show_callback = 0; win_callbacks.focus_callback = 0; win_callbacks.key_callback = key_callback, win_callbacks.motion_callback = 0; win_callbacks.button_callback = 0; win_callbacks.mouseover_callback = 0; win_callbacks.userdata = &userdata; // create a window GLWTWindow *window = glwtWindowCreate("", width, height, &win_callbacks, 0); if(window == 0) { std::cerr << "failed to open window" << std::endl; glwtQuit(); return 1; } if (glxwInit()) { std::cerr << "failed to init GLXW" << std::endl; glwtWindowDestroy(window); glwtQuit(); return 1; } glwtWindowShow(window, 1); glwtMakeCurrent(window); glwtSwapInterval(window, 1); // shader source code // the vertex shader simply passes through data std::string vertex_source = "#version 330\n" "layout(location = 0) in vec4 vposition;\n" "void main() {\n" " gl_Position = vposition;\n" "}\n"; // the geometry shader creates the billboard quads std::string geometry_source = "#version 330\n" "uniform mat4 View;\n" "uniform mat4 Projection;\n" "layout (points) in;\n" "layout (triangle_strip, max_vertices = 4) out;\n" "out vec2 txcoord;\n" "void main() {\n" " vec4 pos = View*gl_in[0].gl_Position;\n" " txcoord = vec2(-1,-1);\n" " gl_Position = Projection*(pos+vec4(txcoord,0,0));\n" " EmitVertex();\n" " txcoord = vec2( 1,-1);\n" " gl_Position = Projection*(pos+vec4(txcoord,0,0));\n" " EmitVertex();\n" " txcoord = vec2(-1, 1);\n" " gl_Position = Projection*(pos+vec4(txcoord,0,0));\n" " EmitVertex();\n" " txcoord = vec2( 1, 1);\n" " gl_Position = Projection*(pos+vec4(txcoord,0,0));\n" " EmitVertex();\n" "}\n"; // the fragment shader creates a bell like radial color distribution std::string fragment_source = "#version 330\n" "in vec2 txcoord;\n" "layout(location = 0) out vec4 FragColor;\n" "void main() {\n" " float s = 0.2*(1/(1+15.*dot(txcoord, txcoord))-1/16.);\n" " FragColor = s*vec4(1,0.9,0.6,1);\n" "}\n"; // program and shader handles GLuint shader_program, vertex_shader, geometry_shader, fragment_shader; // we need these to properly pass the strings const char *source; int length; // create and compiler vertex shader vertex_shader = glCreateShader(GL_VERTEX_SHADER); source = vertex_source.c_str(); length = vertex_source.size(); glShaderSource(vertex_shader, 1, &source, &length); glCompileShader(vertex_shader); if(!check_shader_compile_status(vertex_shader)) { return 1; } // create and compiler geometry shader geometry_shader = glCreateShader(GL_GEOMETRY_SHADER); source = geometry_source.c_str(); length = geometry_source.size(); glShaderSource(geometry_shader, 1, &source, &length); glCompileShader(geometry_shader); if(!check_shader_compile_status(geometry_shader)) { return 1; } // create and compiler fragment shader fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); source = fragment_source.c_str(); length = fragment_source.size(); glShaderSource(fragment_shader, 1, &source, &length); glCompileShader(fragment_shader); if(!check_shader_compile_status(fragment_shader)) { return 1; } // create program shader_program = glCreateProgram(); // attach shaders glAttachShader(shader_program, vertex_shader); glAttachShader(shader_program, geometry_shader); glAttachShader(shader_program, fragment_shader); // link the program and check for errors glLinkProgram(shader_program); check_program_link_status(shader_program); // obtain location of projection uniform GLint View_location = glGetUniformLocation(shader_program, "View"); GLint Projection_location = glGetUniformLocation(shader_program, "Projection"); // vao and vbo handle GLuint vao, vbo; // generate and bind the vao glGenVertexArrays(1, &vao); glBindVertexArray(vao); // generate and bind the vertex buffer object glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); const int particles = 128*1024; // create a galaxylike distribution of points std::vector<GLfloat> vertexData(particles*3); for(int i = 0;i<particles;++i) { int arm = 3*(std::rand()/float(RAND_MAX)); float alpha = 1/(0.1f+std::pow(std::rand()/float(RAND_MAX),0.7f))-1/1.1f; float r = 4.0f*alpha; alpha += arm*2.0f*3.1416f/3.0f; vertexData[3*i+0] = r*std::sin(alpha); vertexData[3*i+1] = 0; vertexData[3*i+2] = r*std::cos(alpha); vertexData[3*i+0] += (4.0f-0.2*alpha)*(2-(std::rand()/float(RAND_MAX)+std::rand()/float(RAND_MAX)+ std::rand()/float(RAND_MAX)+std::rand()/float(RAND_MAX))); vertexData[3*i+1] += (2.0f-0.1*alpha)*(2-(std::rand()/float(RAND_MAX)+std::rand()/float(RAND_MAX)+ std::rand()/float(RAND_MAX)+std::rand()/float(RAND_MAX))); vertexData[3*i+2] += (4.0f-0.2*alpha)*(2-(std::rand()/float(RAND_MAX)+std::rand()/float(RAND_MAX)+ std::rand()/float(RAND_MAX)+std::rand()/float(RAND_MAX))); } // fill with data glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*vertexData.size(), &vertexData[0], GL_STATIC_DRAW); // set up generic attrib pointers glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), (char*)0 + 0*sizeof(GLfloat)); // "unbind" vao glBindVertexArray(0); // we are blending so no depth testing glDisable(GL_DEPTH_TEST); // enable blending glEnable(GL_BLEND); // and set the blend function to result = 1*source + 1*destination glBlendFunc(GL_ONE, GL_ONE); while(userdata.running) { // get the time in seconds float t = glwtGetNanoTime()*1.e-9f; // update events glwtEventHandle(0); // clear first glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // use the shader program glUseProgram(shader_program); // calculate ViewProjection matrix glm::mat4 Projection = glm::perspective(90.0f, 4.0f / 3.0f, 0.1f, 100.f); // translate the world/view position glm::mat4 View = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -50.0f)); // make the camera rotate around the origin View = glm::rotate(View, 30.0f*std::sin(0.1f*t), glm::vec3(1.0f, 0.0f, 0.0f)); View = glm::rotate(View, -22.5f*t, glm::vec3(0.0f, 1.0f, 0.0f)); // set the uniform glUniformMatrix4fv(View_location, 1, GL_FALSE, glm::value_ptr(View)); glUniformMatrix4fv(Projection_location, 1, GL_FALSE, glm::value_ptr(Projection)); // bind the vao glBindVertexArray(vao); // draw glDrawArrays(GL_POINTS, 0, particles); // check for errors GLenum error = glGetError(); if(error != GL_NO_ERROR) { userdata.running = false; } // finally swap buffers glwtSwapBuffers(window); } // delete the created objects glDeleteVertexArrays(1, &vao); glDeleteBuffers(1, &vbo); glDetachShader(shader_program, vertex_shader); glDetachShader(shader_program, geometry_shader); glDetachShader(shader_program, fragment_shader); glDeleteShader(vertex_shader); glDeleteShader(geometry_shader); glDeleteShader(fragment_shader); glDeleteProgram(shader_program); glwtWindowDestroy(window); glwtQuit(); return 0; }
GLWTWindow *glwtWindowCreate( const char *title, int width, int height, GLWTWindow *share, void (*win_callback)(GLWTWindow *window, const GLWTWindowEvent *event, void *userdata), void *userdata) { GLWTWindow *win = calloc(1, sizeof(GLWTWindow)); if(!win) return 0; win->win_callback = win_callback; win->userdata = userdata; XSetWindowAttributes attrib; attrib.colormap = glwt.x11.colormap; attrib.event_mask = 0 | StructureNotifyMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | EnterWindowMask | LeaveWindowMask | FocusChangeMask | ExposureMask; unsigned long attrib_mask = CWColormap | CWEventMask; win->x11.window = XCreateWindow( glwt.x11.display, RootWindow(glwt.x11.display, glwt.x11.screen_num), 0, 0, width, height, 0, glwt.x11.depth, InputOutput, glwt.x11.visual, attrib_mask, &attrib); Atom protocols[] = { glwt.x11.atoms.WM_DELETE_WINDOW, glwt.x11.atoms._NET_WM_PING, }; int num_protocols = sizeof(protocols)/sizeof(*protocols); if(XSetWMProtocols(glwt.x11.display, win->x11.window, protocols, num_protocols) == 0) { glwtErrorPrintf("XSetWMProtocols failed"); goto error; } #ifdef GLWT_USE_EGL if(glwtWindowCreateEGL(win, share, win->x11.window) != 0) #else if(glwtWindowCreateGLX(win, share) != 0) #endif goto error; if(XSaveContext(glwt.x11.display, win->x11.window, glwt.x11.xcontext, (XPointer)win) != 0) { glwtErrorPrintf("XSaveContext failed"); goto error; } glwtWindowSetTitle(win, title); return win; error: glwtWindowDestroy(win); return 0; }
int main() { int width = 640; int height = 480; UserData userdata; userdata.running = true; GLWTConfig glwt_config; glwt_config.red_bits = 8; glwt_config.green_bits = 8; glwt_config.blue_bits = 8; glwt_config.alpha_bits = 8; glwt_config.depth_bits = 24; glwt_config.stencil_bits = 8; glwt_config.samples = 0; glwt_config.sample_buffers = 0; glwt_config.api = GLWT_API_OPENGL | GLWT_PROFILE_CORE; glwt_config.api_version_major = 3; glwt_config.api_version_minor = 3; GLWTAppCallbacks app_callbacks; app_callbacks.error_callback = error_callback; app_callbacks.userdata = &userdata; if(glwtInit(&glwt_config, &app_callbacks) != 0) { std::cerr << "failed to init GLWT" << std::endl; return 1; } GLWTWindowCallbacks win_callbacks; win_callbacks.close_callback = close_callback; win_callbacks.expose_callback = 0; win_callbacks.resize_callback = 0; win_callbacks.show_callback = 0; win_callbacks.focus_callback = 0; win_callbacks.key_callback = key_callback, win_callbacks.motion_callback = 0; win_callbacks.button_callback = 0; win_callbacks.mouseover_callback = 0; win_callbacks.userdata = &userdata; // create a window GLWTWindow *window = glwtWindowCreate("", width, height, &win_callbacks, 0); if(window == 0) { std::cerr << "failed to open window" << std::endl; glwtQuit(); return 1; } if (glxwInit()) { std::cerr << "failed to init GLXW" << std::endl; glwtWindowDestroy(window); glwtQuit(); return 1; } glwtWindowShow(window, 1); glwtMakeCurrent(window); glwtSwapInterval(window, 1); // shader source code std::string vertex_source = "#version 330\n" "uniform mat4 ViewProjection;\n" // the projection matrix uniform "layout(location = 0) in vec4 vposition;\n" "layout(location = 1) in vec4 vcolor;\n" "layout(location = 2) in vec3 voffset;\n" // the per instance offset "out vec4 fcolor;\n" "void main() {\n" " fcolor = vcolor;\n" " gl_Position = ViewProjection*(vposition + vec4(voffset, 0));\n" "}\n"; std::string fragment_source = "#version 330\n" "in vec4 fcolor;\n" "layout(location = 0) out vec4 FragColor;\n" "void main() {\n" " FragColor = fcolor;\n" "}\n"; // program and shader handles GLuint shader_program, vertex_shader, fragment_shader; // we need these to properly pass the strings const char *source; int length; // create and compiler vertex shader vertex_shader = glCreateShader(GL_VERTEX_SHADER); source = vertex_source.c_str(); length = vertex_source.size(); glShaderSource(vertex_shader, 1, &source, &length); glCompileShader(vertex_shader); if(!check_shader_compile_status(vertex_shader)) { return 1; } // create and compiler fragment shader fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); source = fragment_source.c_str(); length = fragment_source.size(); glShaderSource(fragment_shader, 1, &source, &length); glCompileShader(fragment_shader); if(!check_shader_compile_status(fragment_shader)) { return 1; } // create program shader_program = glCreateProgram(); // attach shaders glAttachShader(shader_program, vertex_shader); glAttachShader(shader_program, fragment_shader); // link the program and check for errors glLinkProgram(shader_program); check_program_link_status(shader_program); // obtain location of projection uniform GLint ViewProjection_location = glGetUniformLocation(shader_program, "ViewProjection"); // vao and vbo handles GLuint vao, vbo, tbo, ibo; // generate and bind the vao glGenVertexArrays(1, &vao); glBindVertexArray(vao); // generate and bind the vertex buffer object glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); // data for a cube GLfloat vertexData[] = { // X Y Z R G B // face 0: 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // vertex 0 -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // vertex 1 1.0f,-1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // vertex 2 -1.0f,-1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // vertex 3 // face 1: 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, // vertex 0 1.0f,-1.0f, 1.0f, 0.0f, 1.0f, 0.0f, // vertex 1 1.0f, 1.0f,-1.0f, 0.0f, 1.0f, 0.0f, // vertex 2 1.0f,-1.0f,-1.0f, 0.0f, 1.0f, 0.0f, // vertex 3 // face 2: 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, // vertex 0 1.0f, 1.0f,-1.0f, 0.0f, 0.0f, 1.0f, // vertex 1 -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, // vertex 2 -1.0f, 1.0f,-1.0f, 0.0f, 0.0f, 1.0f, // vertex 3 // face 3: 1.0f, 1.0f,-1.0f, 1.0f, 1.0f, 0.0f, // vertex 0 1.0f,-1.0f,-1.0f, 1.0f, 1.0f, 0.0f, // vertex 1 -1.0f, 1.0f,-1.0f, 1.0f, 1.0f, 0.0f, // vertex 2 -1.0f,-1.0f,-1.0f, 1.0f, 1.0f, 0.0f, // vertex 3 // face 4: -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // vertex 0 -1.0f, 1.0f,-1.0f, 0.0f, 1.0f, 1.0f, // vertex 1 -1.0f,-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // vertex 2 -1.0f,-1.0f,-1.0f, 0.0f, 1.0f, 1.0f, // vertex 3 // face 5: 1.0f,-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, // vertex 0 -1.0f,-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, // vertex 1 1.0f,-1.0f,-1.0f, 1.0f, 0.0f, 1.0f, // vertex 2 -1.0f,-1.0f,-1.0f, 1.0f, 0.0f, 1.0f, // vertex 3 }; // 6 faces with 4 vertices with 6 components (floats) // fill with data glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*6*4*6, vertexData, GL_STATIC_DRAW); // set up generic attrib pointers glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), (char*)0 + 0*sizeof(GLfloat)); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), (char*)0 + 3*sizeof(GLfloat)); // generate and bind the index buffer object glGenBuffers(1, &ibo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); GLuint indexData[] = { // face 0: 0,1,2, // first triangle 2,1,3, // second triangle // face 1: 4,5,6, // first triangle 6,5,7, // second triangle // face 2: 8,9,10, // first triangle 10,9,11, // second triangle // face 3: 12,13,14, // first triangle 14,13,15, // second triangle // face 4: 16,17,18, // first triangle 18,17,19, // second triangle // face 5: 20,21,22, // first triangle 22,21,23, // second triangle }; // fill with data glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*6*2*3, indexData, GL_STATIC_DRAW); // generate and bind the vertex buffer object containing the // instance offsets glGenBuffers(1, &tbo); glBindBuffer(GL_ARRAY_BUFFER, tbo); // the offsets GLfloat translationData[] = { 2.0f, 2.0f, 2.0f, // cube 0 2.0f, 2.0f,-2.0f, // cube 1 2.0f,-2.0f, 2.0f, // cube 2 2.0f,-2.0f,-2.0f, // cube 3 -2.0f, 2.0f, 2.0f, // cube 4 -2.0f, 2.0f,-2.0f, // cube 5 -2.0f,-2.0f, 2.0f, // cube 6 -2.0f,-2.0f,-2.0f, // cube 7 }; // 8 offsets with 3 components each // fill with data glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*3*8, translationData, GL_STATIC_DRAW); // set up generic attrib pointers glEnableVertexAttribArray(2); glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), (char*)0 + 0*sizeof(GLfloat)); // a attrib divisor of 1 means that attribute 2 will advance once // every instance (0 would mean once per vertex) glVertexAttribDivisor(2, 1); // "unbind" vao glBindVertexArray(0); // we are drawing 3d objects so we want depth testing glEnable(GL_DEPTH_TEST); while(userdata.running) { // get the time in seconds float t = glwtGetNanoTime()*1.e-9f; // update events glwtEventHandle(0); // clear first glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // use the shader program glUseProgram(shader_program); // calculate ViewProjection matrix glm::mat4 Projection = glm::perspective(90.0f, 4.0f / 3.0f, 0.1f, 100.f); // translate the world/view position glm::mat4 View = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -5.0f)); // make the camera rotate around the origin View = glm::rotate(View, 90.0f*t, glm::vec3(1.0f, 1.0f, 1.0f)); glm::mat4 ViewProjection = Projection*View; // set the uniform glUniformMatrix4fv(ViewProjection_location, 1, GL_FALSE, glm::value_ptr(ViewProjection)); // bind the vao glBindVertexArray(vao); // draw // the additional parameter indicates how many instances to render glDrawElementsInstanced(GL_TRIANGLES, 6*6, GL_UNSIGNED_INT, 0, 8); // check for errors GLenum error = glGetError(); if(error != GL_NO_ERROR) { userdata.running = false; } // finally swap buffers glwtSwapBuffers(window); } // delete the created objects glDeleteVertexArrays(1, &vao); glDeleteBuffers(1, &vbo); glDeleteBuffers(1, &ibo); glDeleteBuffers(1, &tbo); glDetachShader(shader_program, vertex_shader); glDetachShader(shader_program, fragment_shader); glDeleteShader(vertex_shader); glDeleteShader(fragment_shader); glDeleteProgram(shader_program); glwtWindowDestroy(window); glwtQuit(); return 0; }
GLWTWindow *glwtWindowCreate( const char *title, int width, int height, GLWTWindow *share, void (*win_callback)(GLWTWindow *window, const GLWTWindowEvent *event, void *userdata), void *userdata) { (void)title; GLWTWindow *win = calloc(1, sizeof(GLWTWindow)); if(!win) return 0; win->win_callback = win_callback; win->userdata = userdata; DISPMANX_UPDATE_HANDLE_T dispman_update; VC_RECT_T dst_rect; VC_RECT_T src_rect; dst_rect.x = 0; dst_rect.y = 0; dst_rect.width = glwt.rpi.width; dst_rect.height = glwt.rpi.height; width = glwt.rpi.width; height = glwt.rpi.height; src_rect.x = 0; src_rect.y = 0; src_rect.width = width << 16; src_rect.height = height << 16; dispman_update = vc_dispmanx_update_start( 0 ); VC_DISPMANX_ALPHA_T alpha_flags; alpha_flags.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS; alpha_flags.opacity = 255; alpha_flags.mask = 0; win->rpi.nativewindow.element = vc_dispmanx_element_add( dispman_update, glwt.rpi.dispman_display, 0 /*layer*/, &dst_rect, 0 /*src*/, &src_rect, DISPMANX_PROTECTION_NONE, &alpha_flags /*alpha*/, 0 /*clamp*/, (DISPMANX_TRANSFORM_T)0 /*transform*/); win->rpi.nativewindow.width = width; win->rpi.nativewindow.height = height; vc_dispmanx_update_submit_sync( dispman_update ); if(glwtWindowCreateEGL(win, share, &win->rpi.nativewindow) != 0) goto error; return win; error: glwtWindowDestroy(win); return 0; }
int main() { int width = 640; int height = 480; UserData userdata; userdata.running = true; GLWTConfig glwt_config; glwt_config.red_bits = 8; glwt_config.green_bits = 8; glwt_config.blue_bits = 8; glwt_config.alpha_bits = 8; glwt_config.depth_bits = 24; glwt_config.stencil_bits = 8; glwt_config.samples = 0; glwt_config.sample_buffers = 0; glwt_config.api = GLWT_API_OPENGL | GLWT_PROFILE_CORE; glwt_config.api_version_major = 3; glwt_config.api_version_minor = 3; GLWTAppCallbacks app_callbacks; app_callbacks.error_callback = error_callback; app_callbacks.userdata = &userdata; if(glwtInit(&glwt_config, &app_callbacks) != 0) { std::cerr << "failed to init GLWT" << std::endl; return 1; } GLWTWindowCallbacks win_callbacks; win_callbacks.close_callback = close_callback; win_callbacks.expose_callback = 0; win_callbacks.resize_callback = 0; win_callbacks.show_callback = 0; win_callbacks.focus_callback = 0; win_callbacks.key_callback = key_callback, win_callbacks.motion_callback = 0; win_callbacks.button_callback = 0; win_callbacks.mouseover_callback = 0; win_callbacks.userdata = &userdata; // create a window GLWTWindow *window = glwtWindowCreate("", width, height, &win_callbacks, 0); if(window == 0) { std::cerr << "failed to open window" << std::endl; glwtQuit(); return 1; } if (glxwInit()) { std::cerr << "failed to init GLXW" << std::endl; glwtWindowDestroy(window); glwtQuit(); return 1; } glwtWindowShow(window, 1); glwtMakeCurrent(window); glwtSwapInterval(window, 1); // shader source code std::string vertex_source = "#version 330\n" "layout(location = 0) in vec4 vposition;\n" "layout(location = 1) in vec2 vtexcoord;\n" "out vec2 ftexcoord;\n" "void main() {\n" " ftexcoord = vtexcoord;\n" " gl_Position = vposition;\n" "}\n"; std::string fragment_source = "#version 330\n" "uniform sampler2D tex;\n" // texture uniform "in vec2 ftexcoord;\n" "layout(location = 0) out vec4 FragColor;\n" "void main() {\n" " FragColor = texture(tex, ftexcoord);\n" "}\n"; // program and shader handles GLuint shader_program, vertex_shader, fragment_shader; // we need these to properly pass the strings const char *source; int length; // create and compiler vertex shader vertex_shader = glCreateShader(GL_VERTEX_SHADER); source = vertex_source.c_str(); length = vertex_source.size(); glShaderSource(vertex_shader, 1, &source, &length); glCompileShader(vertex_shader); if(!check_shader_compile_status(vertex_shader)) { return 1; } // create and compiler fragment shader fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); source = fragment_source.c_str(); length = fragment_source.size(); glShaderSource(fragment_shader, 1, &source, &length); glCompileShader(fragment_shader); if(!check_shader_compile_status(fragment_shader)) { return 1; } // create program shader_program = glCreateProgram(); // attach shaders glAttachShader(shader_program, vertex_shader); glAttachShader(shader_program, fragment_shader); // link the program and check for errors glLinkProgram(shader_program); check_program_link_status(shader_program); // get texture uniform location GLint texture_location = glGetUniformLocation(shader_program, "tex"); // vao and vbo handle GLuint vao, vbo, ibo; // generate and bind the vao glGenVertexArrays(1, &vao); glBindVertexArray(vao); // generate and bind the vertex buffer object glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); // data for a fullscreen quad (this time with texture coords) GLfloat vertexData[] = { // X Y Z U V 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // vertex 0 -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, // vertex 1 1.0f,-1.0f, 0.0f, 1.0f, 0.0f, // vertex 2 -1.0f,-1.0f, 0.0f, 0.0f, 0.0f, // vertex 3 }; // 4 vertices with 5 components (floats) each // fill with data glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*4*5, vertexData, GL_STATIC_DRAW); // set up generic attrib pointers glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (char*)0 + 0*sizeof(GLfloat)); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (char*)0 + 3*sizeof(GLfloat)); // generate and bind the index buffer object glGenBuffers(1, &ibo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); GLuint indexData[] = { 0,1,2, // first triangle 2,1,3, // second triangle }; // fill with data glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*2*3, indexData, GL_STATIC_DRAW); // "unbind" vao glBindVertexArray(0); // texture handle GLuint texture; // generate texture glGenTextures(1, &texture); // bind the texture glBindTexture(GL_TEXTURE_2D, texture); // create some image data std::vector<GLubyte> image(4*width*height); for(int j = 0;j<height;++j) for(int i = 0;i<width;++i) { size_t index = j*width + i; image[4*index + 0] = 0xFF*(j/10%2)*(i/10%2); // R image[4*index + 1] = 0xFF*(j/13%2)*(i/13%2); // G image[4*index + 2] = 0xFF*(j/17%2)*(i/17%2); // B image[4*index + 3] = 0xFF; // A } // set texture parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // set texture content glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &image[0]); while(userdata.running) { // update events glwtEventHandle(0); // clear first glClear(GL_COLOR_BUFFER_BIT); // use the shader program glUseProgram(shader_program); // bind texture to texture unit 0 glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture); // set texture uniform glUniform1i(texture_location, 0); // bind the vao glBindVertexArray(vao); // draw glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); // check for errors GLenum error = glGetError(); if(error != GL_NO_ERROR) { userdata.running = false; } // finally swap buffers glwtSwapBuffers(window); } // delete the created objects glDeleteTextures(1, &texture); glDeleteVertexArrays(1, &vao); glDeleteBuffers(1, &vbo); glDeleteBuffers(1, &ibo); glDetachShader(shader_program, vertex_shader); glDetachShader(shader_program, fragment_shader); glDeleteShader(vertex_shader); glDeleteShader(fragment_shader); glDeleteProgram(shader_program); glwtWindowDestroy(window); glwtQuit(); return 0; }
int main() { int width = 640; int height = 480; UserData userdata; userdata.running = true; GLWTConfig glwt_config; glwt_config.red_bits = 8; glwt_config.green_bits = 8; glwt_config.blue_bits = 8; glwt_config.alpha_bits = 8; glwt_config.depth_bits = 24; glwt_config.stencil_bits = 8; glwt_config.samples = 0; glwt_config.sample_buffers = 0; glwt_config.api = GLWT_API_OPENGL | GLWT_PROFILE_CORE; glwt_config.api_version_major = 3; glwt_config.api_version_minor = 3; GLWTAppCallbacks app_callbacks; app_callbacks.error_callback = error_callback; app_callbacks.userdata = &userdata; if(glwtInit(&glwt_config, &app_callbacks) != 0) { std::cerr << "failed to init GLWT" << std::endl; return 1; } GLWTWindowCallbacks win_callbacks; win_callbacks.close_callback = close_callback; win_callbacks.expose_callback = 0; win_callbacks.resize_callback = 0; win_callbacks.show_callback = 0; win_callbacks.focus_callback = 0; win_callbacks.key_callback = key_callback, win_callbacks.motion_callback = 0; win_callbacks.button_callback = 0; win_callbacks.mouseover_callback = 0; win_callbacks.userdata = &userdata; // create a window GLWTWindow *window = glwtWindowCreate("", width, height, &win_callbacks, 0); if(window == 0) { std::cerr << "failed to open window" << std::endl; glwtQuit(); return 1; } if (glxwInit()) { std::cerr << "failed to init GLXW" << std::endl; glwtWindowDestroy(window); glwtQuit(); return 1; } glwtWindowShow(window, 1); glwtMakeCurrent(window); glwtSwapInterval(window, 1); // shader source code std::string vertex_source = "#version 330\n" "layout(location = 0) in vec4 vposition;\n" "layout(location = 1) in vec4 vcolor;\n" "out vec4 fcolor;\n" "void main() {\n" " fcolor = vcolor;\n" " gl_Position = vposition;\n" "}\n"; std::string fragment_source = "#version 330\n" "in vec4 fcolor;\n" "layout(location = 0) out vec4 FragColor;\n" "void main() {\n" " FragColor = fcolor;\n" "}\n"; // program and shader handles GLuint shader_program, vertex_shader, fragment_shader; // we need these to properly pass the strings const char *source; int length; // create and compiler vertex shader vertex_shader = glCreateShader(GL_VERTEX_SHADER); source = vertex_source.c_str(); length = vertex_source.size(); glShaderSource(vertex_shader, 1, &source, &length); glCompileShader(vertex_shader); if(!check_shader_compile_status(vertex_shader)) { return 1; } // create and compiler fragment shader fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); source = fragment_source.c_str(); length = fragment_source.size(); glShaderSource(fragment_shader, 1, &source, &length); glCompileShader(fragment_shader); if(!check_shader_compile_status(fragment_shader)) { return 1; } // create program shader_program = glCreateProgram(); // attach shaders glAttachShader(shader_program, vertex_shader); glAttachShader(shader_program, fragment_shader); // link the program and check for errors glLinkProgram(shader_program); check_program_link_status(shader_program); // vao and vbo handle GLuint vao, vbo; // generate and bind the vao glGenVertexArrays(1, &vao); glBindVertexArray(vao); // generate and bind the buffer object glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); // data for a fullscreen quad GLfloat vertexData[] = { // X Y Z R G B 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, // vertex 0 -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // vertex 1 1.0f,-1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // vertex 2 1.0f,-1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // vertex 3 -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // vertex 4 -1.0f,-1.0f, 0.0f, 1.0f, 0.0f, 0.0f, // vertex 5 }; // 6 vertices with 6 components (floats) each // fill with data glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*6*6, vertexData, GL_STATIC_DRAW); // set up generic attrib pointers glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), (char*)0 + 0*sizeof(GLfloat)); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), (char*)0 + 3*sizeof(GLfloat)); // "unbind" vao glBindVertexArray(0); while(userdata.running) { // update events glwtEventHandle(0); // clear first glClear(GL_COLOR_BUFFER_BIT); // use the shader program glUseProgram(shader_program); // bind the vao glBindVertexArray(vao); // draw glDrawArrays(GL_TRIANGLES, 0, 6); // check for errors GLenum error = glGetError(); if(error != GL_NO_ERROR) { userdata.running = false; } // finally swap buffers glwtSwapBuffers(window); } // delete the created objects glDeleteVertexArrays(1, &vao); glDeleteBuffers(1, &vbo); glDetachShader(shader_program, vertex_shader); glDetachShader(shader_program, fragment_shader); glDeleteShader(vertex_shader); glDeleteShader(fragment_shader); glDeleteProgram(shader_program); glwtWindowDestroy(window); glwtQuit(); return 0; }