bool Res::Init() { Shader* shader = nullptr; Texture* texture = nullptr; // block shader shader = new Shader(); if (!shader->Init("res/block.vert", "res/block.frag")) return false; AddShader("block", shader); // simpler color shader shader = new Shader(); if (!shader->Init("res/color.vert", "res/color.frag")) return false; AddShader("color", shader); std::vector<byte> buffer, image; LodePNG::loadFile(buffer, "res/blocks.png"); LodePNG::Decoder decoder; decoder.decode(image, buffer); int dim = decoder.getWidth(); texture = Texture::Create3DTexture(dim, dim, decoder.getHeight() / dim, image.data()); AddTexture("blocks", texture); return true; }
void Image::read_png(const char* filename) { std::vector<unsigned char> buffer, image; //load the image file with given filename LodePNG::loadFile(buffer, filename); //decode the png LodePNG::Decoder decoder; decoder.decode(image, buffer.empty() ? 0 : &buffer[0], (unsigned)buffer.size()); if (decoder.getChannels()<3 || decoder.getBpp()<24) { cerr << "Error: only color (RGBA), 8 bit per channel png images are supported." << endl; cerr << "Either convert your image or change the sourcecode." << endl; exit(1); } int w = decoder.getWidth(); int h = decoder.getHeight(); set_extent(w,h); // now convert the image data std::vector<unsigned char>::iterator imageIterator = image.begin(); Color *currentPixel = _pixel; while (imageIterator != image.end()) { currentPixel->r = (*imageIterator)/255.0; imageIterator++; currentPixel->g = (*imageIterator)/255.0; imageIterator++; currentPixel->b = (*imageIterator)/255.0; imageIterator++; // Let's just ignore the alpha channel imageIterator++; currentPixel++; } }
bool ProceduralTexture::loadPNG(char *png_map) { LodePNG::Decoder pngDecoder; std::vector<unsigned char> buffer; Logger::log("Loading png file %s..\n",png_map); LodePNG::loadFile(buffer,png_map); Logger::log("Calling PNG decoder..\n"); pngDecoder.decode(image, buffer); Logger::log("Checking decoder state..\n"); if(pngDecoder.hasError()) { Logger::log("[loadTextureFromPng] Error %d\n", pngDecoder.getError()); Logger::log(" while trying to load \'%s\'\n",png_map); return false; } width = pngDecoder.getWidth(); height = pngDecoder.getHeight(); Logger::log("PNG Decoder Info [ width: %d, height: %d ]..\n",width,height); Logger::log("image size: %d\n",image.size()); Logger::log("isGreyScale: %s\n",pngDecoder.isGreyscaleType()?"true":"false"); Logger::log("isAlphaType: %s\n",pngDecoder.isAlphaType()?"true":"false"); Logger::log("Channels: %d\n",pngDecoder.getChannels()); Logger::log("BPP: %d\n",pngDecoder.getBpp()); return true; }
Image* FW::importLodePngImage(InputStream& stream) { // Read the entire input stream. Array<U8> dataBuffer; int blockSize = 4096; for (;;) { int pos = dataBuffer.getSize(); dataBuffer.resize(pos + blockSize); int num = stream.read(dataBuffer.getPtr(pos), blockSize); if (num < blockSize) { dataBuffer.resize(pos + num); break; } } if (hasError()) return NULL; // Decode image info. LodePNG::Decoder decoder; decoder.inspect(dataBuffer.getPtr(), dataBuffer.getSize()); Vec2i size(decoder.getWidth(), decoder.getHeight()); bool hasAlpha = (LodePNG_InfoColor_canHaveAlpha(&decoder.getInfoPng().color) != 0); if (decoder.hasError()) setError("importLodePngImage(): LodePNG error %d!", decoder.getError()); if (min(size) <= 0) setError("importLodePngImage(): Invalid image size!"); if (hasError()) return NULL; // Decode image data. int numBytes = size.x * size.y * ((hasAlpha) ? 4 : 3); std::vector<U8> pixelBuffer; pixelBuffer.reserve(numBytes); decoder.getInfoRaw().color.colorType = (hasAlpha) ? 6 : 2; decoder.decode(pixelBuffer, dataBuffer.getPtr(), dataBuffer.getSize()); if (decoder.hasError()) setError("importLodePngImage(): LodePNG error %d!", decoder.getError()); if ((int)pixelBuffer.size() != numBytes) setError("importLodePngImage(): Incorrect amount of pixel data!"); if (hasError()) return NULL; // Create image. Image* image = new Image(size, (hasAlpha) ? ImageFormat::R8_G8_B8_A8 : ImageFormat::R8_G8_B8); image->getBuffer().set(&pixelBuffer[0], numBytes); return image; }
bool C_TexturePNG::Load(S_Texture * texture, const char * filename) { std::vector<unsigned char> buffer, image; LodePNG::loadFile(buffer, filename); LodePNG::Decoder decoder; decoder.decode(image, buffer); if(decoder.hasError()) return false; texture->width = decoder.getWidth(); texture->height = decoder.getHeight(); texture->bpp = decoder.getBpp(); texture->imageData = new GLubyte[image.size()]; std::copy(image.begin(), image.end(), texture->imageData); texture->type = GL_RGBA; return true; }
//lodepng용 추가 함수 static void PrintLog(LodePNG::Decoder &decoder) { if(decoder.hasError()) { std::cout << "error " << decoder.getError() << ": " << LodePNG_error_text(decoder.getError()) << std::endl; } else { std::cout << "\n" << "w: " << decoder.getWidth() << "\n" << "h: " << decoder.getHeight() << "\n" << "bitDepth: " << decoder.getInfoPng().color.bitDepth << "\n" << "bpp: " << decoder.getBpp() << "\n" << "colorChannels: " << decoder.getChannels() << "\n" << "paletteSize: " << decoder.getInfoPng().color.palettesize / 4 << "\n" << "colorType: " << decoder.getInfoPng().color.colorType << "\n" << "compressionMethod: " << decoder.getInfoPng().compressionMethod << "\n" << "filterMethod: " << decoder.getInfoPng().filterMethod << "\n" << "interlaceMethod: " << decoder.getInfoPng().interlaceMethod << "\n"; for(size_t i = 0; i < decoder.getInfoPng().text.num; i++) { std::cout << decoder.getInfoPng().text.keys[i] << ": " << decoder.getInfoPng().text.strings[i] << "\n"; } } }
// Load image from file [true = success, false otherwise] bool PNG::load(string pathname){ std::vector<unsigned char> buffer; LodePNG::loadFile(buffer, pathname); //load the image file with given filename LodePNG::Decoder decoder; decoder.inspect(buffer); if (decoder.isGreyscaleType()){ decoder.getInfoRaw().color.colorType = 0; decoder.getInfoRaw().color.bitDepth = 16; // is grayscale } decoder.decode(image, buffer); width = decoder.getWidth(); height = decoder.getHeight(); if(decoder.hasError()) { return false; } return true; }
static bool Load(Image *img, ImageDesc *desc, uchar *data, int data_size) { //lodepng를 기반으로 적절히 로딩하기 SR_ASSERT(data != NULL); SR_ASSERT(data_size > 0); img->image_data_.clear(); LodePNG::Decoder decoder; decoder.decode(img->image_data(), data, data_size); if(decoder.hasError()) { return false; } else { desc->width = decoder.getWidth(); desc->height = decoder.getHeight(); desc->bit_depth = decoder.getInfoPng().color.bitDepth; desc->bpp = decoder.getBpp(); desc->color_channels = decoder.getChannels(); desc->is_grayscale = decoder.isGreyscaleType() > 0 ? true : false; desc->is_alpha = decoder.isAlphaType() > 0 ? true : false; return true; } }
// Entry point. int main(int argc, char *argv[]) { printf("------------------------------------------\n" "------------------------------------------\n" " lemmings_graphical_object by Mathew Carr \n" "------------------------------------------\n" "---------[ http://www.mrdictionary.net ]--\n" "------------------------------------------\n" "\n"); // Error if you don't supply the correct number of arguments. They must all be there. if (argc != IDEAL_NO_MAIN_ARGUMENTS) { printf("Bad arguments.\n" "Expected lemmings_graphical_object, then the following parameters:\n" " - SOURCE_DIRECTORY A path which the program can lop 00.png onto to find \n" " your images. \n" " - GRAPHICAL_OBJECT_TYPE [ 0 exit | 1 entrance | 2 trap ]\n" " [ 3 hazard | 4 uninteractive | 5 water ]\n" " - NO_IMAGES How many images are there in total?\n" " - NO_PRIMARY_IMAGES (TRAPS) How many images in the primary animation?\n" " - NO_SECONDARY_IMAGES (TRAPS) How many images in the secondary animation?\n" " - REPRESENTING_FRAME What frame should be used as preview in LDS Builder?\n" " - TRANSPARENT_COLOUR Which is the transparent colour in the source images?\n" " - HANDLE_X Identify the active coordinate within the object.\n" " - HANDLE_Y Identify the active coordinate within the object.\n" " - ACTIVE_ZONE_X1 Identify the active zone for exits, traps and hazards.\n" " - ACTIVE_ZONE_Y1 Identify the active zone for exits, traps and hazards.\n" " - ACTIVE_ZONE_X2 Identify the active zone for exits, traps and hazards.\n" " - ACTIVE_ZONE_Y2 Identify the active zone for exits, traps and hazards.\n" " - FLAGS What special flag numbers should be applied?.\n" " - DESCRIPTIVE_NAME 15 character description for the object. (NO SPACES)\n" " - OUTPUT_FILE_NAME Specify a .LGO output file name.\n"); return 1; } // If the output file exists, error. if (file_exists(argv[MAIN_ARGUMENT_OUTPUT_FILE_NAME])) { printf("Output file exists: Please delete it first.\n"); return 1; } // Parse parameters: int graphical_object_type = 0; int no_images = 0; int no_primary_images = 0; int no_secondary_images = 0; int representing_frame = 0; int transparent_colour = 0; int handle_x = 0; int handle_y = 0; int active_zone_x1 = 0; int active_zone_y1 = 0; int active_zone_x2 = 0; int active_zone_y2 = 0; int flags = 0; char descriptive_name[16] = {0}; sscanf(argv[MAIN_ARGUMENT_GRAPHICAL_OBJECT_TYPE], "%d", &graphical_object_type); printf("Interpreted graphical object type: %d...", graphical_object_type); if ((graphical_object_type < 0) || (graphical_object_type > 5)) { printf("\nGraphical object parameter out of range.\n"); return 1; } const char *GRAPHICAL_OBJECT_TYPE_DESCRIPTION[6] = {"Exit", "Entrance", "Trap", "Hazard", "Uninteractive", "Water",}; printf(" %s\n", GRAPHICAL_OBJECT_TYPE_DESCRIPTION[graphical_object_type]); sscanf(argv[MAIN_ARGUMENT_NO_IMAGES], "%d", &no_images); printf("Interpreted no images parameter: %d.\n", no_images); if (no_images <= 0) { printf("Don't supply a negative number or zero for number of images!\n"); return 1; } sscanf(argv[MAIN_ARGUMENT_NO_PRIMARY_IMAGES], "%d", &no_primary_images); printf("Interpreted no primary images parameter: %d.\n", no_primary_images); if (no_primary_images < 0) { printf("Don't supply a negative number for number of primary images!\n"); return 1; } sscanf(argv[MAIN_ARGUMENT_NO_SECONDARY_IMAGES], "%d", &no_secondary_images); printf("Interpreted no secondary images parameter: %d.\n", no_secondary_images); if (no_secondary_images < 0) { printf("Don't supply a negative number for number of secondary images!\n"); return 1; } sscanf(argv[MAIN_ARGUMENT_REPRESENTING_FRAME], "%d", &representing_frame); printf("Interpreted representing frame parameter: %d.\n", representing_frame); if ((representing_frame < 0) || (representing_frame >= no_images)) { printf("Out of range parameter for representing frame!\n"); return 1; } sscanf(argv[MAIN_ARGUMENT_TRANSPARENT_COLOUR], "%d", &transparent_colour); printf("Interpreted transparent colour parameter: %d.\n", transparent_colour); if (transparent_colour < 0) { printf("Don't supply a negative number for transparent colour parameter!\n"); return 1; } sscanf(argv[MAIN_ARGUMENT_HANDLE_X], "%d", &handle_x); sscanf(argv[MAIN_ARGUMENT_HANDLE_Y], "%d", &handle_y); printf("Interpreted handle parameters: %d, %d.\n", handle_x, handle_y); sscanf(argv[MAIN_ARGUMENT_ACTIVE_ZONE_X1], "%d", &active_zone_x1); sscanf(argv[MAIN_ARGUMENT_ACTIVE_ZONE_Y1], "%d", &active_zone_y1); sscanf(argv[MAIN_ARGUMENT_ACTIVE_ZONE_X2], "%d", &active_zone_x2); sscanf(argv[MAIN_ARGUMENT_ACTIVE_ZONE_Y2], "%d", &active_zone_y2); printf("Interpreted active zone parameters: %d, %d, %d, %d.\n", active_zone_x1, active_zone_y1, active_zone_x2, active_zone_y2); sscanf(argv[MAIN_ARGUMENT_FLAGS], "%d", &flags); printf("Interpreted flags parameter: %d.\n", flags); // Copy the descriptive name over. strncpy(descriptive_name, argv[MAIN_ARGUMENT_DESCRIPTIVE_NAME], 15); descriptive_name[15] = 0x00; printf("Retrieved descriptive name: '%-15s'.\n" " 123456789012345\n", descriptive_name); // Set up a vector for storing graphical object frame pointers. // We're going to populate this as the images are loaded, // and then splurge them all out when the loading is // complete. std::vector<void *> graphical_object_graphic_pointers; // (LEMMINGS_GRAPHICAL_OBJECT_GRAPHIC *) // We don't have a header instance yet, so we need to prepare a temporary location // in which to store the extracted palette. u16 extracted_palette[16]; int read_width = 0, read_height = 0; // Loop until told to quit (condition: loaded N images as specified in parameter) for (int frame = 0; frame < no_images; frame++) { // This decoder will decode the incoming PNG images. LodePNG::Decoder decoder; // This stores the PNG file in memory while it is being worked on. std::vector<unsigned char> buffer; // This stores the PNG decompressed image in memory while it is being worked on. std::vector<unsigned char> image; // This holds the filename of the file we're going to load char incoming_image_filename[16384]; sprintf(incoming_image_filename, "%s%02d.png", argv[MAIN_ARGUMENT_SOURCE_DIRECTORY], frame); printf("%s... ", incoming_image_filename); // Convert image filename into a std::string using this constructor. std::string string_incoming_image_filename = std::string(incoming_image_filename); // Load in the terrain image PNG. LodePNG::loadFile(buffer, string_incoming_image_filename); // Decode the image, retaining the image pixel index values. decoder.decodeGeneric(image, buffer); // Check for error here. If there's an error, we're done. if (decoder.hasError()) { if (decoder.getError() == 48) { printf("\nHold it! LodePNG error 48.\nDoes '%s' exist?\n", incoming_image_filename); } else { printf("\nHold it! LodePNG error != 48.\nMalformed PNG: '%s'?\n", incoming_image_filename); } return 1; } // Get image information. // Get the width and height from the first image. if (frame == 0) { read_width = decoder.getWidth(); read_height = decoder.getHeight(); } LodePNG::Decoder::Info image_info_struct = decoder.getInfo(); // Get the palette size. unsigned long paletteSize = image_info_struct.paletteSize; printf("has %d colours.\n", paletteSize); // This eventuality is very, very bad. if ((paletteSize > 256) || (paletteSize == 0)) { printf("Detected truecolour, dying!\n"); // Destroy ALL objects in the vector, and terminate. for (int t = 0; t < graphical_object_graphic_pointers.size(); t++) { printf("Killing graphic object %d.\n", t); delete[] ((unsigned char *)(graphical_object_graphic_pointers[t])); } return 1; } // Determine the amount of memory required to store a LEMMINGS_TEXTURE_ARCHIVE_TEXTURE // holding this image. // This is measured in bytes. int memory_size_required = read_width * read_height; // Increase this to the next word. int memory_size_required_total = to_next(memory_size_required + sizeof(LEMMINGS_GRAPHICAL_OBJECT_GRAPHIC), 4); printf("Reserved %6d bytes (%2d + %6d): %3d colour %4d by %4d texture.\n", memory_size_required_total, sizeof(LEMMINGS_GRAPHICAL_OBJECT_GRAPHIC), memory_size_required, paletteSize, read_width, read_height); // Reserve memory for this graphic object graphic. LEMMINGS_GRAPHICAL_OBJECT_GRAPHIC *new_graphic_object_graphic = (LEMMINGS_GRAPHICAL_OBJECT_GRAPHIC *)(new unsigned char[memory_size_required_total]); // Blank the graphic object graphic. memset((void *)new_graphic_object_graphic, 0, memory_size_required_total); // At this pointer to the vector of pointers. graphical_object_graphic_pointers.push_back((void *)(new_graphic_object_graphic)); // Now all we have to do, is set the relevant fields in new_graphic_object_graphic, // then move onto the image. new_graphic_object_graphic->graphic_size = memory_size_required_total; // Rob the bytes from the buffer: for (int output_byte = 0; output_byte < image.size(); output_byte++) { // Copy the byte from the image vector into the data array. // The transparent colour parameter tells the program what colour // should be transparent. // This means that the specified colour should -become zero- when passed through the program. // We need to swap the transparent colour and zero. if (image[output_byte] == transparent_colour) { new_graphic_object_graphic->data[output_byte] = 0; } else if (image[output_byte] == 0) { new_graphic_object_graphic->data[output_byte] = transparent_colour; } else new_graphic_object_graphic->data[output_byte] = image[output_byte]; } // Extract the palette from the first graphic: if (frame == 0) { for (int palette_entry = 0; palette_entry < (min(16, paletteSize)); palette_entry++) { int i_r, i_g, i_b; // These are the incoming palette colours. int nds_r, nds_g, nds_b; // These are the incoming colours reduced to 15-bit. i_r = image_info_struct.palette[0 + palette_entry * 4]; i_g = image_info_struct.palette[1 + palette_entry * 4]; i_b = image_info_struct.palette[2 + palette_entry * 4]; // Reduce the colours to 15 bit. nds_r = (int)((31.9f * ((float)(i_r))) / 255.0f); nds_g = (int)((31.9f * ((float)(i_g))) / 255.0f); nds_b = (int)((31.9f * ((float)(i_b))) / 255.0f); // This macro will convert 5 bit colour channel values into a composite 15 bit NDS colour with enabled alpha. #define RGB15A(r,g,b) ((1<<15) | ((b)<<10) | ((g)<<5) | (r)) u16 nds_colour = RGB15A(nds_r, nds_g, nds_b); // Fill in the palette of the level using the colours from the first graphic if (palette_entry == transparent_colour) { printf("This colour is transparent. Ignoring.\n"); } else if (palette_entry == 0) { if (!(transparent_colour >= 16)) { printf("Extracted colour %3d: R: %2d G: %2d B: %2d\n", transparent_colour, nds_r, nds_g, nds_b); extracted_palette[transparent_colour] = nds_colour; } else { printf("Transparent colour lies >= 0x10, so we'll ignore that colour.\n"); } } else { printf("Extracted colour %3d: R: %2d G: %2d B: %2d\n", palette_entry, nds_r, nds_g, nds_b); extracted_palette[palette_entry] = nds_colour; } } } } printf("Forcing manic magenta on colour zero.\n"); extracted_palette[0] = 0xFC1F; // This is measured in bits, taken to the next byte, then divided again to get the number of bytes. int memory_size_required_for_header_object_offset_array = no_images * sizeof(u32); // Increase this to the next word. int memory_size_required_for_header_total = to_next(memory_size_required_for_header_object_offset_array + sizeof(LEMMINGS_GRAPHICAL_OBJECT_HEADER), 4); printf("Reserved %4d bytes (%2d + %4d): Header must direct to %d objects.\n", memory_size_required_for_header_total, sizeof(LEMMINGS_GRAPHICAL_OBJECT_HEADER), memory_size_required_for_header_object_offset_array, no_images); // Store general information in the header. LEMMINGS_GRAPHICAL_OBJECT_HEADER *generated_header = (LEMMINGS_GRAPHICAL_OBJECT_HEADER *)new unsigned char[memory_size_required_for_header_total]; // Blank the header. memset((void *)generated_header, 0, memory_size_required_for_header_total); // Populate header. #define LEMMINGS_LEVEL_VERSION 7 generated_header->version_number = LEMMINGS_LEVEL_VERSION; generated_header->graphical_object_type = graphical_object_type; generated_header->graphic_width = read_width; generated_header->graphic_height = read_height; generated_header->no_total_frames = no_images; generated_header->no_primary_frames = no_primary_images; generated_header->no_secondary_frames = no_secondary_images; generated_header->representing_frame = representing_frame; generated_header->handle_x = handle_x; generated_header->handle_y = handle_y; generated_header->active_zone_x1 = active_zone_x1; generated_header->active_zone_y1 = active_zone_y1; generated_header->active_zone_x2 = active_zone_x2; generated_header->active_zone_y2 = active_zone_y2; generated_header->active_flags = flags; memcpy(generated_header->graphical_object_name, descriptive_name, 16); // Generate offsets and file size. int cumulative_offset = memory_size_required_for_header_total; int graphic_position = 0; for (int t = 0; t < no_images; graphic_position++, t++) { // Store the current cumulative offset as the offset to this graphic. generated_header->graphic_offsets[graphic_position] = cumulative_offset; printf("Graphic %3d at %6d bytes. (My length is %6d)\n", t, cumulative_offset, ((LEMMINGS_GRAPHICAL_OBJECT_GRAPHIC *)(graphical_object_graphic_pointers[t]))->graphic_size); // Advance the offset by the length of this texture chunk. cumulative_offset += ((LEMMINGS_GRAPHICAL_OBJECT_GRAPHIC *)(graphical_object_graphic_pointers[t]))->graphic_size; } printf("\nFinal length: %6d bytes.\n", cumulative_offset); // Copy palette for (int palette_entry = 0; palette_entry < 16; palette_entry++) { generated_header->ideal_palette[palette_entry] = extracted_palette[palette_entry]; } // The cumulative offset will contain the length of the final file! generated_header->graphical_object_file_size = cumulative_offset; // Open output file. FILE *output_file = fopen(argv[MAIN_ARGUMENT_OUTPUT_FILE_NAME], "wb"); // Write header, then textures. fwrite(generated_header, 1, memory_size_required_for_header_total, output_file); for (int t = 0; t < no_images; t++) { // Write texture. fwrite(graphical_object_graphic_pointers[t], 1, ((LEMMINGS_GRAPHICAL_OBJECT_GRAPHIC *)(graphical_object_graphic_pointers[t]))->graphic_size, output_file); } // Close output file fclose(output_file); // Epilogue: // Construct a final string. char final_output_result_string[2048]; sprintf(final_output_result_string, "Created %s (%d bytes):\n%d graphics (%d/%d).\n", argv[MAIN_ARGUMENT_OUTPUT_FILE_NAME], generated_header->graphical_object_file_size, generated_header->no_total_frames, generated_header->no_primary_frames, generated_header->no_secondary_frames); // Destroy ALL objects in the vectors, and terminate. for (int t = 0; t < no_images; t++) { printf("Killing graphic %3d. (%d bytes)\n", t, ((LEMMINGS_GRAPHICAL_OBJECT_GRAPHIC *)(graphical_object_graphic_pointers[t]))->graphic_size); delete[] ((unsigned char *)(graphical_object_graphic_pointers[t])); } // Destroy the header array. printf("Killing header.\n"); delete[] ((unsigned char *)(generated_header)); printf(final_output_result_string); return 0; // At this point, I would like to thank Lode Vandevenne // without whom this application would not have been possible. // Kudos to you! LodePNG has performed admirably once again! }
GLuint createTexture(const char* filename) { std::vector< unsigned char > rawImage; LodePNG::loadFile( rawImage, filename ); LodePNG::Decoder decoder; std::vector< unsigned char > image; decoder.decode( image, rawImage.empty() ? 0 : &rawImage[0], (unsigned)rawImage.size() ); // // Flip and invert the PNG image since OpenGL likes to load everything // backwards from what is considered normal! // unsigned char *imagePtr = &image[0]; int halfTheHeightInPixels = decoder.getHeight() / 2; int heightInPixels = decoder.getHeight(); // Assuming RGBA for 4 components per pixel. int numColorComponents = 4; // Assuming each color component is an unsigned char. int widthInChars = decoder.getWidth() * numColorComponents; unsigned char *top = NULL; unsigned char *bottom = NULL; unsigned char temp = 0; for( int h = 0; h < halfTheHeightInPixels; ++h ) { top = imagePtr + h * widthInChars; bottom = imagePtr + (heightInPixels - h - 1) * widthInChars; for( int w = 0; w < widthInChars; ++w ) { // Swap the chars around. temp = *top; *top = *bottom; *bottom = temp; ++top; ++bottom; } } GLuint texid; //glEnable(GL_TEXTURE_2D); glGenTextures( 1, &texid ); glActiveTexture(GL_TEXTURE0); glBindTexture( GL_TEXTURE_2D, texid ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, decoder.getWidth(), decoder.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, &image[0] ); if (isGLError()) return -1; return texid; }