void Texture :: buildMipmaps () { glTexParameteri ( target, GL_TEXTURE_BASE_LEVEL, 0 ); glTexParameteri ( target, GL_GENERATE_MIPMAP, GL_TRUE ); glGenerateMipmap ( target ); // should be bound }
static void se_loadTextureImage(JNIEnv* env, jobject clazz, jstring imageKey, jobject jbitmap) { const char* imagePath = env->GetStringUTFChars(imageKey, NULL); SE_ResourceManager *resourceManager = SE_Application::getInstance()->getResourceManager(); SE_ImageData* existdata = resourceManager->getImageDataFromPath(imagePath); if (existdata && !existdata->getData()) { GLuint texid = existdata->getTexID(); if (texid != 0) { glDeleteTextures(1, &texid); } existdata->setTexID(0); AndroidBitmapInfo bitmapInfo; int ret; void* pixels; if ((ret = AndroidBitmap_getInfo(env, jbitmap, &bitmapInfo)) < 0) { LOGE("error: AndroidBitmap_getInfo() failed ! error = %d\n", ret); return; } if (bitmapInfo.format != ANDROID_BITMAP_FORMAT_RGB_565 && bitmapInfo.format != ANDROID_BITMAP_FORMAT_RGBA_8888 && bitmapInfo.format != ANDROID_BITMAP_FORMAT_RGBA_4444) { LOGE("error: Bitmap format is not supported\n"); return; } if ((ret = AndroidBitmap_lockPixels(env, jbitmap, &pixels)) < 0) { LOGE("error: AndroidBitmap_lockPixels() failed ! error = %d\n", ret); return; } GLint internalFormat = GL_RGB; GLenum format = GL_RGB; GLenum type = GL_UNSIGNED_BYTE; switch (bitmapInfo.format) { case ANDROID_BITMAP_FORMAT_RGB_565: type = GL_UNSIGNED_SHORT_5_6_5; break; case ANDROID_BITMAP_FORMAT_RGBA_8888: internalFormat = GL_RGBA; format = GL_RGBA; break; case ANDROID_BITMAP_FORMAT_RGBA_4444: internalFormat = GL_RGBA; format = GL_RGBA; type = GL_UNSIGNED_SHORT_4_4_4_4; break; default: return; break; } int width = bitmapInfo.width; int height = bitmapInfo.height; glPixelStorei(GL_UNPACK_ALIGNMENT,1); glActiveTexture(GL_TEXTURE0); glGenTextures(1, &texid); existdata->setTexID(texid); glBindTexture(GL_TEXTURE_2D, texid); glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, type, pixels); glGenerateMipmap (GL_TEXTURE_2D); GLint wraps, wrapt; if (SE_Util::isPower2(width) && SE_Util::isPower2(height)) { wraps = GL_REPEAT; } else { wraps = GL_CLAMP_TO_EDGE; } if (SE_Util::isPower2(width) && SE_Util::isPower2(height)) { wrapt = GL_REPEAT; } else { wrapt = GL_CLAMP_TO_EDGE; } GLint sampleMin, sampleMag; sampleMin = GL_LINEAR_MIPMAP_LINEAR; sampleMag = GL_LINEAR; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wraps); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapt); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, sampleMin); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, sampleMag); } env->ReleaseStringUTFChars(imageKey, imagePath); }
static void gl2_renderchain_render( gl_t *gl, void *chain_data, video_frame_info_t *video_info, uint64_t frame_count, const struct video_tex_info *tex_info, const struct video_tex_info *feedback_info) { int i; video_shader_ctx_coords_t coords; video_shader_ctx_params_t params; video_shader_ctx_info_t shader_info; gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; static GLfloat fbo_tex_coords[8] = {0.0f}; struct video_tex_info fbo_tex_info[GFX_MAX_SHADERS]; struct video_tex_info *fbo_info = NULL; const struct video_fbo_rect *prev_rect = NULL; GLfloat xamt = 0.0f; GLfloat yamt = 0.0f; unsigned mip_level = 0; unsigned fbo_tex_info_cnt = 0; unsigned width = video_info->width; unsigned height = video_info->height; /* Render the rest of our passes. */ gl->coords.tex_coord = fbo_tex_coords; /* Calculate viewports, texture coordinates etc, * and render all passes from FBOs, to another FBO. */ for (i = 1; i < chain->fbo_pass; i++) { video_shader_ctx_coords_t coords; video_shader_ctx_params_t params; const struct video_fbo_rect *rect = &gl->fbo_rect[i]; prev_rect = &gl->fbo_rect[i - 1]; fbo_info = &fbo_tex_info[i - 1]; xamt = (GLfloat)prev_rect->img_width / prev_rect->width; yamt = (GLfloat)prev_rect->img_height / prev_rect->height; set_texture_coords(fbo_tex_coords, xamt, yamt); fbo_info->tex = chain->fbo_texture[i - 1]; fbo_info->input_size[0] = prev_rect->img_width; fbo_info->input_size[1] = prev_rect->img_height; fbo_info->tex_size[0] = prev_rect->width; fbo_info->tex_size[1] = prev_rect->height; memcpy(fbo_info->coord, fbo_tex_coords, sizeof(fbo_tex_coords)); fbo_tex_info_cnt++; gl2_bind_fb(chain->fbo[i]); shader_info.data = gl; shader_info.idx = i + 1; shader_info.set_active = true; video_shader_driver_use(&shader_info); glBindTexture(GL_TEXTURE_2D, chain->fbo_texture[i - 1]); mip_level = i + 1; if (video_shader_driver_mipmap_input(&mip_level) && gl->have_mipmap) glGenerateMipmap(GL_TEXTURE_2D); glClear(GL_COLOR_BUFFER_BIT); /* Render to FBO with certain size. */ gl_set_viewport(gl, video_info, rect->img_width, rect->img_height, true, false); params.data = gl; params.width = prev_rect->img_width; params.height = prev_rect->img_height; params.tex_width = prev_rect->width; params.tex_height = prev_rect->height; params.out_width = gl->vp.width; params.out_height = gl->vp.height; params.frame_counter = (unsigned int)frame_count; params.info = tex_info; params.prev_info = gl->prev_info; params.feedback_info = feedback_info; params.fbo_info = fbo_tex_info; params.fbo_info_cnt = fbo_tex_info_cnt; video_shader_driver_set_parameters(¶ms); gl->coords.vertices = 4; coords.handle_data = NULL; coords.data = &gl->coords; video_driver_set_coords(&coords); video_info->cb_set_mvp(gl, video_info->shader_data, &gl->mvp); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } #if defined(GL_FRAMEBUFFER_SRGB) && !defined(HAVE_OPENGLES) if (chain->has_srgb_fbo) glDisable(GL_FRAMEBUFFER_SRGB); #endif /* Render our last FBO texture directly to screen. */ prev_rect = &gl->fbo_rect[chain->fbo_pass - 1]; xamt = (GLfloat)prev_rect->img_width / prev_rect->width; yamt = (GLfloat)prev_rect->img_height / prev_rect->height; set_texture_coords(fbo_tex_coords, xamt, yamt); /* Push final FBO to list. */ fbo_info = &fbo_tex_info[chain->fbo_pass - 1]; fbo_info->tex = chain->fbo_texture[chain->fbo_pass - 1]; fbo_info->input_size[0] = prev_rect->img_width; fbo_info->input_size[1] = prev_rect->img_height; fbo_info->tex_size[0] = prev_rect->width; fbo_info->tex_size[1] = prev_rect->height; memcpy(fbo_info->coord, fbo_tex_coords, sizeof(fbo_tex_coords)); fbo_tex_info_cnt++; /* Render our FBO texture to back buffer. */ gl2_renderchain_bind_backbuffer(gl, chain_data); shader_info.data = gl; shader_info.idx = chain->fbo_pass + 1; shader_info.set_active = true; video_shader_driver_use(&shader_info); glBindTexture(GL_TEXTURE_2D, chain->fbo_texture[chain->fbo_pass - 1]); mip_level = chain->fbo_pass + 1; if (video_shader_driver_mipmap_input(&mip_level) && gl->have_mipmap) glGenerateMipmap(GL_TEXTURE_2D); glClear(GL_COLOR_BUFFER_BIT); gl_set_viewport(gl, video_info, width, height, false, true); params.data = gl; params.width = prev_rect->img_width; params.height = prev_rect->img_height; params.tex_width = prev_rect->width; params.tex_height = prev_rect->height; params.out_width = gl->vp.width; params.out_height = gl->vp.height; params.frame_counter = (unsigned int)frame_count; params.info = tex_info; params.prev_info = gl->prev_info; params.feedback_info = feedback_info; params.fbo_info = fbo_tex_info; params.fbo_info_cnt = fbo_tex_info_cnt; video_shader_driver_set_parameters(¶ms); gl->coords.vertex = gl->vertex_ptr; gl->coords.vertices = 4; coords.handle_data = NULL; coords.data = &gl->coords; video_driver_set_coords(&coords); video_info->cb_set_mvp(gl, video_info->shader_data, &gl->mvp); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); gl->coords.tex_coord = gl->tex_info.coord; }
int main() { // INIT glfwSetErrorCallback( error_callback ); /* Initialize the library */ if ( !glfwInit() ) { return -1; } // must use exactly version 3 glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 ); glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 3 ); glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE ); glfwWindowHint( GLFW_RESIZABLE, GL_FALSE ); /* Create a windowed mode window and its OpenGL context */ window = glfwCreateWindow( WIDTH, HEIGHT, "Hello World", NULL, NULL ); if ( !window ) { glfwTerminate(); return -1; } glfwMakeContextCurrent( window ); glfwSetKeyCallback( window, key_callback ); //glfwSetCursorPosCallback(window, cursor_position_callback); glfwSetScrollCallback(window, scroll_callback); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); int count; //printf( "%s\n", glfwGetVideoModes( glfwGetPrimaryMonitor(), &count ) ); glewExperimental = GL_TRUE; if( glewInit() != GLEW_OK ) { fprintf( stderr, "glewInit() failed\n" ); } glViewport( 0, 0, WIDTH, HEIGHT ); glClearColor( 0.2f, 0.3f, 0.3f, 1.0f ); glEnable( GL_DEPTH_TEST ); // SHADER Shader shader( "./vertexShader.glsl", "./fragmentShader.glsl" ); // Set up vertex data (and buffer(s)) and attribute pointers GLfloat vertices[] = { -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, }; GLuint indices[] = { 0, 1, 2, 1, 2, 3, 1, 3, 5, 3, 5, 7, 4, 5, 7, 4, 6, 7, 0, 4, 6, 0, 2, 6, 2, 3, 7, 2, 6, 7, 0, 1, 5, 0, 4, 5 }; // vertex buffer object (VBO) // vertex array object (VAO) GLuint VAO, VBO, EBO; glGenVertexArrays( 1, &VAO ); glGenBuffers( 1, &VBO ); glGenBuffers( 1, &EBO ); // BIND the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s). glBindVertexArray( VAO ); glBindBuffer( GL_ARRAY_BUFFER, VBO ); glBufferData( GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, EBO ); glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW ); // void glVertexAttribPointer( GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * pointer); // the 0 for index comes from location = 0 in the vertex shader glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0 ); glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)) ); glEnableVertexAttribArray( 0 ); glEnableVertexAttribArray( 1 ); glBindVertexArray( 0 ); stbi_set_flip_vertically_on_load(1); // TEXTURE GLuint texture; glGenTextures(1, &texture); //printf( "texture: %d\n", texture ); glBindTexture(GL_TEXTURE_2D, texture); // All upcoming GL_TEXTURE_2D operations now have effect on our texture object // Set our texture parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture wrapping to GL_REPEAT glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture filtering glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Load, create texture and generate mipmaps int width, height, comp; unsigned char* image = stbi_load("./images/container.jpg", &width, &height, &comp, 3); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); glGenerateMipmap(GL_TEXTURE_2D); stbi_image_free(image); glBindTexture(GL_TEXTURE_2D, 0); GLuint texture1; glGenTextures(1, &texture1); //printf( "texture1: %d\n", texture1 ); glBindTexture(GL_TEXTURE_2D, texture1); // Set our texture parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture wrapping to GL_REPEAT glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture filtering glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Load, create texture and generate mipmaps image = stbi_load("./images/awesomeface.png", &width, &height, &comp, 3 ); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); glGenerateMipmap(GL_TEXTURE_2D); stbi_image_free(image); glBindTexture(GL_TEXTURE_2D, 0); glm::mat4 projection; projection = glm::perspective( 45.0f, (GLfloat)WIDTH/HEIGHT, 0.1f, 100.0f ); /* for( int y = 0; y < 4; ++y ) { for( int x = 0; x < 4; ++x ) { printf( "%f ", test[x][y] ); } printf("\n"); } */ // Game loop while( !glfwWindowShouldClose( window ) ) { //for( int iter = 1; iter; --iter ) { glfwPollEvents(); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glActiveTexture( GL_TEXTURE0 ); glBindTexture(GL_TEXTURE_2D, texture); glUniform1i( glGetUniformLocation(shader.Program, "texture"), 0 ); glActiveTexture( GL_TEXTURE1 ); glBindTexture(GL_TEXTURE_2D, texture1); glUniform1i( glGetUniformLocation(shader.Program, "texture1"), 1 ); glUseProgram( shader.Program ); glm::mat4 models[2]; models[0] = glm::translate( models[0], glm::vec3( 4.0f, 4.0f, -10.0f ) ); //models[1] = glm::translate( models[1], glm::vec3( -4.0f, -4.0f, -10.0f ) ); models[1] = glm::scale( models[1], glm::vec3( 50.0f, 50.0f, 50.0f ) ); updateCamera(); //glm::mat4 rotatedView = camera[1] * camera[0] * view; printf( "rotation x %f, y %f, z %f\n", rotation.x, rotation.y, rotation.z ); glm::mat4 rotatedView; rotatedView = glm::rotate( rotatedView, rotation.x, glm::vec3(1, 0, 0) ) ; rotatedView = glm::rotate( rotatedView, rotation.y, glm::vec3(0, 1, 0) ) ; rotatedView = glm::rotate( rotatedView, rotation.z, glm::vec3(0, 0, 1) ) ; rotatedView *= view; //view = glm::translate( view, position ); //glm::mat4 rotatedView; //projection = glm::rotate( projection, glm::radians(cameraOrientation[1]), glm::vec3(1.0f, 0.0f, 0.0f) ); //projection = glm::rotate( projection, glm::radians(cameraOrientation[0]), glm::vec3(0.0f, 1.0f, 0.0f) ); //projection = projection * (cameraPosition / 10.0f); glUniformMatrix4fv( glGetUniformLocation(shader.Program, "view" ), 1, GL_FALSE, glm::value_ptr(rotatedView) ); glUniformMatrix4fv( glGetUniformLocation(shader.Program, "projection" ), 1, GL_FALSE, glm::value_ptr(projection) ); for( int numBoxes = 0; numBoxes < 3; ++numBoxes ) { glUniformMatrix4fv( glGetUniformLocation(shader.Program, "model" ), 1, GL_FALSE, glm::value_ptr(models[numBoxes]) ); glBindVertexArray( VAO ); //glDrawArrays( GL_TRIANGLES, 0, 3 ); glDrawElements( GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0 ); glBindVertexArray( 0 ); } glfwSwapBuffers( window ); fps(); printf("\n"); } glDeleteVertexArrays( 1, &VAO ); glDeleteBuffers( 1, &VBO ); glfwDestroyWindow( window ); glfwTerminate(); return 0; }
// The MAIN function, from here we start the application and run the game loop int main() { // Init GLFW glfwInit( ); // Set all the required options for GLFW glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 ); glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 3 ); glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE ); glfwWindowHint( GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE ); glfwWindowHint( GLFW_RESIZABLE, GL_FALSE ); // Create a GLFWwindow object that we can use for GLFW's functions GLFWwindow *window = glfwCreateWindow( WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr ); int screenWidth, screenHeight; glfwGetFramebufferSize( window, &screenWidth, &screenHeight ); if ( nullptr == window ) { std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate( ); return EXIT_FAILURE; } glfwMakeContextCurrent( window ); // Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions glewExperimental = GL_TRUE; // Initialize GLEW to setup the OpenGL Function pointers if ( GLEW_OK != glewInit( ) ) { std::cout << "Failed to initialize GLEW" << std::endl; return EXIT_FAILURE; } // Define the viewport dimensions glViewport( 0, 0, screenWidth, screenHeight ); // Setup OpenGL options glEnable( GL_DEPTH_TEST ); // enable alpha support glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); // Build and compile our shader program Shader ourShader( "res/shaders/core.vs", "res/shaders/core.frag" ); // Set up vertex data (and buffer(s)) and attribute pointers // use with Orthographic Projection /* GLfloat vertices[] = { -0.5f * 500, -0.5f * 500, -0.5f * 500, 0.0f, 0.0f, 0.5f * 500, -0.5f * 500, -0.5f * 500, 1.0f, 0.0f, 0.5f * 500, 0.5f * 500, -0.5f * 500, 1.0f, 1.0f, 0.5f * 500, 0.5f * 500, -0.5f * 500, 1.0f, 1.0f, -0.5f * 500, 0.5f * 500, -0.5f * 500, 0.0f, 1.0f, -0.5f * 500, -0.5f * 500, -0.5f * 500, 0.0f, 0.0f, -0.5f * 500, -0.5f * 500, 0.5f * 500, 0.0f, 0.0f, 0.5f * 500, -0.5f * 500, 0.5f * 500, 1.0f, 0.0f, 0.5f * 500, 0.5f * 500, 0.5f * 500, 1.0f, 1.0f, 0.5f * 500, 0.5f * 500, 0.5f * 500, 1.0f, 1.0f, -0.5f * 500, 0.5f * 500, 0.5f * 500, 0.0f, 1.0f, -0.5f * 500, -0.5f * 500, 0.5f * 500, 0.0f, 0.0f, -0.5f * 500, 0.5f * 500, 0.5f * 500, 1.0f, 0.0f, -0.5f * 500, 0.5f * 500, -0.5f * 500, 1.0f, 1.0f, -0.5f * 500, -0.5f * 500, -0.5f * 500, 0.0f, 1.0f, -0.5f * 500, -0.5f * 500, -0.5f * 500, 0.0f, 1.0f, -0.5f * 500, -0.5f * 500, 0.5f * 500, 0.0f, 0.0f, -0.5f * 500, 0.5f * 500, 0.5f * 500, 1.0f, 0.0f, 0.5f * 500, 0.5f * 500, 0.5f * 500, 1.0f, 0.0f, 0.5f * 500, 0.5f * 500, -0.5f * 500, 1.0f, 1.0f, 0.5f * 500, -0.5f * 500, -0.5f * 500, 0.0f, 1.0f, 0.5f * 500, -0.5f * 500, -0.5f * 500, 0.0f, 1.0f, 0.5f * 500, -0.5f * 500, 0.5f * 500, 0.0f, 0.0f, 0.5f * 500, 0.5f * 500, 0.5f * 500, 1.0f, 0.0f, -0.5f * 500, -0.5f * 500, -0.5f * 500, 0.0f, 1.0f, 0.5f * 500, -0.5f * 500, -0.5f * 500, 1.0f, 1.0f, 0.5f * 500, -0.5f * 500, 0.5f * 500, 1.0f, 0.0f, 0.5f * 500, -0.5f * 500, 0.5f * 500, 1.0f, 0.0f, -0.5f * 500, -0.5f * 500, 0.5f * 500, 0.0f, 0.0f, -0.5f * 500, -0.5f * 500, -0.5f * 500, 0.0f, 1.0f, -0.5f * 500, 0.5f * 500, -0.5f * 500, 0.0f, 1.0f, 0.5f * 500, 0.5f * 500, -0.5f * 500, 1.0f, 1.0f, 0.5f * 500, 0.5f * 500, 0.5f * 500, 1.0f, 0.0f, 0.5f * 500, 0.5f * 500, 0.5f * 500, 1.0f, 0.0f, -0.5f * 500, 0.5f * 500, 0.5f * 500, 0.0f, 0.0f, -0.5f * 500, 0.5f * 500, -0.5f * 500, 0.0f, 1.0f }; */ // use with Perspective Projection GLfloat vertices[] = { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f }; GLuint VBO, VAO; glGenVertexArrays( 1, &VAO ); glGenBuffers( 1, &VBO ); glBindVertexArray(VAO); glBindBuffer( GL_ARRAY_BUFFER, VBO ); glBufferData( GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW ); // Position attribute glVertexAttribPointer( 0, 3, GL_FLOAT , GL_FALSE, 5 * sizeof( GLfloat ), ( GLvoid * )0 ); glEnableVertexAttribArray( 0 ); // TexCoord attribute glVertexAttribPointer( 2, 2, GL_FLOAT, GL_FALSE, 5 * sizeof( GLfloat ), ( GLvoid * )( 3 * sizeof( GLfloat ) ) ); glEnableVertexAttribArray( 2 ); glBindVertexArray( 0 ); // Unbind VAO // Load and create a texture GLuint texture; // ==================== // Texture // ==================== glGenTextures( 1, &texture ); glBindTexture( GL_TEXTURE_2D, texture ); // All upcoming GL_TEXTURE_2D operations now have effect on our texture object // Set our texture parameters glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); // Set texture wrapping to GL_REPEAT glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); // Set texture filtering glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); // Load, create texture and generate mipmaps int width, height; unsigned char *image = SOIL_load_image( "res/images/image1.jpg", &width, &height, 0, SOIL_LOAD_RGBA ); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image ); glGenerateMipmap( GL_TEXTURE_2D ); SOIL_free_image_data( image ); glBindTexture( GL_TEXTURE_2D, 0 ); // Unbind texture when done, so we won't accidentily mess up our texture. glm::mat4 projection; projection = glm::perspective( 45.0f, ( GLfloat )screenWidth / ( GLfloat )screenHeight, 0.1f, 100.0f ); //projection = glm::ortho(0.0f, ( GLfloat )screenWidth, 0.0f, ( GLfloat )screenHeight, 0.1f, 1000.0f); // Game loop while ( !glfwWindowShouldClose( window ) ) { // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions glfwPollEvents( ); // Render // Clear the colorbuffer glClearColor( 0.2f, 0.3f, 0.3f, 1.0f ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // Bind Textures using texture units glActiveTexture( GL_TEXTURE0 ); glBindTexture( GL_TEXTURE_2D, texture ); glUniform1i(glGetUniformLocation( ourShader.Program, "ourTexture1" ), 0 ); // Activate shader ourShader.Use( ); // Create transformations glm::mat4 model; glm::mat4 view; model = glm::rotate( model, ( GLfloat)glfwGetTime( ) * 1.0f, glm::vec3( 0.5f, 1.0f, 0.0f ) ); // use with perspective projection //model = glm::rotate( model, 0.5f, glm::vec3( 1.0f, 0.0f, 0.0f ) ); // use to compare orthographic and perspective projection //view = glm::translate( view, glm::vec3( screenWidth / 2, screenHeight / 2, -700.0f ) ); // use with orthographic projection view = glm::translate( view, glm::vec3( 0.0f, 0.0f, -3.0f ) ); // use with perspective projection // Get their uniform location GLint modelLoc = glGetUniformLocation( ourShader.Program, "model" ); GLint viewLoc = glGetUniformLocation( ourShader.Program, "view" ); GLint projLoc = glGetUniformLocation( ourShader.Program, "projection" ); // Pass them to the shaders glUniformMatrix4fv( modelLoc, 1, GL_FALSE, glm::value_ptr( model ) ); glUniformMatrix4fv( viewLoc, 1, GL_FALSE, glm::value_ptr( view ) ); glUniformMatrix4fv( projLoc, 1, GL_FALSE, glm::value_ptr( projection ) ); // Draw container glBindVertexArray( VAO ); glDrawArrays( GL_TRIANGLES, 0, 36 ); glBindVertexArray( 0 ); // Swap the screen buffers glfwSwapBuffers( window ); } // Properly de-allocate all resources once they've outlived their purpose glDeleteVertexArrays( 1, &VAO ); glDeleteBuffers( 1, &VBO ); // Terminate GLFW, clearing any resources allocated by GLFW. glfwTerminate( ); return EXIT_SUCCESS; }
bool LoadImg( const char *img_path_file, GLuint &image ){ ILenum error; GLenum error_gl; ILboolean success; ILuint imgage_id; /* Tworzy identyfikator dla wczytywanej grafiki. */ ilGenImages( 1, &imgage_id ); /* Przygotowywuje dla wczytywania grafiki. */ ilBindImage( imgage_id ); /* Załadowanie pliku grafiki o nazwie img_path_file do pamięci. */ success = ilLoadImage( img_path_file ); /* Sprawdzenie3 czy jest błąd. */ if( ! success ){ /* Otrzymanie numeru błędu. */ error = ilGetError(); /* Sprawdzenie czy ten kod jest błędem. */ if( error != IL_NO_ERROR ){ /* Wyświetl bład. */ cout<<"ilLoadImage ("<<img_path_file<<"): "<<iluErrorString( error )<<"\n"; image = 0; /* Usuń z pamięci. */ ilDeleteImages( 1, &imgage_id ); return false; } /* Gdyby były błedy z wczytanie a kod błedu na to nie wskazywał. */ cout<<"ilLoadImage ("<<img_path_file<<"): "<<ilGetError()<<"\n"; image = 0; /* Usuń z pamięci. */ ilDeleteImages( 1, &imgage_id ); return false; } /* Szerokość obrazka */ GLint width = ilGetInteger( IL_IMAGE_WIDTH ); /* Wysokość obrazka */ GLint height = ilGetInteger( IL_IMAGE_HEIGHT ); /* Typ obrazka (np. RGB lub RGBA). */ GLint type = ilGetInteger( IL_IMAGE_TYPE ); /* Specyfikacja pikseli (jak są reprezentowane, np. unsigned int). */ GLint format = ilGetInteger( IL_IMAGE_FORMAT ); /* Tworzy identyfikator tekstury */ glGenTextures( 1, &image ); /* Do wcześniej stworzonego identyfikatora stwórz teksturę 2D */ glBindTexture( GL_TEXTURE_2D, image ); /* Kopiuje grafikę z DevIL do OpenGL. ilGetData() - przekazanie całego obrazka (danych), który jest aktualnie przetwarzany. */ glTexImage2D( GL_TEXTURE_2D, 0, format, width, height, 0, format, type, ilGetData() ); /* Sprawdzenie czy nie ma błedu. */ error_gl = glGetError(); if( error_gl != GL_NO_ERROR and error_gl != GL_INVALID_ENUM ){ cout<<"glTexImage2D ("<<img_path_file<<"): "<<gluErrorString( error_gl )<<"\n"; return false; } /* Tworzenie automatycznej Mipmapy, im dalej tym gorsza tekstura. */ glGenerateMipmap( GL_TEXTURE_2D ); /* Typ powtarzania obrazka, gdy się skończy dana tekstura. */ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); /* Jak ma być skalowana tekstura. Typ skalowania. */ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); /* Czyszczenie. */ glBindTexture(GL_TEXTURE_2D, 0); /* Usunięcie z pamięci obrazka w DevIL. */ ilDeleteImages( 1, &imgage_id ); return true; }
// The MAIN function, from here we start the application and run the game loop int main() { // Init GLFW glfwInit(); // Set all the required options for GLFW glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Create a GLFWwindow object that we can use for GLFW's functions GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr); glfwMakeContextCurrent(window); // Set the required callback functions glfwSetKeyCallback(window, key_callback); glfwSetCursorPosCallback(window, mouse_callback); glfwSetScrollCallback(window, scroll_callback); // GLFW Options glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); // Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions glewExperimental = GL_TRUE; // Initialize GLEW to setup the OpenGL Function pointers glewInit(); // Define the viewport dimensions glViewport(0, 0, WIDTH, HEIGHT); // OpenGL options glEnable(GL_DEPTH_TEST); // Build and compile our shader program Shader lightingShader("light_casters.vs", "light_casters.frag"); Shader lampShader("lamp.vs", "lamp.frag"); // Set up vertex data (and buffer(s)) and attribute pointers GLfloat vertices[] = { // Positions // Normals // Texture Coords -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f }; // Positions all containers glm::vec3 cubePositions[] = { glm::vec3( 0.0f, 0.0f, 0.0f), glm::vec3( 2.0f, 5.0f, -15.0f), glm::vec3(-1.5f, -2.2f, -2.5f), glm::vec3(-3.8f, -2.0f, -12.3f), glm::vec3( 2.4f, -0.4f, -3.5f), glm::vec3(-1.7f, 3.0f, -7.5f), glm::vec3( 1.3f, -2.0f, -2.5f), glm::vec3( 1.5f, 2.0f, -2.5f), glm::vec3( 1.5f, 0.2f, -1.5f), glm::vec3(-1.3f, 1.0f, -1.5f) }; // First, set the container's VAO (and VBO) GLuint VBO, containerVAO; glGenVertexArrays(1, &containerVAO); glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindVertexArray(containerVAO); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(1); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat))); glEnableVertexAttribArray(2); glBindVertexArray(0); // Then, we set the light's VAO (VBO stays the same. After all, the vertices are the same for the light object (also a 3D cube)) GLuint lightVAO; glGenVertexArrays(1, &lightVAO); glBindVertexArray(lightVAO); // We only need to bind to the VBO (to link it with glVertexAttribPointer), no need to fill it; the VBO's data already contains all we need. glBindBuffer(GL_ARRAY_BUFFER, VBO); // Set the vertex attributes (only position data for the lamp)) glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0); // Note that we skip over the other data in our buffer object (we don't need the normals/textures, only positions). glEnableVertexAttribArray(0); glBindVertexArray(0); // Load textures GLuint diffuseMap, specularMap, emissionMap; glGenTextures(1, &diffuseMap); glGenTextures(1, &specularMap); glGenTextures(1, &emissionMap); int width, height; unsigned char* image; // Diffuse map image = SOIL_load_image(FileSystem::getPath("resources/textures/container2.png").c_str(), &width, &height, 0, SOIL_LOAD_RGB); glBindTexture(GL_TEXTURE_2D, diffuseMap); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); glGenerateMipmap(GL_TEXTURE_2D); SOIL_free_image_data(image); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST); // Specular map image = SOIL_load_image(FileSystem::getPath("resources/textures/container2_specular.png").c_str(), &width, &height, 0, SOIL_LOAD_RGB); glBindTexture(GL_TEXTURE_2D, specularMap); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); glGenerateMipmap(GL_TEXTURE_2D); SOIL_free_image_data(image); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST); glBindTexture(GL_TEXTURE_2D, 0); // Set texture units lightingShader.Use(); glUniform1i(glGetUniformLocation(lightingShader.Program, "material.diffuse"), 0); glUniform1i(glGetUniformLocation(lightingShader.Program, "material.specular"), 1); // Game loop while (!glfwWindowShouldClose(window)) { // Calculate deltatime of current frame GLfloat currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions glfwPollEvents(); do_movement(); // Clear the colorbuffer glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Use cooresponding shader when setting uniforms/drawing objects lightingShader.Use(); GLint lightPosLoc = glGetUniformLocation(lightingShader.Program, "light.position"); GLint lightSpotdirLoc = glGetUniformLocation(lightingShader.Program, "light.direction"); GLint lightSpotCutOffLoc = glGetUniformLocation(lightingShader.Program, "light.cutOff"); GLint lightSpotOuterCutOffLoc = glGetUniformLocation(lightingShader.Program, "light.outerCutOff"); GLint viewPosLoc = glGetUniformLocation(lightingShader.Program, "viewPos"); glUniform3f(lightPosLoc, camera.Position.x, camera.Position.y, camera.Position.z); glUniform3f(lightSpotdirLoc, camera.Front.x, camera.Front.y, camera.Front.z); glUniform1f(lightSpotCutOffLoc, glm::cos(glm::radians(12.5f))); glUniform1f(lightSpotOuterCutOffLoc, glm::cos(glm::radians(17.5f))); glUniform3f(viewPosLoc, camera.Position.x, camera.Position.y, camera.Position.z); // Set lights properties glUniform3f(glGetUniformLocation(lightingShader.Program, "light.ambient"), 0.1f, 0.1f, 0.1f); // We set the diffuse intensity a bit higher; note that the right lighting conditions differ with each lighting method and environment. // Each environment and lighting type requires some tweaking of these variables to get the best out of your environment. glUniform3f(glGetUniformLocation(lightingShader.Program, "light.diffuse"), 0.8f, 0.8f, 0.8f); glUniform3f(glGetUniformLocation(lightingShader.Program, "light.specular"), 1.0f, 1.0f, 1.0f); glUniform1f(glGetUniformLocation(lightingShader.Program, "light.constant"), 1.0f); glUniform1f(glGetUniformLocation(lightingShader.Program, "light.linear"), 0.09); glUniform1f(glGetUniformLocation(lightingShader.Program, "light.quadratic"), 0.032); // Set material properties glUniform1f(glGetUniformLocation(lightingShader.Program, "material.shininess"), 32.0f); // Create camera transformations glm::mat4 view; view = camera.GetViewMatrix(); glm::mat4 projection = glm::perspective(camera.Zoom, (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 100.0f); // Get the uniform locations GLint modelLoc = glGetUniformLocation(lightingShader.Program, "model"); GLint viewLoc = glGetUniformLocation(lightingShader.Program, "view"); GLint projLoc = glGetUniformLocation(lightingShader.Program, "projection"); // Pass the matrices to the shader glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection)); // Bind diffuse map glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, diffuseMap); // Bind specular map glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, specularMap); // Draw the container (using container's vertex attributes) /*glBindVertexArray(containerVAO); glm::mat4 model; glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); glDrawArrays(GL_TRIANGLES, 0, 36); glBindVertexArray(0);*/ // Draw 10 containers with the same VAO and VBO information; only their world space coordinates differ glm::mat4 model; glBindVertexArray(containerVAO); for (GLuint i = 0; i < 10; i++) { model = glm::mat4(); model = glm::translate(model, cubePositions[i]); GLfloat angle = 20.0f * i; model = glm::rotate(model, angle, glm::vec3(1.0f, 0.3f, 0.5f)); glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); glDrawArrays(GL_TRIANGLES, 0, 36); } glBindVertexArray(0); // Again, no need to draw the lamp object // Also draw the lamp object, again binding the appropriate shader //lampShader.Use(); //// Get location objects for the matrices on the lamp shader (these could be different on a different shader) //modelLoc = glGetUniformLocation(lampShader.Program, "model"); //viewLoc = glGetUniformLocation(lampShader.Program, "view"); //projLoc = glGetUniformLocation(lampShader.Program, "projection"); //// Set matrices //glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); //glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection)); //model = glm::mat4(); //model = glm::translate(model, lightPos); //model = glm::scale(model, glm::vec3(0.2f)); // Make it a smaller cube //glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); //// Draw the light object (using light's vertex attributes) //glBindVertexArray(lightVAO); //glDrawArrays(GL_TRIANGLES, 0, 36); //glBindVertexArray(0); // Swap the screen buffers glfwSwapBuffers(window); } // Terminate GLFW, clearing any resources allocated by GLFW. glfwTerminate(); return 0; }
void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, QGLFramebufferObject::Attachment attachment, GLenum texture_target, GLenum internal_format, GLint samples, bool mipmap) { QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext()); fbo_guard.setContext(ctx); bool ext_detected = (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject); if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(ctx))) return; size = sz; target = texture_target; // texture dimensions QT_RESET_GLERROR(); // reset error state GLuint fbo = 0; glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo); fbo_guard.setId(fbo); glDevice.setFBO(q, attachment); QT_CHECK_GLERROR(); // init texture if (samples == 0) { glGenTextures(1, &texture); glBindTexture(target, texture); glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); if (mipmap) glGenerateMipmap(GL_TEXTURE_2D); #ifndef QT_OPENGL_ES glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); #else glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); #endif glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, texture, 0); QT_CHECK_GLERROR(); valid = checkFramebufferStatus(); glBindTexture(target, 0); color_buffer = 0; } else { mipmap = false; GLint maxSamples; glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples); samples = qBound(0, int(samples), int(maxSamples)); glGenRenderbuffers(1, &color_buffer); glBindRenderbuffer(GL_RENDERBUFFER_EXT, color_buffer); if (glRenderbufferStorageMultisampleEXT && samples > 0) { glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, internal_format, size.width(), size.height()); } else { samples = 0; glRenderbufferStorage(GL_RENDERBUFFER_EXT, internal_format, size.width(), size.height()); } glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, color_buffer); QT_CHECK_GLERROR(); valid = checkFramebufferStatus(); if (valid) glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_SAMPLES_EXT, &samples); } // In practice, a combined depth-stencil buffer is supported by all desktop platforms, while a // separate stencil buffer is not. On embedded devices however, a combined depth-stencil buffer // might not be supported while separate buffers are, according to QTBUG-12861. if (attachment == QGLFramebufferObject::CombinedDepthStencil && (QGLExtensions::glExtensions() & QGLExtensions::PackedDepthStencil)) { // depth and stencil buffer needs another extension glGenRenderbuffers(1, &depth_buffer); Q_ASSERT(!glIsRenderbuffer(depth_buffer)); glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_buffer); Q_ASSERT(glIsRenderbuffer(depth_buffer)); if (samples != 0 && glRenderbufferStorageMultisampleEXT) glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_DEPTH24_STENCIL8_EXT, size.width(), size.height()); else glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, size.width(), size.height()); stencil_buffer = depth_buffer; glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_buffer); glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, stencil_buffer); valid = checkFramebufferStatus(); if (!valid) { glDeleteRenderbuffers(1, &depth_buffer); stencil_buffer = depth_buffer = 0; } } if (depth_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil || (attachment == QGLFramebufferObject::Depth))) { glGenRenderbuffers(1, &depth_buffer); Q_ASSERT(!glIsRenderbuffer(depth_buffer)); glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_buffer); Q_ASSERT(glIsRenderbuffer(depth_buffer)); if (samples != 0 && glRenderbufferStorageMultisampleEXT) { #ifdef QT_OPENGL_ES if (QGLExtensions::glExtensions() & QGLExtensions::Depth24) { glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_DEPTH_COMPONENT24_OES, size.width(), size.height()); } else { glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_DEPTH_COMPONENT16, size.width(), size.height()); } #else glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_DEPTH_COMPONENT, size.width(), size.height()); #endif } else { #ifdef QT_OPENGL_ES if (QGLExtensions::glExtensions() & QGLExtensions::Depth24) { glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24_OES, size.width(), size.height()); } else { glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, size.width(), size.height()); } #else glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, size.width(), size.height()); #endif } glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_buffer); valid = checkFramebufferStatus(); if (!valid) { glDeleteRenderbuffers(1, &depth_buffer); depth_buffer = 0; } } if (stencil_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil)) { glGenRenderbuffers(1, &stencil_buffer); Q_ASSERT(!glIsRenderbuffer(stencil_buffer)); glBindRenderbuffer(GL_RENDERBUFFER_EXT, stencil_buffer); Q_ASSERT(glIsRenderbuffer(stencil_buffer)); if (samples != 0 && glRenderbufferStorageMultisampleEXT) { #ifdef QT_OPENGL_ES glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_STENCIL_INDEX8_EXT, size.width(), size.height()); #else glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_STENCIL_INDEX, size.width(), size.height()); #endif } else { #ifdef QT_OPENGL_ES glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT, size.width(), size.height()); #else glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX, size.width(), size.height()); #endif } glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, stencil_buffer); valid = checkFramebufferStatus(); if (!valid) { glDeleteRenderbuffers(1, &stencil_buffer); stencil_buffer = 0; } } // The FBO might have become valid after removing the depth or stencil buffer. valid = checkFramebufferStatus(); if (depth_buffer && stencil_buffer) { fbo_attachment = QGLFramebufferObject::CombinedDepthStencil; } else if (depth_buffer) { fbo_attachment = QGLFramebufferObject::Depth; } else { fbo_attachment = QGLFramebufferObject::NoAttachment; } glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo); if (!valid) { if (color_buffer) glDeleteRenderbuffers(1, &color_buffer); else glDeleteTextures(1, &texture); if (depth_buffer) glDeleteRenderbuffers(1, &depth_buffer); if (stencil_buffer && depth_buffer != stencil_buffer) glDeleteRenderbuffers(1, &stencil_buffer); glDeleteFramebuffers(1, &fbo); fbo_guard.setId(0); } QT_CHECK_GLERROR(); format.setTextureTarget(target); format.setSamples(int(samples)); format.setAttachment(fbo_attachment); format.setInternalTextureFormat(internal_format); format.setMipmap(mipmap); }
// to do: remove example image GLuint MyTexture::LoadBMP(const char * file_path) { // Data read from the header of a BMP file unsigned char header[54]; unsigned int dataPos; unsigned int imageSize; unsigned int width; unsigned int height; // RGB data unsigned char * image_data; FILE * file = fopen(file_path, "rb"); if (!file) { std::cout << "cannot open file " << file_path << "\n"; return 0; } // The header should be 54 bytes if (fread(header, 1, 54, file) != 54) { std::cout << "Wrong BMP\n"; return 0; } // A BMP files always begins with "BM" if (header[0] != 'B' || header[1] != 'M') { std::cout << "Wrong BMP\n"; return 0; } // Make sure this is a 24bpp file if (*(int*)&(header[0x1E]) != 0) { std::cout << "Wrong BMP\n"; return 0; } if (*(int*)&(header[0x1C]) != 24) { std::cout << "Wrong BMP\n"; return 0; } // Read the information about the image dataPos = *(int*)&(header[0x0A]); imageSize = *(int*)&(header[0x22]); width = *(int*)&(header[0x12]); height = *(int*)&(header[0x16]); // Some BMP files are misformatted, guess missing information if (imageSize == 0) { imageSize = width*height * 3; } // 3 : one byte for each Red, Green and Blue component if (dataPos == 0) { dataPos = 54; } // The BMP header is done that way image_data = new unsigned char[imageSize]; // Create a buffer fread(image_data, 1, imageSize, file); // Read and put to the buffer fclose(file); // Close the image // Create a OpenGL texture GLuint textureID; glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_2D, textureID); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, image_data); delete[] image_data; //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // nice trilinear filtering. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glGenerateMipmap(GL_TEXTURE_2D); std::cout << "Image " << file_path << " is loaded\n"; return textureID; }
void RaycastingProcessor::updateResult(DataContainer& data) { ImageRepresentationGL::ScopedRepresentation img(data, p_sourceImageID.getValue()); ScopedTypedData<RenderData> entryPoints(data, p_entryImageID.getValue()); ScopedTypedData<RenderData> exitPoints(data, p_exitImageID.getValue()); ScopedTypedData<CameraData> camera(data, p_camera.getValue()); if (img != nullptr && entryPoints != nullptr && exitPoints != nullptr && camera != nullptr) { if (img->getDimensionality() == 3) { // little hack to support LOD texture lookup for the gradients: // if texture does not yet have mipmaps, create them. const cgt::Texture* tex = img->getTexture(); if (tex->getFilter() != cgt::Texture::MIPMAP) { const_cast<cgt::Texture*>(tex)->setFilter(cgt::Texture::MIPMAP); glGenerateMipmap(GL_TEXTURE_3D); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); LGL_ERROR; } _shader->activate(); _shader->setIgnoreUniformLocationError(true); // Compute min/max depth if needed by shader if (_shader->getUniformLocation("_minDepth") != -1) { _shader->deactivate(); float minDepth = _minReduction->reduce(entryPoints->getDepthTexture()).front(); _shader->activate(); _shader->setUniform("_minDepth", minDepth); } if (_shader->getUniformLocation("_maxDepth") != -1) { _shader->deactivate(); float maxDepth = _maxReduction->reduce(exitPoints->getDepthTexture()).front(); _shader->activate(); _shader->setUniform("_maxDepth", maxDepth); } decorateRenderProlog(data, _shader); _shader->setUniform("_viewportSizeRCP", 1.f / cgt::vec2(getEffectiveViewportSize())); _shader->setUniform("_jitterStepSizeMultiplier", p_jitterStepSizeMultiplier.getValue()); // compute sampling step size relative to volume size float samplingStepSize = 1.f / (p_samplingRate.getValue() * cgt::max(img->getSize())); _shader->setUniform("_samplingStepSize", samplingStepSize); // compute and set camera parameters const cgt::Camera& cam = camera->getCamera(); float n = cam.getNearDist(); float f = cam.getFarDist(); _shader->setUniform("_cameraPosition", cam.getPosition()); _shader->setUniform("const_to_z_e_1", 0.5f + 0.5f*((f+n)/(f-n))); _shader->setUniform("const_to_z_e_2", ((f-n)/(f*n))); _shader->setUniform("const_to_z_w_1", ((f*n)/(f-n))); _shader->setUniform("const_to_z_w_2", 0.5f*((f+n)/(f-n))+0.5f); _shader->setIgnoreUniformLocationError(false); // bind input textures cgt::TextureUnit volumeUnit, entryUnit, exitUnit, tfUnit; img->bind(_shader, volumeUnit, "_volume", "_volumeTextureParams"); p_transferFunction.getTF()->bind(_shader, tfUnit); if (! _bindEntryExitDepthTextures) { entryPoints->bindColorTexture(_shader, entryUnit, "_entryPoints", "_entryParams"); exitPoints->bindColorTexture(_shader, exitUnit, "_exitPoints", "_exitParams"); processImpl(data, img); } else { cgt::TextureUnit entryUnitDepth, exitUnitDepth; entryPoints->bind(_shader, entryUnit, entryUnitDepth, "_entryPoints", "_entryPointsDepth", "_entryParams"); exitPoints->bind(_shader, exitUnit, exitUnitDepth, "_exitPoints", "_exitPointsDepth", "_exitParams"); processImpl(data, img); } decorateRenderEpilog(_shader); _shader->deactivate(); cgt::TextureUnit::setZeroUnit(); LGL_ERROR; } else { LERROR("Input image must have dimensionality of 3."); } } else { LDEBUG("No suitable input image found."); } }
/** * Method is used to build texture mipmapis for mipmapping technique. * @param target is texture type. */ void FrameBufferObject::buildMipmaps(GLenum target) const { glBindTexture(target, getColorBuffer()); glGenerateMipmap(target); }
void displayCB() { // get the total elapsed time playTime = (float)timer.getElapsedTime(); // compute rotation angle const float ANGLE_SPEED = 10; // degree/s float angle = ANGLE_SPEED * playTime; // render to texture ////////////////////////////////////////////////////// t1.start(); // adjust viewport and projection matrix to texture dimension glViewport(0, 0, TEXTURE_WIDTH, TEXTURE_HEIGHT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0f, (float)(TEXTURE_WIDTH)/TEXTURE_HEIGHT, 1.0f, 100.0f); glMatrixMode(GL_MODELVIEW); // camera transform glLoadIdentity(); glTranslatef(0, 0, -CAMERA_DISTANCE); // with MSAA // render to MSAA FBO if(msaaUsed) { // set the rendering destination to FBO glBindFramebuffer(GL_FRAMEBUFFER, fboMsaaId); // clear buffer glClearColor(1, 1, 1, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // draw a rotating object at the origin glPushMatrix(); glRotatef(angle*0.5f, 1, 0, 0); glRotatef(angle, 0, 1, 0); glRotatef(angle*0.7f, 0, 0, 1); glTranslatef(0, -1.575f, 0); drawTeapot(); glPopMatrix(); // copy rendered image from MSAA (multi-sample) to normal (single-sample) FBO // NOTE: The multi samples at a pixel in read buffer will be converted // to a single sample at the target pixel in draw buffer. glBindFramebuffer(GL_READ_FRAMEBUFFER, fboMsaaId); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboId); glBlitFramebuffer(0, 0, TEXTURE_WIDTH, TEXTURE_HEIGHT, // src rect 0, 0, TEXTURE_WIDTH, TEXTURE_HEIGHT, // dst rect GL_COLOR_BUFFER_BIT, // buffer mask GL_LINEAR); // scale filter // trigger mipmaps generation explicitly // NOTE: If GL_GENERATE_MIPMAP is set to GL_TRUE, then glCopyTexSubImage2D() // triggers mipmap generation automatically. However, the texture attached // onto a FBO should generate mipmaps manually via glGenerateMipmap(). glBindTexture(GL_TEXTURE_2D, textureId); glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); // back to normal window-system-provided framebuffer glBindFramebuffer(GL_FRAMEBUFFER, 0); // unbind } // without MSAA // render to non MSAA FBO else { // set the rendering destination to FBO glBindFramebuffer(GL_FRAMEBUFFER, fboId); // clear buffer glClearColor(1, 1, 1, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // draw a rotating object at the origin glPushMatrix(); glRotatef(angle*0.5f, 1, 0, 0); glRotatef(angle, 0, 1, 0); glRotatef(angle*0.7f, 0, 0, 1); glTranslatef(0, -1.575f, 0); drawTeapot(); glPopMatrix(); // trigger mipmaps generation explicitly // NOTE: If GL_GENERATE_MIPMAP is set to GL_TRUE, then glCopyTexSubImage2D() // triggers mipmap generation automatically. However, the texture attached // onto a FBO should generate mipmaps manually via glGenerateMipmap(). glBindTexture(GL_TEXTURE_2D, textureId); glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); // back to normal window-system-provided framebuffer glBindFramebuffer(GL_FRAMEBUFFER, 0); // unbind } // measure the elapsed time of render-to-texture t1.stop(); renderToTextureTime = t1.getElapsedTimeInMilliSec(); /////////////////////////////////////////////////////////////////////////// // rendering as normal //////////////////////////////////////////////////// // back to normal viewport and projection matrix toPerspective(); // tramsform camera glTranslatef(0, 0, -cameraDistance); glRotatef(cameraAngleX, 1, 0, 0); // pitch glRotatef(cameraAngleY, 0, 1, 0); // heading // clear framebuffer glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glPushMatrix(); // draw a cube with the dynamic texture draw(); glPopMatrix(); // draw info messages showInfo(); showFPS(); glutSwapBuffers(); }
void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool regenerate) { SkAutoLockPixels alp(*bitmap); if (!bitmap->readyToDraw()) { ALOGE("Cannot generate texture from bitmap"); return; } // We could also enable mipmapping if both bitmap dimensions are powers // of 2 but we'd have to deal with size changes. Let's keep this simple const bool canMipMap = Extensions::getInstance().hasNPot(); // If the texture had mipmap enabled but not anymore, // force a glTexImage2D to discard the mipmap levels const bool resize = !regenerate || bitmap->width() != int(texture->width) || bitmap->height() != int(texture->height) || (regenerate && canMipMap && texture->mipMap && !bitmap->hasHardwareMipMap()); if (!regenerate) { glGenTextures(1, &texture->id); } texture->generation = bitmap->getGenerationID(); texture->width = bitmap->width(); texture->height = bitmap->height(); Caches::getInstance().bindTexture(texture->id); switch (bitmap->getConfig()) { case SkBitmap::kA8_Config: glPixelStorei(GL_UNPACK_ALIGNMENT, 1); uploadToTexture(resize, GL_ALPHA, bitmap->rowBytesAsPixels(), texture->width, texture->height, GL_UNSIGNED_BYTE, bitmap->getPixels()); texture->blend = true; break; case SkBitmap::kRGB_565_Config: glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel()); uploadToTexture(resize, GL_RGB, bitmap->rowBytesAsPixels(), texture->width, texture->height, GL_UNSIGNED_SHORT_5_6_5, bitmap->getPixels()); texture->blend = false; break; case SkBitmap::kARGB_8888_Config: glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel()); uploadToTexture(resize, GL_RGBA, bitmap->rowBytesAsPixels(), texture->width, texture->height, GL_UNSIGNED_BYTE, bitmap->getPixels()); // Do this after calling getPixels() to make sure Skia's deferred // decoding happened texture->blend = !bitmap->isOpaque(); break; case SkBitmap::kARGB_4444_Config: case SkBitmap::kIndex8_Config: glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel()); uploadLoFiTexture(resize, bitmap, texture->width, texture->height); texture->blend = !bitmap->isOpaque(); break; default: ALOGW("Unsupported bitmap config: %d", bitmap->getConfig()); break; } if (canMipMap) { texture->mipMap = bitmap->hasHardwareMipMap(); if (texture->mipMap) { glGenerateMipmap(GL_TEXTURE_2D); } } if (!regenerate) { texture->setFilter(GL_NEAREST); texture->setWrap(GL_CLAMP_TO_EDGE); } }
GLuint loadBMP_custom(const char * imagepath){ printf("Reading image %s\n", imagepath); // Data read from the header of the BMP file unsigned char header[54]; unsigned int dataPos; unsigned int imageSize; unsigned int width, height; // Actual RGB data unsigned char * data; // Open the file FILE * file = fopen(imagepath,"rb"); if (!file) {printf("%s could not be opened. Are you in the right directory ? Don't forget to read the FAQ !\n", imagepath); getchar(); return 0;} // Read the header, i.e. the 54 first bytes // If less than 54 bytes are read, problem if ( fread(header, 1, 54, file)!=54 ){ printf("Not a correct BMP file\n"); return 0; } // A BMP files always begins with "BM" if ( header[0]!='B' || header[1]!='M' ){ printf("Not a correct BMP file\n"); return 0; } // Make sure this is a 24bpp file if ( *(int*)&(header[0x1E])!=0 ) {printf("Not a correct BMP file\n"); return 0;} if ( *(int*)&(header[0x1C])!=24 ) {printf("Not a correct BMP file\n"); return 0;} // Read the information about the image dataPos = *(int*)&(header[0x0A]); imageSize = *(int*)&(header[0x22]); width = *(int*)&(header[0x12]); height = *(int*)&(header[0x16]); // Some BMP files are misformatted, guess missing information if (imageSize==0) imageSize=width*height*3; // 3 : one byte for each Red, Green and Blue component if (dataPos==0) dataPos=54; // The BMP header is done that way // Create a buffer data = new unsigned char [imageSize]; // Read the actual data from the file into the buffer fread(data,1,imageSize,file); // Everything is in memory now, the file wan be closed fclose (file); // Create one OpenGL texture GLuint textureID; glGenTextures(1, &textureID); // "Bind" the newly created texture : all future texture functions will modify this texture glBindTexture(GL_TEXTURE_2D, textureID); // Give the image to OpenGL glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data); // OpenGL has now copied the data. Free our own version delete [] data; // Poor filtering, or ... //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // ... nice trilinear filtering. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glGenerateMipmap(GL_TEXTURE_2D); // Return the ID of the texture we just created return textureID; }
PIGLIT_GL_TEST_CONFIG_END /** * Test textures having integer or depth-stencil internalFormat with * glGenerateMipmap. GL_INVALID_OPERATION should be thrown by the * implementation. */ static bool test_genmipmap_errors(void) { GLuint tex; static const struct { GLenum intFormat, srcFormat, srcType; const char *extension[2]; } formats[] = { /* Integer internal formats */ { GL_RGBA8I_EXT, GL_RGBA_INTEGER, GL_INT, {"GL_EXT_texture_integer", NULL} }, { GL_RGBA16I_EXT, GL_RGBA_INTEGER, GL_INT, {"GL_EXT_texture_integer", NULL} }, { GL_RGBA32I_EXT, GL_RGBA_INTEGER, GL_INT, {"GL_EXT_texture_integer", NULL} }, { GL_RGB8I_EXT, GL_RGBA_INTEGER, GL_INT, {"GL_EXT_texture_integer", NULL} }, { GL_RGB16I_EXT, GL_RGBA_INTEGER, GL_INT, {"GL_EXT_texture_integer", NULL } }, { GL_RGB32I, GL_RGBA_INTEGER, GL_INT, {"GL_EXT_texture_integer", NULL} }, { GL_RG32I, GL_RGBA_INTEGER, GL_INT, {"GL_EXT_texture_integer", "GL_ARB_texture_rg"} }, { GL_R32I, GL_RGBA_INTEGER, GL_INT, {"GL_EXT_texture_integer", "GL_ARB_texture_rg"} }, { GL_ALPHA8I_EXT, GL_RGBA_INTEGER, GL_INT, {"GL_EXT_texture_integer", NULL} }, { GL_LUMINANCE8I_EXT, GL_RGBA_INTEGER, GL_INT, {"GL_EXT_texture_integer", NULL} }, { GL_INTENSITY8I_EXT, GL_RGBA_INTEGER, GL_INT, {"GL_EXT_texture_integer", NULL} }, { GL_LUMINANCE_ALPHA8I_EXT, GL_RGBA_INTEGER, GL_INT, {"GL_EXT_texture_integer", NULL} }, { GL_RGBA8UI_EXT, GL_RGBA_INTEGER, GL_INT, {"GL_EXT_texture_integer", NULL} }, { GL_RGBA16UI_EXT, GL_RGBA_INTEGER, GL_INT, {"GL_EXT_texture_integer", NULL} }, { GL_RGBA32UI_EXT, GL_RGBA_INTEGER, GL_INT, {"GL_EXT_texture_integer", NULL} }, { GL_RGB8UI_EXT, GL_RGBA_INTEGER, GL_INT, {"GL_EXT_texture_integer", NULL} }, { GL_RGB16UI_EXT, GL_RGBA_INTEGER, GL_INT, {"GL_EXT_texture_integer" } }, { GL_RGB32UI_EXT, GL_RGBA_INTEGER, GL_INT, {"GL_EXT_texture_integer", NULL} }, { GL_RG32UI, GL_RGBA_INTEGER, GL_INT, {"GL_EXT_texture_integer", "GL_ARB_texture_rg"} }, { GL_R32UI, GL_RGBA_INTEGER, GL_INT, {"GL_EXT_texture_integer", "GL_ARB_texture_rg"} }, { GL_ALPHA8UI_EXT, GL_RGBA_INTEGER, GL_INT, {"GL_EXT_texture_integer", NULL} }, { GL_LUMINANCE8UI_EXT, GL_RGBA_INTEGER, GL_INT, {"GL_EXT_texture_integer", NULL} }, { GL_INTENSITY8UI_EXT, GL_RGBA_INTEGER, GL_INT, {"GL_EXT_texture_integer", NULL} }, { GL_LUMINANCE_ALPHA8UI_EXT, GL_RGBA_INTEGER, GL_INT, {"GL_EXT_texture_integer", NULL} }, /* Packed depth / stencil formats */ { GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, {"GL_EXT_packed_depth_stencil", NULL} }, { GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, {"GL_ARB_depth_buffer_float", NULL} } }; int i, j; bool pass = true; glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); for (i = 0; i < ARRAY_SIZE(formats); i++) { bool is_ext_supported = true; for (j = 0; j < ARRAY_SIZE(formats[i].extension); j++) { if ((formats[i].extension[j] != NULL) && !piglit_is_extension_supported(formats[i].extension[j])) { printf("Skipping %s\n", piglit_get_gl_enum_name(formats[i].intFormat)); is_ext_supported = false; } } if (!is_ext_supported) continue; glTexImage2D(GL_TEXTURE_2D, 0, formats[i].intFormat, 16, 16, 0, formats[i].srcFormat, formats[i].srcType, NULL); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; glGenerateMipmap(GL_TEXTURE_2D); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; } glDeleteTextures(1, &tex); return pass; }
//---------------------------------------------------------- void ofTexture::generateMipmap(){ // Generate mipmaps using hardware-accelerated core GL methods. // 1. Check whether the current OpenGL version supports mipmap generation: // glGenerateMipmap() was introduced to OpenGL core in 3.0, and // OpenGLES core in 2.0 but earlier versions may support it if they // support extension GL_EXT_framebuffer_object bool isGlGenerateMipmapAvailable = false; #ifdef TARGET_OPENGLES if (ofGetOpenGLESVersion() >= 2) isGlGenerateMipmapAvailable = true; #else if (ofGetOpenGLVersionMajor() >= 3) isGlGenerateMipmapAvailable = true; #endif if (!isGlGenerateMipmapAvailable && !ofGLCheckExtension("GL_EXT_framebuffer_object")) { static bool versionWarningIssued = false; if (!versionWarningIssued) ofLogWarning() << "Your current OpenGL version does not support mipmap generation via glGenerateMipmap()."; versionWarningIssued = true; texData.hasMipmap = false; return; } // 2. Check whether the texture's texture target supports mipmap generation. switch (texData.textureTarget) { /// OpenGL ES only supports mipmap for the following two texture targets: case GL_TEXTURE_2D: case GL_TEXTURE_CUBE_MAP: #ifndef TARGET_OPENGLES /// OpenGL supports mipmaps for additional texture targets: case GL_TEXTURE_1D: case GL_TEXTURE_3D: case GL_TEXTURE_1D_ARRAY: case GL_TEXTURE_2D_ARRAY: #endif { // All good, this particular texture target supports mipmaps. // glEnable(texData.textureTarget); /// < uncomment this hack if you are unlucky enough to run an older ATI card. // See also: https://www.opengl.org/wiki/Common_Mistakes#Automatic_mipmap_generation glBindTexture(texData.textureTarget, (GLuint) texData.textureID); glGenerateMipmap(texData.textureTarget); glBindTexture(texData.textureTarget, 0); texData.hasMipmap = true; break; } default: { // This particular texture target does not support mipmaps. static bool warningIssuedAlready = false; if (!warningIssuedAlready){ ofLogWarning() << "Mipmaps are not supported for textureTarget 0x" << hex << texData.textureTarget << endl << "Most probably you are trying to create mipmaps from a GL_TEXTURE_RECTANGLE texture." << endl << "Try ofDisableArbTex() before loading this texture."; warningIssuedAlready = true; } texData.hasMipmap = false; break; } } // end switch(texData.textureTarget) }
void agp_update_vstore(struct storage_info_t* s, bool copy) { if (s->txmapped == TXSTATE_OFF) return; FLAG_DIRTY(); if (!copy) glBindTexture(GL_TEXTURE_2D, s->vinf.text.glid); else{ glGenTextures(1, &s->vinf.text.glid); /* for the launch_resume and resize states, were we'd push a new * update but have multiple references */ if (s->refcount == 0) s->refcount = 1; glBindTexture(GL_TEXTURE_2D, s->vinf.text.glid); } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, s->txu == ARCAN_VTEX_REPEAT ? GL_REPEAT : GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, s->txv == ARCAN_VTEX_REPEAT ? GL_REPEAT : GL_CLAMP_TO_EDGE); int filtermode = s->filtermode & (~ARCAN_VFILTER_MIPMAP); bool mipmap = s->filtermode & ARCAN_VFILTER_MIPMAP; /* * Mipmapping still misses the option to manually define mipmap levels */ if (copy){ #ifndef GL_GENERATE_MIPMAP if (mipmap) glGenerateMipmap(GL_TEXTURE_2D); #else glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, mipmap); #endif } switch (filtermode){ case ARCAN_VFILTER_NONE: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); break; case ARCAN_VFILTER_LINEAR: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); break; case ARCAN_VFILTER_BILINEAR: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); break; case ARCAN_VFILTER_TRILINEAR: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); break; } if (copy){ s->update_ts = arcan_timemillis(); if (s->txmapped == TXSTATE_DEPTH) glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, s->w, s->h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0); else glTexImage2D(GL_TEXTURE_2D, 0, GL_PIXEL_FORMAT, s->w, s->h, 0, GL_PIXEL_FORMAT, GL_UNSIGNED_BYTE, s->vinf.text.raw); } #ifndef HEADLESS_NOARCAN if (arcan_video_display.conservative){ arcan_mem_free(s->vinf.text.raw); s->vinf.text.raw = NULL; s->vinf.text.s_raw = 0; } #endif glBindTexture(GL_TEXTURE_2D, 0); }
GLuint LoadTGA(const char *file_path) // load TGA file to memory { std::ifstream fileStream(file_path, std::ios::binary); if(!fileStream.is_open()) { std::cout << "Impossible to open " << file_path << ". Are you in the right directory ?\n"; return 0; } GLubyte header[ 18 ]; // first 6 useful header bytes GLuint bytesPerPixel; // number of bytes per pixel in TGA gile GLuint imageSize; // for setting memory GLubyte * data; GLuint texture = 0; unsigned width, height; fileStream.read((char*)header, 18); width = header[12] + header[13] * 256; height = header[14] + header[15] * 256; if( width <= 0 || // is width <= 0 height <= 0 || // is height <=0 (header[16] != 24 && header[16] != 32)) // is TGA 24 or 32 Bit { fileStream.close(); // close file on failure std::cout << "File header error.\n"; return 0; } bytesPerPixel = header[16] / 8; //divide by 8 to get bytes per pixel imageSize = width * height * bytesPerPixel; // calculate memory required for TGA data data = new GLubyte[ imageSize ]; fileStream.seekg(18, std::ios::beg); fileStream.read((char *)data, imageSize); fileStream.close(); glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); if(bytesPerPixel == 3) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data); else //bytesPerPixel == 4 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D); float maxAnisotropy = 1.f; glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (GLint)maxAnisotropy); //to do: modify the texture parameters code from here 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); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); //end of modifiable code delete []data; return texture; }
// The MAIN function, from here we start the application and run the game loop int main() { // Init GLFW glfwInit(); // Set all the required options for GLFW glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // On mac os, must have this config. glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Create a GLFWwindow object that we can use for GLFW's functions GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr); glfwMakeContextCurrent(window); // Set the required callback functions glfwSetKeyCallback(window, key_callback); // Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions glewExperimental = GL_TRUE; // Initialize GLEW to setup the OpenGL Function pointers glewInit(); // Define the viewport dimensions glViewport(0, 0, WIDTH, HEIGHT); glEnable(GL_DEPTH_TEST); // Build and compile our shader program ShaderProgram ourShader("/Users/Evan/Documents/XcodeWorkspace/OpenGLCoreStudy/OpenGLCoreStudy/TestCode/GLSL/First3DObjects.vsh", "/Users/Evan/Documents/XcodeWorkspace/OpenGLCoreStudy/OpenGLCoreStudy/TestCode/GLSL/First3DObjects.fsh"); // Set up vertex data (and buffer(s)) and attribute pointers GLfloat vertices[] = { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f }; glm::vec3 cubePositions[] = { glm::vec3( 0.0f, 0.0f, 0.0f), glm::vec3( 2.0f, 5.0f, -15.0f), glm::vec3(-1.5f, -2.2f, -2.5f), glm::vec3(-3.8f, -2.0f, -12.3f), glm::vec3( 2.4f, -0.4f, -3.5f), glm::vec3(-1.7f, 3.0f, -7.5f), glm::vec3( 1.3f, -2.0f, -2.5f), glm::vec3( 1.5f, 2.0f, -2.5f), glm::vec3( 1.5f, 0.2f, -1.5f), glm::vec3(-1.3f, 1.0f, -1.5f) }; GLuint VBO, VAO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // Position attribute glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); // TexCoord attribute glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(2); glBindVertexArray(0); // Unbind VAO // Load and create a texture GLuint texture1; GLuint texture2; // ==================== // Texture 1 // ==================== glGenTextures(1, &texture1); glBindTexture(GL_TEXTURE_2D, texture1); // All upcoming GL_TEXTURE_2D operations now have effect on our texture object // Set our texture parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture wrapping to GL_REPEAT glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture filtering glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Load, create texture and generate mipmaps int width, height; unsigned char* image = SOIL_load_image("/Users/Evan/Documents/XcodeWorkspace/OpenGLCoreStudy/OpenGLCoreStudy/Resource/Image/container.jpg", &width, &height, 0, SOIL_LOAD_RGB); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); glGenerateMipmap(GL_TEXTURE_2D); SOIL_free_image_data(image); glBindTexture(GL_TEXTURE_2D, 0); // Unbind texture when done, so we won't accidentily mess up our texture. // =================== // Texture 2 // =================== glGenTextures(1, &texture2); glBindTexture(GL_TEXTURE_2D, texture2); // Set our texture parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture filtering glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Load, create texture and generate mipmaps image = SOIL_load_image("/Users/Evan/Documents/XcodeWorkspace/OpenGLCoreStudy/OpenGLCoreStudy/Resource/Image/awesomeface.png", &width, &height, 0, SOIL_LOAD_RGB); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); glGenerateMipmap(GL_TEXTURE_2D); SOIL_free_image_data(image); glBindTexture(GL_TEXTURE_2D, 0); // Game loop while (!glfwWindowShouldClose(window)) { GLfloat currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions glfwPollEvents(); do_movement(); // Render // Clear the colorbuffer glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Bind Textures using texture units glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture1); glUniform1i(glGetUniformLocation(ourShader.program, "ourTexture1"), 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texture2); glUniform1i(glGetUniformLocation(ourShader.program, "ourTexture2"), 1); // Activate shader ourShader.useShader(); // Camera/View transformation glm::mat4 view; view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp); // Projection glm::mat4 projection; projection = glm::perspective(45.0f, (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 100.0f); // Get the uniform locations GLint modelLoc = glGetUniformLocation(ourShader.program, "model"); GLint viewLoc = glGetUniformLocation(ourShader.program, "view"); GLint projLoc = glGetUniformLocation(ourShader.program, "projection"); // Pass the matrices to the shader glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection)); glBindVertexArray(VAO); for (GLuint i = 0; i < 10; i++) { // Calculate the model matrix for each object and pass it to shader before drawing glm::mat4 model; model = glm::translate(model, cubePositions[i]); GLfloat angle = 20.0f * i; model = glm::rotate(model, angle, glm::vec3(1.0f, 0.3f, 0.5f)); glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); glDrawArrays(GL_TRIANGLES, 0, 36); } glBindVertexArray(0); // Swap the screen buffers glfwSwapBuffers(window); } // Properly de-allocate all resources once they've outlived their purpose glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); // Terminate GLFW, clearing any resources allocated by GLFW. glfwTerminate(); return 0; }
void CubeMap::CubeMap::generateMipMaps() { glBindTexture( GL_TEXTURE_CUBE_MAP, m_handle ); glGenerateMipmap( GL_TEXTURE_CUBE_MAP ); glBindTexture( GL_TEXTURE_CUBE_MAP, 0 ); }
/** Render a glyph for a character into bitmap and save it into the glyph page. * \param c The character to be loaded. * \param c \ref GlyphInfo for the character. */ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi) { assert(gi.glyph_index > 0); assert(gi.font_number < m_face_ttf->getTotalFaces()); FT_Face cur_face = m_face_ttf->getFace(gi.font_number); FT_GlyphSlot slot = cur_face->glyph; // Same face may be shared across the different FontWithFace, // so reset dpi each time font_manager->checkFTError(FT_Set_Pixel_Sizes(cur_face, 0, getDPI()), "setting DPI"); font_manager->checkFTError(FT_Load_Glyph(cur_face, gi.glyph_index, FT_LOAD_DEFAULT), "loading a glyph"); font_manager->checkFTError(shapeOutline(&(slot->outline)), "shaping outline"); font_manager->checkFTError(FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL), "rendering a glyph to bitmap"); // Convert to an anti-aliased bitmap FT_Bitmap* bits = &(slot->bitmap); core::dimension2du texture_size(bits->width + 1, bits->rows + 1); if ((m_used_width + texture_size.Width > getGlyphPageSize() && m_used_height + m_current_height + texture_size.Height > getGlyphPageSize()) || m_used_height + texture_size.Height > getGlyphPageSize()) { // Add a new glyph page if current one is full createNewGlyphPage(); } // Determine the linebreak location if (m_used_width + texture_size.Width > getGlyphPageSize()) { m_used_width = 0; m_used_height += m_current_height; m_current_height = 0; } const unsigned int cur_tex = m_spritebank->getTextureCount() -1; #ifndef SERVER_ONLY if (bits->buffer != NULL) { video::ITexture* tex = m_spritebank->getTexture(cur_tex); glBindTexture(GL_TEXTURE_2D, tex->getOpenGLTextureName()); assert(bits->pixel_mode == FT_PIXEL_MODE_GRAY); if (CVS->isARBTextureSwizzleUsable()) { glTexSubImage2D(GL_TEXTURE_2D, 0, m_used_width, m_used_height, bits->width, bits->rows, GL_RED, GL_UNSIGNED_BYTE, bits->buffer); } else { const unsigned int size = bits->width * bits->rows; uint8_t* image_data = new uint8_t[size * 4]; memset(image_data, 255, size * 4); for (unsigned int i = 0; i < size; i++) image_data[4 * i + 3] = bits->buffer[i]; glTexSubImage2D(GL_TEXTURE_2D, 0, m_used_width, m_used_height, bits->width, bits->rows, GL_RGBA, GL_UNSIGNED_BYTE, image_data); delete[] image_data; } if (tex->hasMipMaps()) glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); } #endif // Store the rectangle of current glyph gui::SGUISpriteFrame f; gui::SGUISprite s; core::rect<s32> rectangle(m_used_width, m_used_height, m_used_width + bits->width, m_used_height + bits->rows); f.rectNumber = m_spritebank->getPositions().size(); f.textureNumber = cur_tex; // Add frame to sprite s.Frames.push_back(f); s.frameTime = 0; m_spritebank->getPositions().push_back(rectangle); m_spritebank->getSprites().push_back(s); // Save glyph metrics FontArea a; a.advance_x = cur_face->glyph->advance.x / BEARING; a.bearing_x = cur_face->glyph->metrics.horiBearingX / BEARING; const int cur_height = (cur_face->glyph->metrics.height / BEARING); const int cur_offset_y = cur_height - (cur_face->glyph->metrics.horiBearingY / BEARING); a.offset_y = m_glyph_max_height - cur_height + cur_offset_y; a.offset_y_bt = -cur_offset_y; a.spriteno = f.rectNumber; m_character_area_map[c] = a; // Store used area m_used_width += texture_size.Width; if (m_current_height < texture_size.Height) m_current_height = texture_size.Height; } // insertGlyph
void Texture2D::generateMipMaps() { glBindTexture( GL_TEXTURE_2D, m_handle ); glGenerateMipmap( GL_TEXTURE_2D ); glBindTexture( GL_TEXTURE_2D, 0 ); }
void myinit(void) { // Load shaders and use the resulting shader program GLuint program = InitShader( "vshader.glsl", "fshader.glsl" ); glUseProgram(program); // Generate vertex arrays for geometric shapes generateCube(program, &cubeData); generateSphere(program, &sphereData); generateCone(program, &coneData); generateCylinder(program, &cylData); uModelView = glGetUniformLocation( program, "ModelView" ); uProjection = glGetUniformLocation( program, "Projection" ); uView = glGetUniformLocation( program, "View" ); glClearColor( 0.1, 0.1, 0.2, 1.0 ); // dark blue background uAmbient = glGetUniformLocation( program, "AmbientProduct" ); uDiffuse = glGetUniformLocation( program, "DiffuseProduct" ); uSpecular = glGetUniformLocation( program, "SpecularProduct" ); uLightPos = glGetUniformLocation( program, "LightPosition" ); uShininess = glGetUniformLocation( program, "Shininess" ); uTex = glGetUniformLocation( program, "Tex" ); uEnableTex = glGetUniformLocation( program, "EnableTex" ); glUniform4f(uAmbient, 0.2f, 0.2f, 0.2f, 1.0f); glUniform4f(uDiffuse, 0.6f, 0.6f, 0.6f, 1.0f); glUniform4f(uSpecular, 0.2f, 0.2f, 0.2f, 1.0f); glUniform4f(uLightPos, 15.0f, 15.0f, 30.0f, 0.0f); glUniform1f(uShininess, 100.0f); glEnable(GL_DEPTH_TEST); TgaImage coolImage; if (!coolImage.loadTGA("challenge.tga")) { printf("Error loading image file\n"); exit(1); } TgaImage earthImage; if (!earthImage.loadTGA("earth.tga")) { printf("Error loading image file\n"); exit(1); } glGenTextures( 1, &texture_cube ); glBindTexture( GL_TEXTURE_2D, texture_cube ); glTexImage2D(GL_TEXTURE_2D, 0, 4, coolImage.width, coolImage.height, 0, (coolImage.byteCount == 3) ? GL_BGR : GL_BGRA, GL_UNSIGNED_BYTE, coolImage.data ); glGenerateMipmap(GL_TEXTURE_2D); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glGenTextures( 1, &texture_earth ); glBindTexture( GL_TEXTURE_2D, texture_earth ); glTexImage2D(GL_TEXTURE_2D, 0, 4, earthImage.width, earthImage.height, 0, (earthImage.byteCount == 3) ? GL_BGR : GL_BGRA, GL_UNSIGNED_BYTE, earthImage.data ); glGenerateMipmap(GL_TEXTURE_2D); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); //glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); //glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Set texture sampler variable to texture unit 0 // (set in glActiveTexture(GL_TEXTURE0)) glUniform1i( uTex, 0); Arcball = new BallData ; Ball_Init(Arcball); Ball_Place(Arcball,qOne,0.75); }
GLuint createTextureFromTga(const char * path) { long length; char * buffer = getTextFileContent(path, &length); const TgaHeader * header = (TgaHeader *) buffer; GLint format; GLint internalFormat; GLuint texture; const GLvoid * imgData; if (buffer == NULL) { return 0; } if (length <= (signed long) sizeof(TgaHeader)) { fprintf(stderr, "Too small TGA file: %s\n", path); free(buffer); return 0; } if (header->datatype != 2 || (header->bitperpel != 24 && header->bitperpel != 32)) { fprintf(stderr, "Wrong TGA file format: %s\n", path); free(buffer); return 0; } format = (header->bitperpel == 24 ? GL_BGR : GL_BGRA); internalFormat = (format == GL_BGR ? GL_RGB8 : GL_RGBA8); imgData = (const GLvoid *) (buffer + sizeof(TgaHeader) + header->idlength); glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); /* Set 1-byte alignment (for non (2^n)x(2^n) size textures). */ glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, header->width, header->height, 0, format, GL_UNSIGNED_BYTE, imgData); free(buffer); #if 0 /* Linear filtering */ 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_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);*/ #else glGenerateMipmap(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); #endif #if 0 /* No wrap */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); #else glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); #endif CHECK_OPENGL_ERRORS(__FILE__, __LINE__); return texture; }
//---------------------------------------------------------------------------------------------------------------------- //This virtual function is called whenever the widget needs to be painted. // this is our main drawing routine void GLWindow::paintGL() { //---------------------------------------------------------------------------------------------------------------------- // Pass 1 render our Depth texture to the FBO //---------------------------------------------------------------------------------------------------------------------- // enable culling glEnable(GL_CULL_FACE); glEnable(GL_MULTISAMPLE_ARB); // bind the FBO and render offscreen to the texture glBindFramebuffer(GL_FRAMEBUFFER,m_fboID); // bind the texture object to 0 (off ) glBindTexture(GL_TEXTURE_2D,0); // we need to render to the same size as the texture to avoid // distortions glViewport(0,0,m_textureSize,m_textureSize); // Clear previous frame values glClear( GL_DEPTH_BUFFER_BIT); // as we are only rendering depth turn off the colour / alpha glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // render only the back faces so we don't get too much self shadowing glCullFace(GL_FRONT); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(m_polyOffsetFactor,m_polyOffsetScale ); // set the shape of the camera before rendering m_lightCamera->setShape(m_fov,1.0,m_zNear,m_zfar); // draw the scene from the POV of the light drawScene(&GLWindow::loadToLightPOVShader); //---------------------------------------------------------------------------------------------------------------------- // Pass two use the texture // now we have created the texture for shadows render the scene properly //---------------------------------------------------------------------------------------------------------------------- // go back to our normal framebuffer glBindFramebuffer(GL_FRAMEBUFFER,0); // set the viewport to the screen dimensions glViewport(0,0,m_width,m_height); // enable colour rendering again (as we turned it off earlier) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // clear the screen glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // bind the shadow texture glBindTexture(GL_TEXTURE_2D,m_textureID); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); glTexParameteri( GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE ); // we need to generate the mip maps each time we bind glGenerateMipmap(GL_TEXTURE_2D); // now only cull back faces glDisable(GL_CULL_FACE); // render our scene with the shadow shader drawScene(&GLWindow::loadMatricesToShadowShader); //---------------------------------------------------------------------------------------------------------------------- // this draws the debug texture on the quad //---------------------------------------------------------------------------------------------------------------------- if(m_drawDebugQuad) { glBindTexture(GL_TEXTURE_2D,m_textureID); // glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE ); // glTexParameteri( GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE ); debugTexture(-0.6,-1,0.6,1); } //---------------------------------------------------------------------------------------------------------------------- // now we draw a cube to visualise the light //---------------------------------------------------------------------------------------------------------------------- ngl::VAOPrimitives *prim=ngl::VAOPrimitives::instance(); ngl::ShaderLib *shader = ngl::ShaderLib::instance(); shader->use("Colour"); m_transform.reset(); m_transform.setPosition(m_lightPosition); ngl::Mat4 MVP=m_transform.getMatrix() * m_mouseGlobalTX * m_cam->getVPMatrix(); shader->setShaderParamFromMat4("MVP",MVP); prim->draw("cube"); }
void myinit() { GLint err = glGetError(); assert(err==GL_NO_ERROR); // GLfloat light_ambient[] = { btScalar(0.2), btScalar(0.2), btScalar(0.2), btScalar(1.0) }; GLfloat light_ambient[] = { btScalar(1.0), btScalar(1.2), btScalar(0.2), btScalar(1.0) }; GLfloat light_diffuse[] = { btScalar(1.0), btScalar(1.0), btScalar(1.0), btScalar(1.0) }; GLfloat light_specular[] = { btScalar(1.0), btScalar(1.0), btScalar(1.0), btScalar(1.0 )}; /* light_position is NOT default value */ GLfloat light_position0[] = { btScalar(10000.0), btScalar(10000.0), btScalar(10000.0), btScalar(0.0 )}; GLfloat light_position1[] = { btScalar(-1.0), btScalar(-10.0), btScalar(-1.0), btScalar(0.0) }; // glShadeModel(GL_FLAT);//GL_SMOOTH); //glShadeModel(GL_SMOOTH); err = glGetError(); assert(err==GL_NO_ERROR); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); err = glGetError(); assert(err==GL_NO_ERROR); glClearColor(float(0.7),float(0.7),float(0.7),float(0)); //glEnable(GL_LIGHTING); //glEnable(GL_LIGHT0); err = glGetError(); assert(err==GL_NO_ERROR); static bool m_textureenabled = true; static bool m_textureinitialized = false; err = glGetError(); assert(err==GL_NO_ERROR); if(m_textureenabled) { if(!m_textureinitialized) { glActiveTexture(GL_TEXTURE0); GLubyte* image=new GLubyte[256*256*3]; for(int y=0;y<256;++y) { const int t=y>>5; GLubyte* pi=image+y*256*3; for(int x=0;x<256;++x) { if (x<2||y<2||x>253||y>253) { pi[0]=0; pi[1]=0; pi[2]=0; } else { pi[0]=255; pi[1]=255; pi[2]=255; } /* const int s=x>>5; const GLubyte b=180; GLubyte c=b+((s+t&1)&1)*(255-b); pi[0]=c; pi[1]=c; pi[2]=c; */ pi+=3; } } glGenTextures(1,(GLuint*)&m_texturehandle); glBindTexture(GL_TEXTURE_2D,m_texturehandle); err = glGetError(); assert(err==GL_NO_ERROR); #if 0 glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); err = glGetError(); assert(err==GL_NO_ERROR); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); err = glGetError(); assert(err==GL_NO_ERROR); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); err = glGetError(); assert(err==GL_NO_ERROR); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); err = glGetError(); assert(err==GL_NO_ERROR); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); err = glGetError(); assert(err==GL_NO_ERROR); #endif err = glGetError(); assert(err==GL_NO_ERROR); int filter=1; // Build2DMipmaps(3,256,256,GL_RGB,image,filter); //gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA,256,256,GL_RGB,GL_UNSIGNED_BYTE,image); //glTexParameterf(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256,256,0,GL_RGB,GL_UNSIGNED_BYTE,image); glGenerateMipmap(GL_TEXTURE_2D); err = glGetError(); assert(err==GL_NO_ERROR); delete[] image; m_textureinitialized=true; } // glMatrixMode(GL_TEXTURE); // glLoadIdentity(); // glMatrixMode(GL_MODELVIEW); err = glGetError(); assert(err==GL_NO_ERROR); glBindTexture(GL_TEXTURE_2D,m_texturehandle); err = glGetError(); assert(err==GL_NO_ERROR); } else
//----------------------------------------------------------------------------- // Very fast texture-to-texture blitter and hardware bi/trilinear scaling implementation using FBO // Destination texture must be 1D, 2D, 3D, or Cube // Source texture must be 1D, 2D or 3D // Supports compressed formats as both source and destination format, it will use the hardware DXT compressor // if available. // @author W.J. van der Laan void GLES2TextureBuffer::blitFromTexture(GLES2TextureBuffer *src, const Image::Box &srcBox, const Image::Box &dstBox) { return; // todo - add a shader attach... // std::cerr << "GLES2TextureBuffer::blitFromTexture " << // src->mTextureID << ":" << srcBox.left << "," << srcBox.top << "," << srcBox.right << "," << srcBox.bottom << " " << // mTextureID << ":" << dstBox.left << "," << dstBox.top << "," << dstBox.right << "," << dstBox.bottom << std::endl; // Store reference to FBO manager GLES2FBOManager *fboMan = static_cast<GLES2FBOManager *>(GLES2RTTManager::getSingletonPtr()); RenderSystem* rsys = Root::getSingleton().getRenderSystem(); rsys->_disableTextureUnitsFrom(0); glActiveTexture(GL_TEXTURE0); // Disable alpha, depth and scissor testing, disable blending, // and disable culling glDisable(GL_DEPTH_TEST); glDisable(GL_SCISSOR_TEST); glDisable(GL_BLEND); glDisable(GL_CULL_FACE); // Set up source texture OGRE_CHECK_GL_ERROR(glBindTexture(src->mTarget, src->mTextureID)); // Set filtering modes depending on the dimensions and source if(srcBox.getWidth()==dstBox.getWidth() && srcBox.getHeight()==dstBox.getHeight() && srcBox.getDepth()==dstBox.getDepth()) { // Dimensions match -- use nearest filtering (fastest and pixel correct) OGRE_CHECK_GL_ERROR(glTexParameteri(src->mTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); OGRE_CHECK_GL_ERROR(glTexParameteri(src->mTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); } else { // Dimensions don't match -- use bi or trilinear filtering depending on the // source texture. if(src->mUsage & TU_AUTOMIPMAP) { // Automatic mipmaps, we can safely use trilinear filter which // brings greatly improved quality for minimisation. OGRE_CHECK_GL_ERROR(glTexParameteri(src->mTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)); OGRE_CHECK_GL_ERROR(glTexParameteri(src->mTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); } else { // Manual mipmaps, stay safe with bilinear filtering so that no // intermipmap leakage occurs. OGRE_CHECK_GL_ERROR(glTexParameteri(src->mTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); OGRE_CHECK_GL_ERROR(glTexParameteri(src->mTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); } } // Clamp to edge (fastest) OGRE_CHECK_GL_ERROR(glTexParameteri(src->mTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); OGRE_CHECK_GL_ERROR(glTexParameteri(src->mTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); #if OGRE_NO_GLES3_SUPPORT == 0 OGRE_CHECK_GL_ERROR(glTexParameteri(src->mTarget, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE)); // Set origin base level mipmap to make sure we source from the right mip // level. OGRE_CHECK_GL_ERROR(glTexParameteri(src->mTarget, GL_TEXTURE_BASE_LEVEL, src->mLevel)); #endif // Store old binding so it can be restored later GLint oldfb; OGRE_CHECK_GL_ERROR(glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldfb)); // Set up temporary FBO OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, fboMan->getTemporaryFBO())); GLuint tempTex = 0; if(!fboMan->checkFormat(mFormat)) { // If target format not directly supported, create intermediate texture GLenum tempFormat = GLES2PixelUtil::getClosestGLInternalFormat(fboMan->getSupportedAlternative(mFormat)); OGRE_CHECK_GL_ERROR(glGenTextures(1, &tempTex)); OGRE_CHECK_GL_ERROR(glBindTexture(GL_TEXTURE_2D, tempTex)); #if GL_APPLE_texture_max_level && OGRE_PLATFORM != OGRE_PLATFORM_NACL OGRE_CHECK_GL_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL_APPLE, 0)); #elif OGRE_NO_GLES3_SUPPORT == 0 OGRE_CHECK_GL_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0)); #endif // Allocate temporary texture of the size of the destination area OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, tempFormat, GLES2PixelUtil::optionalPO2(dstBox.getWidth()), GLES2PixelUtil::optionalPO2(dstBox.getHeight()), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0)); OGRE_CHECK_GL_ERROR(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tempTex, 0)); // Set viewport to size of destination slice OGRE_CHECK_GL_ERROR(glViewport(0, 0, dstBox.getWidth(), dstBox.getHeight())); } else { // We are going to bind directly, so set viewport to size and position of destination slice OGRE_CHECK_GL_ERROR(glViewport(dstBox.left, dstBox.top, dstBox.getWidth(), dstBox.getHeight())); } // Process each destination slice for(size_t slice=dstBox.front; slice<dstBox.back; ++slice) { if(!tempTex) { // Bind directly bindToFramebuffer(GL_COLOR_ATTACHMENT0, slice); } /// Calculate source texture coordinates float u1 = (float)srcBox.left / (float)src->mWidth; float v1 = (float)srcBox.top / (float)src->mHeight; float u2 = (float)srcBox.right / (float)src->mWidth; float v2 = (float)srcBox.bottom / (float)src->mHeight; /// Calculate source slice for this destination slice float w = (float)(slice - dstBox.front) / (float)dstBox.getDepth(); /// Get slice # in source w = w * (float)srcBox.getDepth() + srcBox.front; /// Normalise to texture coordinate in 0.0 .. 1.0 w = (w+0.5f) / (float)src->mDepth; /// Finally we're ready to rumble OGRE_CHECK_GL_ERROR(glBindTexture(src->mTarget, src->mTextureID)); OGRE_CHECK_GL_ERROR(glEnable(src->mTarget)); GLfloat squareVertices[] = { -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, }; GLfloat texCoords[] = { u1, v1, w, u2, v1, w, u2, v2, w, u1, v2, w }; GLuint posAttrIndex = 0; GLuint texAttrIndex = 0; if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) { GLSLESProgramPipeline* programPipeline = GLSLESProgramPipelineManager::getSingleton().getActiveProgramPipeline(); posAttrIndex = (GLuint)programPipeline->getAttributeIndex(VES_POSITION, 0); texAttrIndex = (GLuint)programPipeline->getAttributeIndex(VES_TEXTURE_COORDINATES, 0); } else { GLSLESLinkProgram* linkProgram = GLSLESLinkProgramManager::getSingleton().getActiveLinkProgram(); posAttrIndex = (GLuint)linkProgram->getAttributeIndex(VES_POSITION, 0); texAttrIndex = (GLuint)linkProgram->getAttributeIndex(VES_TEXTURE_COORDINATES, 0); } // Draw the textured quad OGRE_CHECK_GL_ERROR(glVertexAttribPointer(posAttrIndex, 2, GL_FLOAT, 0, 0, squareVertices)); OGRE_CHECK_GL_ERROR(glEnableVertexAttribArray(posAttrIndex)); OGRE_CHECK_GL_ERROR(glVertexAttribPointer(texAttrIndex, 3, GL_FLOAT, 0, 0, texCoords)); OGRE_CHECK_GL_ERROR(glEnableVertexAttribArray(texAttrIndex)); OGRE_CHECK_GL_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); OGRE_CHECK_GL_ERROR(glDisable(src->mTarget)); if(tempTex) { // Copy temporary texture OGRE_CHECK_GL_ERROR(glBindTexture(mTarget, mTextureID)); switch(mTarget) { case GL_TEXTURE_2D: case GL_TEXTURE_CUBE_MAP: OGRE_CHECK_GL_ERROR(glCopyTexSubImage2D(mFaceTarget, mLevel, dstBox.left, dstBox.top, 0, 0, dstBox.getWidth(), dstBox.getHeight())); break; } } } // Finish up if(!tempTex) { // Generate mipmaps if(mUsage & TU_AUTOMIPMAP) { OGRE_CHECK_GL_ERROR(glBindTexture(mTarget, mTextureID)); OGRE_CHECK_GL_ERROR(glGenerateMipmap(mTarget)); } } // Reset source texture to sane state OGRE_CHECK_GL_ERROR(glBindTexture(src->mTarget, src->mTextureID)); #if OGRE_NO_GLES3_SUPPORT == 0 OGRE_CHECK_GL_ERROR(glTexParameteri(src->mTarget, GL_TEXTURE_BASE_LEVEL, 0)); // Detach texture from temporary framebuffer if(mFormat == PF_DEPTH) { OGRE_CHECK_GL_ERROR(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0)); } else #endif { OGRE_CHECK_GL_ERROR(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0)); } // Restore old framebuffer OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, oldfb)); OGRE_CHECK_GL_ERROR(glDeleteTextures(1, &tempTex)); }
void CGrassDrawer::CreateFarTex() { //TODO create normalmap, too? const int sizeMod = 2; const int billboardSize = 256; const int numAngles = 16; const int texSizeX = billboardSize * numAngles; const int texSizeY = billboardSize; if (farTex == 0) { glGenTextures(1, &farTex); glBindTexture(GL_TEXTURE_2D, farTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glSpringTexStorage2D(GL_TEXTURE_2D, -1, GL_RGBA8, texSizeX, texSizeY); } FBO fboTex; fboTex.Bind(); fboTex.AttachTexture(farTex); fboTex.CheckStatus("GRASSDRAWER1"); FBO fbo; fbo.Bind(); fbo.CreateRenderBuffer(GL_DEPTH_ATTACHMENT_EXT, GL_DEPTH_COMPONENT16, texSizeX * sizeMod, texSizeY * sizeMod); fbo.CreateRenderBuffer(GL_COLOR_ATTACHMENT0_EXT, GL_RGBA8, texSizeX * sizeMod, texSizeY * sizeMod); fbo.CheckStatus("GRASSDRAWER2"); if (!fboTex.IsValid() || !fbo.IsValid()) { grassOff = true; return; } glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glDisable(GL_FOG); glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); glBindTexture(GL_TEXTURE_2D, grassBladeTex); glEnable(GL_TEXTURE_2D); glEnable(GL_CLIP_PLANE0); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glColor4f(1,1,1,1); glViewport(0,0,texSizeX*sizeMod, texSizeY*sizeMod); glClearColor(mapInfo->grass.color.r,mapInfo->grass.color.g,mapInfo->grass.color.b,0.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearColor(0.f,0.f,0.f,0.f); static const GLdouble eq[4] = {0.f, 1.f, 0.f, 0.f}; // render turf from different vertical angles for (int a=0;a<numAngles;++a) { glViewport(a*billboardSize*sizeMod, 0, billboardSize*sizeMod, billboardSize*sizeMod); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRotatef(a*90.f/(numAngles-1),1,0,0); //glTranslatef(0,-0.5f,0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-partTurfSize, partTurfSize, partTurfSize, -partTurfSize, -turfSize, turfSize); // has to be applied after the matrix transformations, // cause it uses those an `compiles` them into the clip plane glClipPlane(GL_CLIP_PLANE0, &eq[0]); glCallList(grassDL); } glDisable(GL_CLIP_PLANE0); // scale down the rendered fartextures (MSAA) and write to the final texture glBindFramebufferEXT(GL_READ_FRAMEBUFFER, fbo.fboId); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, fboTex.fboId); glBlitFramebufferEXT(0, 0, texSizeX*sizeMod, texSizeY*sizeMod, 0, 0, texSizeX, texSizeY, GL_COLOR_BUFFER_BIT, GL_LINEAR); // compute mipmaps glBindTexture(GL_TEXTURE_2D, farTex); glGenerateMipmap(GL_TEXTURE_2D); // blur non-rendered areas, so in mipmaps color data isn't blurred with background color { const int mipLevels = std::ceil(std::log((float)(std::max(texSizeX, texSizeY) + 1))); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glEnable(GL_BLEND); glBlendFuncSeparate(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA, GL_ZERO, GL_DST_ALPHA); // copy each mipmap to its predecessor background // -> fill background with blurred color data fboTex.Bind(); for (int mipLevel = mipLevels - 2; mipLevel >= 0; --mipLevel) { fboTex.AttachTexture(farTex, GL_TEXTURE_2D, GL_COLOR_ATTACHMENT0_EXT, mipLevel); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, mipLevel + 1.f); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, mipLevel + 1.f); glViewport(0, 0, texSizeX>>mipLevel, texSizeY>>mipLevel); CVertexArray* va = GetVertexArray(); va->Initialize(); va->AddVertexT(float3(-1.0f, 1.0f, 0.0f), 0.0f, 1.0f); va->AddVertexT(float3( 1.0f, 1.0f, 0.0f), 1.0f, 1.0f); va->AddVertexT(float3( 1.0f, -1.0f, 0.0f), 1.0f, 0.0f); va->AddVertexT(float3(-1.0f, -1.0f, 0.0f), 0.0f, 0.0f); va->DrawArrayT(GL_QUADS); } glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // recreate mipmaps from now blurred base level glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, -1000.f); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 1000.f); glGenerateMipmap(GL_TEXTURE_2D); } glViewport(globalRendering->viewPosX, 0, globalRendering->viewSizeX, globalRendering->viewSizeY); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); FBO::Unbind(); //glSaveTexture(farTex, "grassfar.png"); }
// The MAIN function, from here we start the application and run the game loop int main() { // Init GLFW glfwInit(); // Set all the required options for GLFW glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Create a GLFWwindow object that we can use for GLFW's functions GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr); glfwMakeContextCurrent(window); // Set the required callback functions glfwSetKeyCallback(window, key_callback); // Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions glewExperimental = GL_TRUE; // Initialize GLEW to setup the OpenGL Function pointers glewInit(); // Define the viewport dimensions glViewport(0, 0, WIDTH, HEIGHT); // Build and compile our shader program Shader ourShader("transform.vs", "transform.frag"); // Set up vertex data (and buffer(s)) and attribute pointers GLfloat vertices[] = { // Positions // Colors // Texture Coords 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // Top Right 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Bottom Right -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Bottom Left -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // Top Left }; GLuint indices[] = { // Note that we start from 0! 0, 1, 3, // First Triangle 1, 2, 3 // Second Triangle }; GLuint VBO, VAO, EBO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); // Position attribute glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); // Color attribute glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(1); // TexCoord attribute glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat))); glEnableVertexAttribArray(2); glBindVertexArray(0); // Unbind VAO // Load and create a texture GLuint texture1; GLuint texture2; // ==================== // Texture 1 // ==================== glGenTextures(1, &texture1); glBindTexture(GL_TEXTURE_2D, texture1); // All upcoming GL_TEXTURE_2D operations now have effect on our texture object // Set our texture parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture wrapping to GL_REPEAT glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture filtering glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Load, create texture and generate mipmaps int width, height; unsigned char* image = SOIL_load_image("../../../resources/textures/container.jpg", &width, &height, 0, SOIL_LOAD_RGB); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); glGenerateMipmap(GL_TEXTURE_2D); SOIL_free_image_data(image); glBindTexture(GL_TEXTURE_2D, 0); // Unbind texture when done, so we won't accidentily mess up our texture. // =================== // Texture 2 // =================== glGenTextures(1, &texture2); glBindTexture(GL_TEXTURE_2D, texture2); // Set our texture parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture filtering glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Load, create texture and generate mipmaps image = SOIL_load_image("../../../resources/textures/awesomeface.png", &width, &height, 0, SOIL_LOAD_RGB); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); glGenerateMipmap(GL_TEXTURE_2D); SOIL_free_image_data(image); glBindTexture(GL_TEXTURE_2D, 0); // Game loop while (!glfwWindowShouldClose(window)) { // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions glfwPollEvents(); // Render // Clear the colorbuffer glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); // Bind Textures using texture units glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture1); glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture1"), 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texture2); glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture2"), 1); // Activate shader ourShader.Use(); // Create transformations glm::mat4 transform; transform = glm::translate(transform, glm::vec3(0.5f, -0.5f, 0.0f)); transform = glm::rotate(transform, (GLfloat)glfwGetTime() * 50.0f, glm::vec3(0.0f, 0.0f, 1.0f)); // Get matrix's uniform location and set matrix GLint transformLoc = glGetUniformLocation(ourShader.Program, "transform"); glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform)); // Draw container glBindVertexArray(VAO); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glBindVertexArray(0); // Swap the screen buffers glfwSwapBuffers(window); } // Properly de-allocate all resources once they've outlived their purpose glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); glDeleteBuffers(1, &EBO); // Terminate GLFW, clearing any resources allocated by GLFW. glfwTerminate(); return 0; }
bool Texture :: loadCubemap ( const char * f1, const char * f2, const char * f3, const char * f4, const char * f5, const char * f6 ) { TexImage * image [6]; image [0] = loadTexImage ( f1 ); image [1] = loadTexImage ( f2 ); image [2] = loadTexImage ( f3 ); image [3] = loadTexImage ( f4 ); image [4] = loadTexImage ( f5 ); image [5] = loadTexImage ( f6 ); for ( int i = 0; i < 6; i++ ) if ( image [i] == NULL || image [i] -> getImageType () != TexImage :: image2D || image [i] -> getWidth () != image [i] -> getHeight () ) { for ( int j = 0; j < 6; j++ ) delete image [j]; return false; } for ( int i = 1; i < 6; i++ ) if ( image [i] -> getWidth () != image [0] -> getWidth () || image [i] -> getFormat () != image [0] -> getFormat () ) { for ( int j = 0; j < 6; j++ ) delete image [j]; return false; } setParamsFromTexImage ( image [0], GL_TEXTURE_CUBE_MAP ); glGenTextures ( 1, &id ); glBindTexture ( target, id ); glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 ); // set 1-byte alignment glTexParameteri ( target, GL_TEXTURE_WRAP_S, GL_REPEAT ); // set default params for texture glTexParameteri ( target, GL_TEXTURE_WRAP_T, GL_REPEAT ); if ( !image [0] -> isCompressed () ) // not compressed image { for ( int i = 0; i < 6; i++ ) glTexImage2D ( GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + i, 0, getFormat ().getInternalFormat (), width, height, 0, getFormat ().getFormat (), image [i] -> getGlType (), image [i] -> imageData () ); if ( autoMipmaps ) glGenerateMipmap ( target ); } else { int mipmaps = image [0] -> getNumLevels (); // glTexParameteri ( target, GL_TEXTURE_MAX_LEVEL, mipmaps - 1 ); for ( int i = 0; i < 6; i++ ) { int w = width; int h = height; byte * ptr = image [i] -> imageData ( i, 0 ); for ( int j = 0; j < mipmaps; j++ ) { int size = image [i] -> imageDataSize ( 0, j ); glCompressedTexImage2D ( GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + i, j, getFormat ().getInternalFormat (), w, h, 0, size, ptr ); if ( ( w = w / 2 ) < 1 ) w = 1; if ( ( h = h / 2 ) < 1 ) h = 1; ptr += size; } } } if ( autoMipmaps ) { glTexParameteri ( target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ); glTexParameteri ( target, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); } else { glTexParameteri ( target, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri ( target, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); } glBindTexture ( target, 0 ); for ( int j = 0; j < 6; j++ ) delete image [j]; return true; }