bool Window_GL::open(WindowParams p, std::string title) { // glfwWindowHint(GLFW_SAMPLES, p.samples); glfwWindowHint(GLFW_RESIZABLE, 1); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); int count; GLFWmonitor **ml = glfwGetMonitors(&count); GLFWmonitor *m = NULL; if (p.fullscreen) { m = glfwGetPrimaryMonitor(); if (p.fullscreen_monitor && p.fullscreen_monitor <= count) m = ml[p.fullscreen_monitor-1]; } handle = (void*)glfwCreateWindow(p.width, p.height, title.c_str(), m, NULL); glfwMakeContextCurrent((GLFWwindow*)handle); params = p; // Make sure we were able to create a rendering context. if (!handle) { LOG->Error("Unable to obtain an OpenGL 3.1 rendering context."); return false; } if (glxwInit() != 0) LOG->Error("Unable to load required OpenGL extensions."); return true; }
void SimpleGLScene::init() { t0 = QDateTime::currentMSecsSinceEpoch(); glxwInit(); glGetError(); // read & ignore GL_INVALID_ENUM here (GLEW bug) initShaders(); initBuffers(); glEnable(GL_DEPTH_TEST); sceneNode = YAML::LoadFile("test/scene.yaml"); }
void ae3d::GfxDevice::Init( int width, int height ) { if (glxwInit() != 0) { System::Print( "Unable to initialize GLXW!" ); return; } SetBackBufferDimensionAndFBO( width, height ); glEnable( GL_DEPTH_TEST ); }
bool GLFWWindow::open(const std::string& title, uint width, uint height) { if(opened) return true; this->title = title; this->width = width; this->height = height; if(glfwInit() == GL_FALSE) { logError("cannot initialize GLFW"); return false; } glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 3); glfwOpenWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); if(!glfwOpenWindow(width, height, 8, 8, 8, 8, 24, 8, GLFW_WINDOW)) { logError("cannot open the GLFW window"); return false; } if(!glxwInit()) return false; glfwSetWindowTitle(title.c_str()); glfwSetMouseButtonCallback(&mouseButtonCallback); glfwSetMousePosCallback(&mousePosCallback); glfwSetMouseWheelCallback(&mouseWheelCallback); glfwSetKeyCallback(&keyCallback); this->opened = true; return true; }
// APPLICATION ENTRY // ----------------- int main() { int width = 1024; int height = 768; sim_ptr = NULL; int c = 0; GLFWmonitor** m = glfwGetMonitors(&c); // init glfwSetErrorCallback(error_callback); if(!glfwInit()) { printf("ERROR: cannot initialize GLFW.\n"); exit(EXIT_FAILURE); } // glfwWindowHint(GLFW_DEPTH_BITS, 16); // glfwWindowHint(GLFW_FSAA_SAMPLES, 4); GLFWwindow* window = glfwCreateWindow(width, height, "Simulation", NULL, NULL); if(!window) { printf("ERROR: cannot open window.\n"); exit(EXIT_FAILURE); } glfwSetWindowSizeCallback(window, window_size_callback); glfwSetWindowCloseCallback(window, window_close_callback); glfwSetMouseButtonCallback(window, mouse_button_callback); glfwSetCursorPosCallback(window, cursor_callback); glfwSetScrollCallback(window, scroll_callback); glfwSetKeyCallback(window, key_callback); glfwSetCharCallback(window, char_callback); glfwMakeContextCurrent(window); #if defined(ROXLU_GL_CORE3) if(glxwInit() != 0) { printf("ERROR: cannot init glxw\n"); return EXIT_FAILURE; } #else glewExperimental = true; GLenum err = glewInit(); if (GLEW_OK != err) { fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err)); exit(EXIT_FAILURE); } #endif Simulation sim; sim_ptr = ∼ sim.window = window; sim.window_w = width; sim.window_h = height; sim.setup(); bool running = true; while(running) { glfwPollEvents(); sim.update(); sim.draw(); glfwSwapBuffers(window); running = !(glfwGetKey(window, GLFW_KEY_ESC)); } glfwTerminate(); return EXIT_SUCCESS; };
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; }
int main() { int width = 640; int height = 480; if(glfwInit() == GL_FALSE) { std::cerr << "failed to init GLFW" << std::endl; return 1; } // select opengl version glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // create a window GLFWwindow *window; if((window = glfwCreateWindow(width, height, "02indexed_vbo", 0, 0)) == 0) { std::cerr << "failed to open window" << std::endl; glfwTerminate(); return 1; } glfwMakeContextCurrent(window); if(glxwInit()) { std::cerr << "failed to init GL3W" << std::endl; glfwDestroyWindow(window); glfwTerminate(); return 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)) { glfwDestroyWindow(window); glfwTerminate(); 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)) { glfwDestroyWindow(window); glfwTerminate(); 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, 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 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, 1.0f, 0.0f, 0.0f, // vertex 3 }; // 4 vertices with 6 components (floats) each // fill with data glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*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[] = { 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); while(!glfwWindowShouldClose(window)) { glfwPollEvents(); // clear first glClear(GL_COLOR_BUFFER_BIT); // use the shader program glUseProgram(shader_program); // 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) { std::cerr << error << std::endl; break; } // finally swap buffers glfwSwapBuffers(window); } // delete the created objects 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); glfwDestroyWindow(window); glfwTerminate(); return 0; }
int main() { if(glfwInit() == GL_FALSE) { std::cerr << "Failed to initialize GLFW" << std::endl; return -1; } defer(glfwTerminate()); glfwDefaultWindowHints(); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_SAMPLES, 4); GLFWwindow* window = glfwCreateWindow(800, 600, "Models", nullptr, nullptr); if(window == nullptr) { std::cerr << "Failed to open GLFW window" << std::endl; return -1; } defer(glfwDestroyWindow(window)); glfwMakeContextCurrent(window); if(glxwInit()) { std::cerr << "Failed to init GLXW" << std::endl; return -1; } glfwSwapInterval(1); glfwSetWindowSizeCallback(window, windowSizeCallback); glfwShowWindow(window); bool errorFlag = false; std::vector<GLuint> shaders; GLuint vertexShaderId = loadShader("shaders/vertexShader.glsl", GL_VERTEX_SHADER, &errorFlag); if(errorFlag) { std::cerr << "Failed to load vertex shader (invalid working directory?)" << std::endl; return -1; } shaders.push_back(vertexShaderId); GLuint fragmentShaderId = loadShader("shaders/fragmentShader.glsl", GL_FRAGMENT_SHADER, &errorFlag); if(errorFlag) { std::cerr << "Failed to load fragment shader (invalid working directory?)" << std::endl; return -1; } shaders.push_back(fragmentShaderId); GLuint programId = prepareProgram(shaders, &errorFlag); if(errorFlag) { std::cerr << "Failed to prepare program" << std::endl; return -1; } defer(glDeleteProgram(programId)); glDeleteShader(vertexShaderId); glDeleteShader(fragmentShaderId); // === prepare textures === GLuint textureArray[3]; int texturesNum = sizeof(textureArray)/sizeof(textureArray[0]); glGenTextures(texturesNum, textureArray); defer(glDeleteTextures(texturesNum, textureArray)); GLuint grassTexture = textureArray[0]; GLuint skyboxTexture = textureArray[1]; GLuint towerTexture = textureArray[2]; if(!loadDDSTexture("textures/grass.dds", grassTexture)) return -1; if(!loadDDSTexture("textures/skybox.dds", skyboxTexture)) return -1; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); if(!loadDDSTexture("textures/tower.dds", towerTexture)) return -1; // === prepare VAOs === GLuint vaoArray[3]; int vaosNum = sizeof(vaoArray)/sizeof(vaoArray[0]); glGenVertexArrays(vaosNum, vaoArray); defer(glDeleteVertexArrays(vaosNum, vaoArray)); GLuint grassVAO = vaoArray[0]; GLuint skyboxVAO = vaoArray[1]; GLuint towerVAO = vaoArray[2]; // === prepare VBOs === GLuint vboArray[6]; int vbosNum = sizeof(vboArray)/sizeof(vboArray[0]); glGenBuffers(vbosNum, vboArray); defer(glDeleteBuffers(vbosNum, vboArray)); GLuint grassVBO = vboArray[0]; GLuint skyboxVBO = vboArray[1]; GLuint towerVBO = vboArray[2]; GLuint grassIndicesVBO = vboArray[3]; GLuint skyboxIndicesVBO = vboArray[4]; GLuint towerIndicesVBO = vboArray[5]; // === load models === GLsizei grassIndicesNumber, skyboxIndicesNumber, towerIndicesNumber; GLenum grassIndexType, skyboxIndexType, towerIndexType; if(!modelLoad("models/grass.emd", grassVAO, grassVBO, grassIndicesVBO, &grassIndicesNumber, &grassIndexType)) return -1; if(!modelLoad("models/skybox.emd", skyboxVAO, skyboxVBO, skyboxIndicesVBO, &skyboxIndicesNumber, &skyboxIndexType)) return -1; if(!modelLoad("models/tower.emd", towerVAO, towerVBO, towerIndicesVBO, &towerIndicesNumber, &towerIndexType)) return -1; glm::mat4 projection = glm::perspective(70.0f, 4.0f / 3.0f, 0.3f, 250.0f); GLint matrixId = glGetUniformLocation(programId, "MVP"); GLint samplerId = glGetUniformLocation(programId, "textureSampler"); auto startTime = std::chrono::high_resolution_clock::now(); auto prevTime = startTime; glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); // hide cursor Camera camera(window, glm::vec3(0, 0, 5), 3.14f /* toward -Z */, 0.0f /* look at the horizon */); glEnable(GL_DOUBLEBUFFER); glEnable(GL_CULL_FACE); glEnable(GL_MULTISAMPLE); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glClearColor(0, 0, 0, 1); glUniform1i(samplerId, 0); while(glfwWindowShouldClose(window) == GL_FALSE) { if(glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) break; if(glfwGetKey(window, GLFW_KEY_Z) == GLFW_PRESS) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } if(glfwGetKey(window, GLFW_KEY_X) == GLFW_PRESS) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } auto currentTime = std::chrono::high_resolution_clock::now(); float startDeltaTimeMs = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - startTime).count(); float prevDeltaTimeMs = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - prevTime).count(); prevTime = currentTime; float rotationTimeMs = 100000.0f; float currentRotation = startDeltaTimeMs / rotationTimeMs; float islandAngle = 360.0f*(currentRotation - (long)currentRotation); glm::mat4 view; camera.getViewMatrix(prevDeltaTimeMs, &view); glm::mat4 vp = projection * view; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(programId); glm::mat4 towerMVP = vp * glm::rotate(islandAngle, 0.0f, 1.0f, 0.0f) * glm::translate(-1.5f, -1.0f, -1.5f); glBindTexture(GL_TEXTURE_2D, towerTexture); glBindVertexArray(towerVAO); glUniformMatrix4fv(matrixId, 1, GL_FALSE, &towerMVP[0][0]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, towerIndicesVBO); glDrawElements(GL_TRIANGLES, towerIndicesNumber, towerIndexType, nullptr); glm::mat4 grassMVP = vp * glm::rotate(islandAngle, 0.0f, 1.0f, 0.0f) * glm::translate(0.0f, -1.0f, 0.0f); glBindTexture(GL_TEXTURE_2D, grassTexture); glBindVertexArray(grassVAO); glUniformMatrix4fv(matrixId, 1, GL_FALSE, &grassMVP[0][0]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, grassIndicesVBO); glDrawElements(GL_TRIANGLES, grassIndicesNumber, grassIndexType, nullptr); glm::vec3 cameraPos; camera.getPosition(&cameraPos); glm::mat4 skyboxMatrix = glm::translate(cameraPos) * glm::scale(100.0f,100.0f,100.0f); glm::mat4 skyboxMVP = vp * skyboxMatrix; // TODO: implement modelDraw procedure (or maybe Model object?) glBindTexture(GL_TEXTURE_2D, skyboxTexture); glBindVertexArray(skyboxVAO); glUniformMatrix4fv(matrixId, 1, GL_FALSE, &skyboxMVP[0][0]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, skyboxIndicesVBO); glDrawElements(GL_TRIANGLES, skyboxIndicesNumber, skyboxIndexType, nullptr); glfwSwapBuffers(window); glfwPollEvents(); } 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); // 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() { if(glfwInit() == GL_FALSE) { std::cerr << "Failed to initialize GLFW" << std::endl; return -1; } defer(glfwTerminate()); glfwDefaultWindowHints(); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_SAMPLES, 4); GLFWwindow* window = glfwCreateWindow(800, 600, "Lighting", nullptr, nullptr); if(window == nullptr) { std::cerr << "Failed to open GLFW window" << std::endl; return -1; } defer(glfwDestroyWindow(window)); glfwMakeContextCurrent(window); if(glxwInit()) { std::cerr << "Failed to init GLXW" << std::endl; return -1; } glfwSwapInterval(1); glfwSetWindowSizeCallback(window, windowSizeCallback); glfwShowWindow(window); bool errorFlag = false; std::vector<GLuint> shaders; GLuint vertexShaderId = loadShader("shaders/vertexShader.glsl", GL_VERTEX_SHADER, &errorFlag); if(errorFlag) { std::cerr << "Failed to load vertex shader (invalid working directory?)" << std::endl; return -1; } shaders.push_back(vertexShaderId); GLuint fragmentShaderId = loadShader("shaders/fragmentShader.glsl", GL_FRAGMENT_SHADER, &errorFlag); if(errorFlag) { std::cerr << "Failed to load fragment shader (invalid working directory?)" << std::endl; return -1; } shaders.push_back(fragmentShaderId); GLuint programId = prepareProgram(shaders, &errorFlag); if(errorFlag) { std::cerr << "Failed to prepare program" << std::endl; return -1; } defer(glDeleteProgram(programId)); glDeleteShader(vertexShaderId); glDeleteShader(fragmentShaderId); // === prepare textures === GLuint textureArray[6]; int texturesNum = sizeof(textureArray)/sizeof(textureArray[0]); glGenTextures(texturesNum, textureArray); defer(glDeleteTextures(texturesNum, textureArray)); GLuint grassTexture = textureArray[0]; GLuint skyboxTexture = textureArray[1]; GLuint towerTexture = textureArray[2]; GLuint garkGreenTexture = textureArray[3]; GLuint redTexture = textureArray[4]; GLuint blueTexture = textureArray[5]; if(!loadDDSTexture("textures/grass.dds", grassTexture)) return -1; if(!loadDDSTexture("textures/skybox.dds", skyboxTexture)) return -1; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); if(!loadDDSTexture("textures/tower.dds", towerTexture)) return -1; loadOneColorTexture(0.05f, 0.5f, 0.1f, garkGreenTexture); loadOneColorTexture(1.0f, 0.0f, 0.0f, redTexture); loadOneColorTexture(0.0f, 0.0f, 1.0f, blueTexture); // === prepare VAOs === GLuint vaoArray[5]; int vaosNum = sizeof(vaoArray)/sizeof(vaoArray[0]); glGenVertexArrays(vaosNum, vaoArray); defer(glDeleteVertexArrays(vaosNum, vaoArray)); GLuint grassVAO = vaoArray[0]; GLuint skyboxVAO = vaoArray[1]; GLuint towerVAO = vaoArray[2]; GLuint torusVAO = vaoArray[3]; GLuint sphereVAO = vaoArray[4]; // === prepare VBOs === GLuint vboArray[10]; int vbosNum = sizeof(vboArray)/sizeof(vboArray[0]); glGenBuffers(vbosNum, vboArray); defer(glDeleteBuffers(vbosNum, vboArray)); GLuint grassVBO = vboArray[0]; GLuint grassIndicesVBO = vboArray[1]; GLuint skyboxVBO = vboArray[2]; GLuint skyboxIndicesVBO = vboArray[3]; GLuint towerVBO = vboArray[4]; GLuint towerIndicesVBO = vboArray[5]; GLuint torusVBO = vboArray[6]; GLuint torusIndicesVBO = vboArray[7]; GLuint sphereVBO = vboArray[8]; GLuint sphereIndicesVBO = vboArray[9]; // === load models === GLsizei grassIndicesNumber, skyboxIndicesNumber, towerIndicesNumber, torusIndicesNumber, sphereIndicesNumber; GLenum grassIndexType, skyboxIndexType, towerIndexType, torusIndexType, sphereIndexType; if(!modelLoad("models/grass.emd", grassVAO, grassVBO, grassIndicesVBO, &grassIndicesNumber, &grassIndexType)) return -1; if(!modelLoad("models/skybox.emd", skyboxVAO, skyboxVBO, skyboxIndicesVBO, &skyboxIndicesNumber, &skyboxIndexType)) return -1; if(!modelLoad("models/tower.emd", towerVAO, towerVBO, towerIndicesVBO, &towerIndicesNumber, &towerIndexType)) return -1; if(!modelLoad("models/torus.emd", torusVAO, torusVBO, torusIndicesVBO, &torusIndicesNumber, &torusIndexType)) return -1; if(!modelLoad("models/sphere.emd", sphereVAO, sphereVBO, sphereIndicesVBO, &sphereIndicesNumber, &sphereIndexType)) return -1; glm::mat4 projection = glm::perspective(70.0f, 4.0f / 3.0f, 0.3f, 250.0f); GLint uniformMVP = getUniformLocation(programId, "MVP"); GLint uniformM = getUniformLocation(programId, "M"); GLint uniformTextureSample = getUniformLocation(programId, "textureSampler"); GLint uniformCameraPos = getUniformLocation(programId, "cameraPos"); GLint uniformMaterialSpecularFactor = getUniformLocation(programId, "materialSpecularFactor"); GLint uniformMaterialSpecularIntensity = getUniformLocation(programId, "materialSpecularIntensity"); GLint uniformMaterialEmission = getUniformLocation(programId, "materialEmission"); auto startTime = std::chrono::high_resolution_clock::now(); auto prevTime = startTime; Camera camera(window, glm::vec3(0, 0, 5), 3.14f /* toward -Z */, 0.0f /* look at the horizon */); glEnable(GL_DOUBLEBUFFER); glEnable(GL_CULL_FACE); glEnable(GL_MULTISAMPLE); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glClearColor(0, 0, 0, 1); glUseProgram(programId); glUniform1i(uniformTextureSample, 0); bool directionalLightEnabled = true; bool pointLightEnabled = true; bool spotLightEnabled = true; bool wireframesModeEnabled = false; float lastKeyPressCheck = 0.0; const float keyPressCheckIntervalMs = 250.0f; setupLights(programId, directionalLightEnabled, pointLightEnabled, spotLightEnabled); while(glfwWindowShouldClose(window) == GL_FALSE) { if(glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) break; auto currentTime = std::chrono::high_resolution_clock::now(); float startDeltaTimeMs = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - startTime).count(); float prevDeltaTimeMs = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - prevTime).count(); prevTime = currentTime; float rotationTimeMs = 100000.0f; float currentRotation = startDeltaTimeMs / rotationTimeMs; float islandAngle = 360.0f*(currentRotation - (long)currentRotation); if(startDeltaTimeMs - lastKeyPressCheck > keyPressCheckIntervalMs) { if(glfwGetKey(window, GLFW_KEY_X) == GLFW_PRESS) { lastKeyPressCheck = startDeltaTimeMs; wireframesModeEnabled = !wireframesModeEnabled; if(wireframesModeEnabled) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); else glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } if(glfwGetKey(window, GLFW_KEY_M) == GLFW_PRESS) { lastKeyPressCheck = startDeltaTimeMs; bool enabled = camera.getMouseInterception(); camera.setMouseInterception(!enabled); } if(glfwGetKey(window, GLFW_KEY_1) == GLFW_PRESS) { lastKeyPressCheck = startDeltaTimeMs; directionalLightEnabled = !directionalLightEnabled; setupLights(programId, directionalLightEnabled, pointLightEnabled, spotLightEnabled); } if(glfwGetKey(window, GLFW_KEY_2) == GLFW_PRESS) { lastKeyPressCheck = startDeltaTimeMs; pointLightEnabled = !pointLightEnabled; setupLights(programId, directionalLightEnabled, pointLightEnabled, spotLightEnabled); } if(glfwGetKey(window, GLFW_KEY_3) == GLFW_PRESS) { lastKeyPressCheck = startDeltaTimeMs; spotLightEnabled = !spotLightEnabled; setupLights(programId, directionalLightEnabled, pointLightEnabled, spotLightEnabled); } } glm::vec3 cameraPos; camera.getPosition(&cameraPos); glUniform3f(uniformCameraPos, cameraPos.x, cameraPos.y, cameraPos.z); glm::mat4 view; camera.getViewMatrix(prevDeltaTimeMs, &view); glm::mat4 vp = projection * view; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // TODO implement ModelLoader and Model classes // tower glm::mat4 towerM = glm::rotate(islandAngle, 0.0f, 1.0f, 0.0f) * glm::translate(-1.5f, -1.0f, -1.5f); glm::mat4 towerMVP = vp * towerM; glBindTexture(GL_TEXTURE_2D, towerTexture); glBindVertexArray(towerVAO); glUniformMatrix4fv(uniformMVP, 1, GL_FALSE, &towerMVP[0][0]); glUniformMatrix4fv(uniformM, 1, GL_FALSE, &towerM[0][0]); glUniform1f(uniformMaterialSpecularFactor, 1.0f); glUniform1f(uniformMaterialSpecularIntensity, 0.0f); glUniform3f(uniformMaterialEmission, 0.0f, 0.0f, 0.0f); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, towerIndicesVBO); glDrawElements(GL_TRIANGLES, towerIndicesNumber, towerIndexType, nullptr); // torus glm::mat4 torusM = glm::translate(0.0f, 1.0f, 0.0f) * glm::rotate((60.0f - 3.0f*islandAngle), 0.0f, 0.5f, 0.0f); glm::mat4 torusMVP = vp * torusM; glBindTexture(GL_TEXTURE_2D, garkGreenTexture); glBindVertexArray(torusVAO); glUniformMatrix4fv(uniformMVP, 1, GL_FALSE, &torusMVP[0][0]); glUniformMatrix4fv(uniformM, 1, GL_FALSE, &torusM[0][0]); glUniform1f(uniformMaterialSpecularFactor, 1.0f); glUniform1f(uniformMaterialSpecularIntensity, 1.0f); glUniform3f(uniformMaterialEmission, 0.0f, 0.0f, 0.0f); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, torusIndicesVBO); glDrawElements(GL_TRIANGLES, torusIndicesNumber, torusIndexType, nullptr); // grass glm::mat4 grassM = glm::rotate(islandAngle, 0.0f, 1.0f, 0.0f) * glm::translate(0.0f, -1.0f, 0.0f); glm::mat4 grassMVP = vp * grassM; glBindTexture(GL_TEXTURE_2D, grassTexture); glBindVertexArray(grassVAO); glUniformMatrix4fv(uniformMVP, 1, GL_FALSE, &grassMVP[0][0]); glUniformMatrix4fv(uniformM, 1, GL_FALSE, &grassM[0][0]); glUniform1f(uniformMaterialSpecularFactor, 32.0f); glUniform1f(uniformMaterialSpecularIntensity, 2.0f); glUniform3f(uniformMaterialEmission, 0.0f, 0.0f, 0.0f); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, grassIndicesVBO); glDrawElements(GL_TRIANGLES, grassIndicesNumber, grassIndexType, nullptr); // skybox glm::mat4 skyboxM = glm::translate(cameraPos) * glm::scale(100.0f,100.0f,100.0f); glm::mat4 skyboxMVP = vp * skyboxM; glBindTexture(GL_TEXTURE_2D, skyboxTexture); glBindVertexArray(skyboxVAO); glUniformMatrix4fv(uniformMVP, 1, GL_FALSE, &skyboxMVP[0][0]); glUniformMatrix4fv(uniformM, 1, GL_FALSE, &skyboxM[0][0]); glUniform1f(uniformMaterialSpecularFactor, 1.0f); glUniform1f(uniformMaterialSpecularIntensity, 0.0f); glUniform3f(uniformMaterialEmission, 0.0f, 0.0f, 0.0f); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, skyboxIndicesVBO); glDrawElements(GL_TRIANGLES, skyboxIndicesNumber, skyboxIndexType, nullptr); // point light source if(pointLightEnabled) { glm::mat4 pointLightM = glm::translate(pointLightPos); glm::mat4 pointLightMVP = vp * pointLightM; glBindTexture(GL_TEXTURE_2D, redTexture); glBindVertexArray(sphereVAO); glUniformMatrix4fv(uniformMVP, 1, GL_FALSE, &pointLightMVP[0][0]); glUniformMatrix4fv(uniformM, 1, GL_FALSE, &pointLightM[0][0]); glUniform1f(uniformMaterialSpecularFactor, 1.0f); glUniform1f(uniformMaterialSpecularIntensity, 1.0f); glUniform3f(uniformMaterialEmission, 0.5f, 0.5f, 0.5f); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, sphereIndicesVBO); glDrawElements(GL_TRIANGLES, sphereIndicesNumber, sphereIndexType, nullptr); } // spot light source if(spotLightEnabled) { glm::mat4 spotLightM = glm::translate(spotLightPos); glm::mat4 spotLightMVP = vp * spotLightM; glBindTexture(GL_TEXTURE_2D, blueTexture); glBindVertexArray(sphereVAO); glUniformMatrix4fv(uniformMVP, 1, GL_FALSE, &spotLightMVP[0][0]); glUniformMatrix4fv(uniformM, 1, GL_FALSE, &spotLightM[0][0]); glUniform1f(uniformMaterialSpecularFactor, 1.0f); glUniform1f(uniformMaterialSpecularIntensity, 1.0f); glUniform3f(uniformMaterialEmission, 0.5f, 0.5f, 0.5f); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, sphereIndicesVBO); glDrawElements(GL_TRIANGLES, sphereIndicesNumber, sphereIndexType, nullptr); } glfwSwapBuffers(window); glfwPollEvents(); } return 0; }
int main() { if(glfwInit() == GL_FALSE) { std::cerr << "Failed to initialize GLFW" << std::endl; return -1; } defer(std::cout << "Calling glfwTerminate()" << std::endl; glfwTerminate()); glfwDefaultWindowHints(); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); GLFWwindow* window = glfwCreateWindow(800, 600, "Rotating cube", nullptr, nullptr); if(window == nullptr) { std::cerr << "Failed to open GLFW window" << std::endl; return -1; } defer(std::cout << "Calling glfwDestroyWindow()" << std::endl; glfwDestroyWindow(window)); glfwMakeContextCurrent(window); if(glxwInit()) { std::cerr << "Failed to init GLXW" << std::endl; return -1; } glfwSwapInterval(1); glfwSetWindowSizeCallback(window, windowSizeCallback); glfwShowWindow(window); bool errorFlag = false; std::vector<GLuint> shaders; GLuint vertexShaderId = loadShader("shaders/vertexShader.glsl", GL_VERTEX_SHADER, &errorFlag); if(errorFlag) { std::cerr << "Failed to load vertex shader (invalid working directory?)" << std::endl; return -1; } shaders.push_back(vertexShaderId); GLuint fragmentShaderId = loadShader("shaders/fragmentShader.glsl", GL_FRAGMENT_SHADER, &errorFlag); if(errorFlag) { std::cerr << "Failed to load fragment shader (invalid working directory?)" << std::endl; return -1; } shaders.push_back(fragmentShaderId); GLuint programId = prepareProgram(shaders, &errorFlag); if(errorFlag) { std::cerr << "Failed to prepare program" << std::endl; return -1; } defer(glDeleteProgram(programId)); glDeleteShader(vertexShaderId); glDeleteShader(fragmentShaderId); GLuint vertexVBO; glGenBuffers(1, &vertexVBO); defer(glDeleteBuffers(1, &vertexVBO)); glBindBuffer(GL_ARRAY_BUFFER, vertexVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(globVertexBufferData), globVertexBufferData, GL_STATIC_DRAW); GLuint colorVBO; glGenBuffers(1, &colorVBO); defer(glDeleteBuffers(1, &colorVBO)); glBindBuffer(GL_ARRAY_BUFFER, colorVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(globColorBufferData), globColorBufferData, GL_STATIC_DRAW); GLuint vao; glGenVertexArrays(1, &vao); defer(glDeleteVertexArrays(1, &vao)); glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, vertexVBO); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); glBindBuffer(GL_ARRAY_BUFFER, 0); // unbind VBO glBindBuffer(GL_ARRAY_BUFFER, colorVBO); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr); glBindBuffer(GL_ARRAY_BUFFER, 0); // unbind VBO glBindVertexArray(0); // unbind VAO glm::mat4 projection = glm::perspective(80.0f, 4.0f / 3.0f, 0.3f, 100.0f); GLint matrixId = glGetUniformLocation(programId, "MVP"); auto startTime = std::chrono::high_resolution_clock::now(); auto prevTime = startTime; // hide cursor glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); Camera camera(window, glm::vec3(0, 0, 5), 3.14f /* toward -Z */, 0.0f /* look at the horizon */); glEnable(GL_DOUBLEBUFFER); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glDepthFunc(GL_LESS); glClearColor(0, 0, 0, 1); while(glfwWindowShouldClose(window) == GL_FALSE) { if(glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) break; if(glfwGetKey(window, GLFW_KEY_Z) == GLFW_PRESS) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } if(glfwGetKey(window, GLFW_KEY_X) == GLFW_PRESS) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } auto currentTime = std::chrono::high_resolution_clock::now(); float startDeltaTimeMs = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - startTime).count(); float prevDeltaTimeMs = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - prevTime).count(); prevTime = currentTime; float rotationTimeMs = 3000.0f; float currentRotation = startDeltaTimeMs / rotationTimeMs; float angle = 360.0f*(currentRotation - (long)currentRotation); glm::mat4 view; camera.getViewMatrix(prevDeltaTimeMs, &view); glm::mat4 model = glm::rotate(angle, 0.0f, 1.0f, 0.0f); glm::mat4 mvp = projection * view * model; // matrix multiplication is the other way around glUniformMatrix4fv(matrixId, 1, GL_FALSE, &mvp[0][0]); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(programId); glBindVertexArray(vao); glEnableVertexAttribArray(0); // could be done once before while loop ... -> glEnableVertexAttribArray(1); glDrawArrays(GL_TRIANGLES, 0, 3*12); glDisableVertexAttribArray(1); // -> ... in this cast remove these two lines glDisableVertexAttribArray(0); glfwSwapBuffers(window); glfwPollEvents(); } 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; }
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; }
int main() { int width = 640; int height = 480; if(glfwInit() == GL_FALSE) { std::cerr << "failed to init GLFW" << std::endl; return 1; } // select opengl version glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // create a window GLFWwindow *window; if((window = glfwCreateWindow(width, height, "03texture", 0, 0)) == 0) { std::cerr << "failed to open window" << std::endl; glfwTerminate(); return 1; } glfwMakeContextCurrent(window); if(glxwInit()) { std::cerr << "failed to init GL3W" << std::endl; glfwDestroyWindow(window); glfwTerminate(); return 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)) { glfwDestroyWindow(window); glfwTerminate(); 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)) { glfwDestroyWindow(window); glfwTerminate(); 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(!glfwWindowShouldClose(window)) { glfwPollEvents(); // 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) { std::cerr << error << std::endl; break; } // finally swap buffers glfwSwapBuffers(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); glfwDestroyWindow(window); glfwTerminate(); return 0; }