// http://stackoverflow.com/questions/6005076/building-glew-on-windows-with-mingw #define GLEW_STATIC #include #include #include #include #include #include #include #include #include GLuint LoadTexture(char *filename,int *textw,int *texth) { SDL_Surface *surface; GLuint textureid; int mode; surface = IMG_Load(filename); // Or if you don't use SDL_image you can use SDL_LoadBMP here instead: // surface = SDL_LoadBMP(filename); // could not load filename if (!surface) { return 0; } // work out what format to tell glTexImage2D to use... if (surface->format->BytesPerPixel == 3) { // RGB 24bit mode = GL_RGB; } else if (surface->format->BytesPerPixel == 4) { // RGBA 32bit mode = GL_RGBA; } else { SDL_FreeSurface(surface); return 0; } *textw=surface->w; *texth=surface->h; // create one texture name glGenTextures(1, &textureid); // tell opengl to use the generated texture name glBindTexture(GL_TEXTURE_2D, textureid); // this reads from the sdl surface and puts it into an opengl texture glTexImage2D(GL_TEXTURE_2D, 0, mode, surface->w, surface->h, 0, mode, GL_UNSIGNED_BYTE, surface->pixels); // these affect how this texture is drawn later on...glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // clean up SDL_FreeSurface(surface); return textureid; } GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path){ // Create the shaders GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); // Read the Vertex Shader code from the file std::string VertexShaderCode; std::ifstream VertexShaderStream(vertex_file_path, std::ios::in); if(VertexShaderStream.is_open()){ std::string Line = ""; while(getline(VertexShaderStream, Line)) VertexShaderCode += "\n" + Line; VertexShaderStream.close(); }else{ printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", vertex_file_path); getchar(); return 0; } // Read the Fragment Shader code from the file std::string FragmentShaderCode; std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in); if(FragmentShaderStream.is_open()){ std::string Line = ""; while(getline(FragmentShaderStream, Line)) FragmentShaderCode += "\n" + Line; FragmentShaderStream.close(); } GLint Result = GL_FALSE; int InfoLogLength; // Compile Vertex Shader printf("Compiling shader : %s\n", vertex_file_path); char const * VertexSourcePointer = VertexShaderCode.c_str(); glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL); glCompileShader(VertexShaderID); // Check Vertex Shader glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); if ( InfoLogLength > 0 ){ std::vector VertexShaderErrorMessage(InfoLogLength+1); glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); printf("%s\n", &VertexShaderErrorMessage[0]); } // Compile Fragment Shader printf("Compiling shader : %s\n", fragment_file_path); char const * FragmentSourcePointer = FragmentShaderCode.c_str(); glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL); glCompileShader(FragmentShaderID); // Check Fragment Shader glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); if ( InfoLogLength > 0 ){ std::vector FragmentShaderErrorMessage(InfoLogLength+1); glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]); printf("%s\n", &FragmentShaderErrorMessage[0]); } // Link the program printf("Linking program\n"); GLuint ProgramID = glCreateProgram(); glAttachShader(ProgramID, VertexShaderID); glAttachShader(ProgramID, FragmentShaderID); glLinkProgram(ProgramID); // Check the program glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); if ( InfoLogLength > 0 ){ std::vector ProgramErrorMessage(InfoLogLength+1); glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]); printf("%s\n", &ProgramErrorMessage[0]); } glDetachShader(ProgramID, VertexShaderID); glDetachShader(ProgramID, FragmentShaderID); glDeleteShader(VertexShaderID); glDeleteShader(FragmentShaderID); return ProgramID; } GLuint WriteTexture(int textw, int texth){ // The framebuffer, which regroups 0, 1, or more textures, and 0 or 1 depth buffer. GLuint FramebufferName = 0; glGenFramebuffers(1, &FramebufferName); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName); // The texture we're going to render to GLuint renderedTexture; glGenTextures(1, &renderedTexture); // "Bind" the newly created texture : all future texture functions will modify this texture glBindTexture(GL_TEXTURE_2D, renderedTexture); // Give an empty image to OpenGL ( the last "0" ) glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, textw, texth, 0,GL_RGB, GL_UNSIGNED_BYTE, 0); // Poor filtering. Needed ! glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // The depth buffer -- OPTIONAL, REMOVE WHEN NOT NEEDED GLuint depthrenderbuffer; glGenRenderbuffers(1, &depthrenderbuffer); glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbuffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 1024, 768); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthrenderbuffer); // Set "renderedTexture" as our colour attachement #0 glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderedTexture, 0); // Set the list of draw buffers. GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0}; glDrawBuffers(1, DrawBuffers); // "1" is the size of DrawBuffers // Always check that our framebuffer is ok if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) return false; } int main(int argc, char* args[]) { GLFWwindow* window; GLuint tex1, tex2; int textw, texth; int textw2, texth2; /* Initialize the library */ /* GLFW */ if (!glfwInit()) { printf("GLFW Error"); return 1; } /* Create a windowed mode window and its OpenGL context */ glfwSetWindowSizeLimits(window, 640, 480, 640, 480); window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL); if (!window) { glfwTerminate(); return 1; } /* Make the window's context current */ glfwMakeContextCurrent(window); /* GLEW */ glewExperimental = GL_FALSE; GLenum error = glGetError(); if (error != GL_NO_ERROR) { std::cout << "OpenGL Error: " << error << std::endl; } GLenum glewinit = glewInit(); if (glewinit != GLEW_OK) { std::cout << "Glew not okay! " << glewinit; return 1; } /* SDL */ if (SDL_Init(SDL_INIT_VIDEO) < 0) { printf("SDL Error"); return 1; } // INIT // An array of 3 vectors which represents 3 vertices static const GLfloat g_vertex_buffer_data[] = { -1.0f, -1.0f, 0.0f, // (bottom - left ) TRIANGLE 1 1.0f, -1.0f, 0.0f, // (bottom - right) -1.0f, 1.0f, 0.0f, // (top - left ) 1.0f, 1.0f, 0.0f, // (top - right) TRIANGLE 2 1.0f, -1.0f, 0.0f, // (bottom - right) -1.0f, 1.0f, 0.0f, // (top - left ) }; // One color for each vertex. They were generated randomly. static const GLfloat g_uv_buffer_data[] = { 0.0f, 1.0f-0.0f, // (bottom - left ) TRIANGLE 1 1.0f, 1.0f-0.0f, // (bottom - right) 0.0f, 1.0f-1.0f, // (top - left ) 1.0f, 1.0f-1.0f, // (top - right) TRIANGLE 2 1.0f, 1.0f-0.0f, // (bottom - right) 0.0f, 1.0f-1.0f, // (top - left ) }; // Identify our vertex buffer GLuint vertexbuffer; glGenBuffers(1, &vertexbuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW); // Identify our color buffer GLuint colorbuffer; glGenBuffers(1, &colorbuffer); glBindBuffer(GL_ARRAY_BUFFER, colorbuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(g_uv_buffer_data), g_uv_buffer_data, GL_STATIC_DRAW); tex1 = LoadTexture("../img/tests/flieger.jpg",&textw,&texth); printf("Tex1: %d", tex1); tex2 = LoadTexture("../img/tests/flieger2.jpg",&textw2,&texth2); printf("Tex2: %d", tex2); glfwSetWindowSize(window, textw, texth); glViewport(0, 0, textw, texth); glfwSetWindowSizeLimits(window, textw, texth, textw, texth); GLuint programID = LoadShaders("trimap.vertexshader", "trimap.fragmentshader"); GLint textureLoc1 = glGetUniformLocation(programID, "myTextureSampler"); GLint textureLoc2 = glGetUniformLocation(programID, "myTextureSampler2"); GLint widthLoc = glGetUniformLocation(programID, "pixWidth"); GLint heigthLoc = glGetUniformLocation(programID, "pixHeight"); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex1); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, tex2); printf("Shader program ID: %d\n", programID); printf("textureLoc1: %d\n", textureLoc1); printf("textureLoc2: %d\n", textureLoc2); printf("widthLoc: %d\n", widthLoc); printf("heigthLoc: %d\n", heigthLoc); printf("Width: %f\n", 1.0f/textw); printf("Height: %f\n", 1.0f/texth); // INIT END /* Loop until the user closes the window */ while (!glfwWindowShouldClose(window)) { /* Render here */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(programID); glUniform1f(widthLoc, 1.0f/textw); glUniform1f(heigthLoc, 1.0f/texth); glUniform1i(textureLoc1, 0); glUniform1i(textureLoc2, 1); // 1rst attribute buffer : vertices glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); glVertexAttribPointer( 0, // attribute 0. No particular reason for 0, but must match the layout in the shader. 3, // size GL_FLOAT, // type GL_FALSE, // normalized? 0, // stride (void*)0 // array buffer offset ); // 2nd attribute buffer : colors glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, colorbuffer); glVertexAttribPointer( 1, // attribute. No particular reason for 1, but must match the layout in the shader. 2, // size GL_FLOAT, // type GL_FALSE, // normalized? 0, // stride (void*)0 // array buffer offset ); // Draw the triangle ! glDrawArrays(GL_TRIANGLES, 0, 2*3); // 2*3 indices starting at 0 -> 2 triangles -> 1 square glDisableVertexAttribArray(0); // RENDER END /* Swap front and back buffers */ glfwSwapBuffers(window); /* Poll for and process events */ glfwPollEvents(); } glfwTerminate(); return 0; }