void CursorDescription::add_gridclipped_frames( const PixelBuffer &pixelbuffer, int xpos, int ypos, int width, int height, int xarray, int yarray, int array_skipframes, int xspace, int yspace) { int ystart = ypos; for (int y = 0; y < yarray; y++) { int xstart = xpos; for (int x = 0; x < xarray; x++) { if (y == yarray - 1 && x >= xarray - array_skipframes) break; if (xstart + width > pixelbuffer.get_width() || ystart + height > pixelbuffer.get_height()) throw Exception("add_gridclipped_frames: Outside pixelbuffer bounds"); impl->frames.push_back(CursorDescriptionFrame(pixelbuffer, Rect(xstart, ystart, xstart + width, ystart + height))); xstart += width + xspace; } ystart += height + yspace; } }
int main(int argc, const char* argv[]) { if (argc < 2) { std::cerr << "ERROR : Please specify a input file." << std::endl; exit(1); } std::string filename = argv[1]; Scene scene(filename); std::cout << filename << std::endl; PixelBuffer buf = RayTracer::rayTrace(scene); // file splitting code referenced form // http://www.cplusplus.com/reference/string/string/find_last_of/ int index = filename.find_last_of("/\\"); std::string path = filename.substr(0,index); std::string name = filename.substr(index+1); std::stringstream ss; ss << name; std::string namebase; std::getline(ss, namebase, '.'); buf.toFile(namebase); return 0; }
void Font::drawCachedGlyphBitmap(CachedGlyphInfo* glyph, int x, int y, uint8_t* bitmap, uint32_t bitmapWidth, uint32_t bitmapHeight, Rect* bounds, const float* pos) { int dstX = x + glyph->mBitmapLeft; int dstY = y + glyph->mBitmapTop; CacheTexture* cacheTexture = glyph->mCacheTexture; PixelBuffer* pixelBuffer = cacheTexture->getPixelBuffer(); uint32_t formatSize = PixelBuffer::formatSize(pixelBuffer->getFormat()); uint32_t alpha_channel_offset = PixelBuffer::formatAlphaOffset(pixelBuffer->getFormat()); uint32_t cacheWidth = cacheTexture->getWidth(); uint32_t srcStride = formatSize * cacheWidth; uint32_t startY = glyph->mStartY * srcStride; uint32_t endY = startY + (glyph->mBitmapHeight * srcStride); const uint8_t* cacheBuffer = pixelBuffer->map(); for (uint32_t cacheY = startY, bitmapY = dstY * bitmapWidth; cacheY < endY; cacheY += srcStride, bitmapY += bitmapWidth) { if (formatSize == 1) { memcpy(&bitmap[bitmapY + dstX], &cacheBuffer[cacheY + glyph->mStartX], glyph->mBitmapWidth); } else { for (uint32_t i = 0; i < glyph->mBitmapWidth; ++i) { bitmap[bitmapY + dstX + i] = cacheBuffer[cacheY + (glyph->mStartX + i)*formatSize + alpha_channel_offset]; } } } }
void Filter::applyToBuffer(PixelBuffer* buffer, float newStrength[]) { PixelBuffer* tempB; tempB = new PixelBuffer(buffer->getWidth(), buffer->getHeight(), buffer->getBackgroundColor()); for (int h = 0; h < buffer->getHeight(); h++) { for (int w = 0; w < buffer->getWidth(); w++) { ColorData c = buffer->getPixel(w, h); for (int mw = 0; mw < maskWidth; mw++) { for (int mh = 0; mh < maskHeight; mh++) { trans = mask[mw][mh]; ColorData maskC = buffer->getPixel((w - maskWidth/2 + mw), (h - maskHeight/2 + mh)); maskC = maskC * trans; c = c + maskC; } } c = c - buffer->getPixel(w, h); tempB->setPixel(w, h, c); } } buffer->copyPixelBuffer(tempB, buffer); delete tempB; }
CollisionOutline::CollisionOutline( IODevice &file, const std::string &file_extension, int alpha_limit, OutlineAccuracy accuracy, bool get_insides) { if( file_extension == "out" ) { OutlineProviderFile outline_provider(file); *this = CollisionOutline(outline_provider.get_contours(), outline_provider.get_size(), accuracy_raw ); } else { PixelBuffer pbuf = ImageProviderFactory::load(file, file_extension); if( pbuf.get_format() == tf_rgba8 ) { OutlineProviderBitmap outline_provider(pbuf, alpha_limit, get_insides); *this = CollisionOutline(outline_provider.get_contours(), outline_provider.get_size(), accuracy ); } else { OutlineProviderBitmap outline_provider(pbuf, alpha_limit, get_insides); *this = CollisionOutline(outline_provider.get_contours(), outline_provider.get_size(), accuracy_raw ); } } set_rotation_hotspot(origin_center); }
int main(int argv, char **argc) { Scene *scene = new Scene(); std::ifstream sceneFile("scene.txt"); if (!sceneFile) return 123; std::string s((std::istreambuf_iterator<char>(sceneFile)), std::istreambuf_iterator<char>()); JsonGroup json(s); JsonArray objects(json.at("objects").Array()); JsonArray lights(json.at("lights").Array()); JsonGroup camera(json.at("camera").Group()); Camera cam = Camera(Vector3D(camera.at("position").Array().at(0).Float(), camera.at("position").Array().at(1).Float(), camera.at("position").Array().at(2).Float()), Vector3D(camera.at("target").Array().at(0).Float(), camera.at("target").Array().at(1).Float(), camera.at("target").Array().at(2).Float()), camera.at("roll").Float()); for (int i = 0; i < objects.size(); i++){ JsonGroup object = objects.at(i).Group(); if (object.at("type").String().compare("sphere") == 0){ scene->add(new SphereObject(Vector3D(object.at("position").Array().at(0).Float(), object.at("position").Array().at(1).Float(), object.at("position").Array().at(2).Float()), object.at("radius").Float(), Color(object.at("color").Array().at(0).Integer(), object.at("color").Array().at(1).Integer(), object.at("color").Array().at(2).Integer()), object.at("reflection").Float(), object.at("refraction").Float(), object.at("ior").Float())); } if (object.at("type").String().compare("plane") == 0){ scene->add(new PlaneObject(Vector3D(object.at("position").Array().at(0).Float(), object.at("position").Array().at(1).Float(), object.at("position").Array().at(2).Float()), Vector3D(object.at("normal").Array().at(0).Float(), object.at("normal").Array().at(1).Float(), object.at("normal").Array().at(2).Float()), Color(object.at("color").Array().at(0).Array().at(0).Integer(), object.at("color").Array().at(0).Array().at(1).Integer(), object.at("color").Array().at(0).Array().at(2).Integer()), Color(object.at("color").Array().at(1).Array().at(0).Integer(), object.at("color").Array().at(1).Array().at(1).Integer(), object.at("color").Array().at(1).Array().at(2).Integer()), object.at("reflection").Float(), object.at("refraction").Float(), object.at("ior").Float())); } if (object.at("type").String().compare("triangle") == 0){ scene->add(new TriangleObject(Vector3D(object.at("vertices").Array().at(0).Array().at(0).Integer(), object.at("vertices").Array().at(0).Array().at(1).Integer(), object.at("vertices").Array().at(0).Array().at(2).Integer()), Vector3D(object.at("vertices").Array().at(1).Array().at(0).Integer(), object.at("vertices").Array().at(1).Array().at(1).Integer(), object.at("vertices").Array().at(1).Array().at(2).Integer()), Vector3D(object.at("vertices").Array().at(2).Array().at(0).Integer(), object.at("vertices").Array().at(2).Array().at(1).Integer(), object.at("vertices").Array().at(2).Array().at(2).Integer()), Color(object.at("color").Array().at(0).Integer(), object.at("color").Array().at(1).Integer(), object.at("color").Array().at(2).Integer()), object.at("reflection").Float(), object.at("refraction").Float(), object.at("ior").Float())); } } for (int i = 0; i < lights.size(); i++){ JsonGroup light = lights.at(i).Group(); if (light.at("type").String().compare("point") == 0){ scene->add(new PointLight(Vector3D(light.at("position").Array().at(0).Float(), light.at("position").Array().at(1).Float(), light.at("position").Array().at(2).Float()))); } if (light.at("type").String().compare("direction") == 0){ scene->add(new DirectionLight(Vector3D(light.at("direction").Array().at(0).Float(), light.at("direction").Array().at(1).Float(), light.at("direction").Array().at(2).Float()))); } } Renderer *renderer = new Renderer(); PixelBuffer *buffer = renderer->render(scene, &cam, camera.at("resolution").Array().at(0).Integer(), camera.at("resolution").Array().at(1).Integer(), camera.at("raydepth").Integer()); //buffer->savePPM("test.ppm"); buffer->saveBMP("image.bmp"); return 0; }
TransferTexture::TransferTexture(GraphicContext &gc, const PixelBuffer &pbuff, PixelBufferDirection direction, BufferUsage usage) { GraphicContextProvider *gc_provider = gc.get_provider(); PixelBufferProvider *provider = gc_provider->alloc_pixel_buffer(); *this = TransferTexture(provider); provider->create(pbuff.get_data(), pbuff.get_size(), direction, pbuff.get_format(), usage); }
HSVSprite::HSVSprite(Canvas &canvas, HSVSpriteBatch *batcher, const std::string &image_filename) : batcher(batcher) { PixelBuffer image = ImageProviderFactory::load(image_filename); Subtexture subtexture = batcher->alloc_sprite(canvas, image.get_size()); geometry = subtexture.get_geometry(); texture = subtexture.get_texture(); texture.set_subimage(canvas, geometry.get_top_left(), image, image.get_size()); }
Texture2D::Texture2D( GraphicContext &context, const std::string &filename, const FileSystem &fs, const ImageImportDescription &import_desc) { PixelBuffer pb = ImageProviderFactory::load(filename, fs, std::string()); pb = import_desc.process(pb); *this = Texture2D(context, pb.get_width(), pb.get_height(), import_desc.is_srgb() ? tf_srgb8_alpha8 : tf_rgba8); set_subimage(context, Point(0, 0), pb, Rect(pb.get_size()), 0); impl->provider->set_wrap_mode(impl->wrap_mode_s, impl->wrap_mode_t); }
Texture *NGE_SDL_Texture_Load(const char *path) { PixelBuffer *buf; Texture *tex = NULL; SDL_Surface *surface; Sint32 i, j; Uint8 *p, *q; Uint8 r, g, b, a; if(path) { if((surface = IMG_Load(path))) { //SDL_LockSurface(surface); -> peut poser des pb buf = new PixelBuffer(surface->format->BytesPerPixel, surface->w, surface->h); p = (Uint8 *) surface->pixels; //for(i = 0; i < surface->h; i++) { for(i = surface->h - 1; i >= 0; i--) { q = buf->getPixelAddr(0, i); for(j = 0; j < surface->w; j++) { r = p[j * surface->format->BytesPerPixel + 0]; g = p[j * surface->format->BytesPerPixel + 1]; b = p[j * surface->format->BytesPerPixel + 2]; if(surface->format->BytesPerPixel == 4) a = p[j * surface->format->BytesPerPixel + 3]; else; q[j * surface->format->BytesPerPixel + 0] = r; q[j * surface->format->BytesPerPixel + 1] = g; q[j * surface->format->BytesPerPixel + 2] = b; if(surface->format->BytesPerPixel == 4) q[j * surface->format->BytesPerPixel + 3] = a; else; } //p += surface->format->BytesPerPixel * surface->w; p += surface->format->BytesPerPixel * surface->w; } tex = new Texture(); tex->setPixelBuffer(buf); // tex->updateInGC(); //SDL_UnlockSurface(surface); SDL_FreeSurface(surface); } else printf("Texture \"%s\" not loaded: not found.\n", path); } else; return tex; }
void drawGridGradientCircle(PixelBuffer& buf) { float midX = buf.width() / 2.f; float midY = buf.height() / 2.f; float maxDistSquared = midX * midX + midY * midY; for (int i=0; i < buf.width(); i++) { for (int j=0; j < buf.height(); j++) { float distX = (midX - i); float distY = (midY - j); float distSquared = distX * distX + distY * distY; float t = 1 - distSquared / maxDistSquared; if ( t < 0.90) { if ( (i + j) % 2 == 0 ) { buf.setPixel(i,j, t * .75, t * .75, t * .75); } else { buf.setPixel(i,j, t * .25, t * .25, t * .25); } } else { if (fmod(t * 1000.f, 1.f) < .5) { buf.setPixel(i,j, 0.8f,0.3f,0.1f); } else { buf.setPixel(i,j, 0.9,.51,.22); } } } } }
void SWRenderDisplayWindowProvider::draw_image(const Rect &dest, const PixelBuffer &image, const Rect &src) { XImage ximage; memset(&ximage, 0, sizeof(ximage)); ximage.width = image.get_width(); ximage.height = image.get_height(); ximage.format = ZPixmap; ximage.data = (char *) image.get_data(); ximage.byte_order = LSBFirst; int image_pitch = image.get_pitch(); int image_bpp = image.get_bytes_per_pixel(); if (image_bpp == 1) { ximage.bitmap_unit = 8; } else if (image_bpp == 2) { ximage.bitmap_unit = 16; } else if (image_bpp == 3) { ximage.bitmap_unit = 24; } else ximage.bitmap_unit = 32; ximage.bitmap_pad = ximage.bitmap_unit; ximage.bitmap_bit_order = LSBFirst; ximage.depth = 24; ximage.bytes_per_line = image_pitch; ximage.bits_per_pixel = image_bpp * 8; ximage.red_mask = 0x00ff0000; ximage.green_mask = 0x0000ff00; ximage.blue_mask = 0x000000ff; if (!XInitImage(&ximage)) { throw Exception("Cannot initialise image"); } GC xgc = XCreateGC(window.get_display(), window.get_window(), 0, NULL); XPutImage(window.get_display(), window.get_window(), xgc, &ximage, src.left, src.top, dest.left, dest.top, src.get_width(), src.get_height()); XFreeGC(window.get_display(), xgc); }
App::App() : m_numRows(1) , m_numCols(1) , m_drawType(kCircle) , m_finalImage(0) { QmlDocument *qml = QmlDocument::create("main.qml"); qml->setContextProperty("cs", this); AbstractPane *root = qml->createRootNode<AbstractPane>(); Application::setScene(root); if (root != 0) { TextField* textField = root->findChild<TextField*>("numRows"); connect(textField, SIGNAL(touch(bb::cascades::TouchEvent*)), this, SLOT(onIntFieldTouched(bb::cascades::TouchEvent*))); connect(textField, SIGNAL(textChanged(QString)), this, SLOT(onNumRowsChanged(QString))); textField = root->findChild<TextField*>("numCols"); connect(textField, SIGNAL(touch(bb::cascades::TouchEvent*)), this, SLOT(onIntFieldTouched(bb::cascades::TouchEvent*))); connect(textField, SIGNAL(textChanged(QString)), this, SLOT(onNumColsChanged(QString))); // Four hard-coded buttons. // Three select an image from the asset... Button* button = root->findChild<Button*>("img1"); connect(button, SIGNAL(clicked()), this, SLOT(onImageSelected())); button = root->findChild<Button*>("img2"); connect(button, SIGNAL(clicked()), this, SLOT(onImageSelected())); button = root->findChild<Button*>("img3"); connect(button, SIGNAL(clicked()), this, SLOT(onImageSelected())); // ...and two specify images to draw on demand button = root->findChild<Button*>("circle"); connect(button, SIGNAL(clicked()), this, SLOT(onCircleSelected())); button = root->findChild<Button*>("square"); connect(button, SIGNAL(clicked()), this, SLOT(onSquareSelected())); m_finalImage = root->findChild<ImageView*>("finalImage"); // Set the image on the circle and the square PixelBuffer pixelBuffer; button = root->findChild<Button*>("circle"); pixelBuffer = drawCircle(QSize(50,50)); button->setImage(pixelBuffer.getBuffer()); button = root->findChild<Button*>("square"); pixelBuffer = drawSquare(QSize(50,50)); button->setImage(pixelBuffer.getBuffer()); }
void SWRenderDisplayWindowProvider::draw_image(HDC hdc, const Rect &dest, const PixelBuffer &image, const Rect &src) { BITMAPV5HEADER bmp_header; memset(&bmp_header, 0, sizeof(BITMAPV5HEADER)); bmp_header.bV5Size = sizeof(BITMAPV5HEADER); bmp_header.bV5Width = image.get_width(); bmp_header.bV5Height = -image.get_height(); bmp_header.bV5Planes = 1; bmp_header.bV5BitCount = 32; bmp_header.bV5Compression = BI_BITFIELDS; bmp_header.bV5RedMask = 0x00FF0000; //image.get_red_mask(); bmp_header.bV5GreenMask = 0x0000FF00; //image.get_green_mask(); bmp_header.bV5BlueMask = 0x0000000FF; //image.get_blue_mask(); bmp_header.bV5AlphaMask = 0xFF000000; //image.get_alpha_mask(); //StretchDIBits(hdc, dest.left, dest.top, dest.get_width(), dest.get_height(), src.left, src.top, src.get_width(), src.get_height(), image.get_data(), (BITMAPINFO *) &bmp_header, DIB_RGB_COLORS, SRCCOPY); SetDIBitsToDevice(hdc, dest.left, dest.top, dest.get_width(), dest.get_height(), src.left, image.get_height()-src.bottom, 0, image.get_height(), image.get_data(), (BITMAPINFO *) &bmp_header, DIB_RGB_COLORS); }
Texture2D::Texture2D(GraphicContext &context, const PixelBuffer &image, const Rect &src_rect, bool is_srgb) { *this = Texture2D(context, src_rect.get_width(), src_rect.get_height(), is_srgb ? tf_srgb8_alpha8 : tf_rgba8); set_pixel_ratio(image.get_pixel_ratio()); set_subimage(context, Point(0, 0), image, src_rect, 0); impl->provider->set_wrap_mode(impl->wrap_mode_s, impl->wrap_mode_t); }
void Font::drawCachedGlyphBitmap(CachedGlyphInfo* glyph, int x, int y, uint8_t* bitmap, uint32_t bitmapWidth, uint32_t bitmapHeight, Rect* bounds, const float* pos) { int dstX = x + glyph->mBitmapLeft; int dstY = y + glyph->mBitmapTop; CacheTexture* cacheTexture = glyph->mCacheTexture; uint32_t cacheWidth = cacheTexture->getWidth(); uint32_t startY = glyph->mStartY * cacheWidth; uint32_t endY = startY + (glyph->mBitmapHeight * cacheWidth); PixelBuffer* pixelBuffer = cacheTexture->getPixelBuffer(); const uint8_t* cacheBuffer = pixelBuffer->map(); for (uint32_t cacheY = startY, bitmapY = dstY * bitmapWidth; cacheY < endY; cacheY += cacheWidth, bitmapY += bitmapWidth) { memcpy(&bitmap[bitmapY + dstX], &cacheBuffer[cacheY + glyph->mStartX], glyph->mBitmapWidth); } }
/// A filter that reduce the number of possible colors by binning each color value into the the ///number of bins specified. /// Inherits from Filter ColorData FQuantize::generatePixel(const PixelBuffer &buffer, int x, int y) const { ColorData c = buffer.getPixel(x, y); float red = c.getRed(); float blue = c.getBlue(); float green = c.getGreen(); int steps = m_bins-1; red = round(red*steps)/steps; green = round(green*steps)/steps; blue = round(blue*steps)/steps; ColorData output(red, green, blue); return output; }
PixelBuffer* IPNGHandler::loadImage(const std::string fileName) { cout << "IPNGHandler LOAD IMAGE" << endl; printf("IPNGHandler -> loadImage\n"); PixelBuffer* loadedImageBuffer = NULL; png_image image; memset(&image, 0, (sizeof image)); image.version = PNG_IMAGE_VERSION; if (png_image_begin_read_from_file(&image, fileName.c_str())) { loadedImageBuffer = new PixelBuffer(image.width, image.height, ColorData(0.0,0.0,0.0)); png_bytep buffer; image.format = PNG_FORMAT_RGBA; buffer = new png_byte[PNG_IMAGE_SIZE(image)]; if (buffer && png_image_finish_read(&image, NULL, buffer, 0, NULL)) { cout << "Finished buffer read" << endl; for (int y = 0; y < image.height; y++) { for (int x = 0; x < image.width; x++) { int r, g, b, a = 0; r = (int)buffer[(y*image.width*4)+(x*4)]; g = (int)buffer[(y*image.width*4)+(x*4)+1]; b = (int)buffer[(y*image.width*4)+(x*4)+2]; a = (int)buffer[(y*image.width*4)+(x*4)+3]; loadedImageBuffer->setPixel(x, image.height-(y+1), ColorData(r/255.0f,g/255.0f,b/255.0f,a/255.0f)); } } } delete[] buffer; } cout << "returning loaded image buffer" << endl; return loadedImageBuffer; }
void X11Window::set_large_icon(const PixelBuffer &image) { unsigned int size = (image.get_width() * image.get_height()) + 2; // header is 2 ints unsigned long* data = (unsigned long*)malloc(size * sizeof(unsigned long)); // set header data[0] = image.get_width(); data[1] = image.get_height(); // icon data is expected as ARGB PixelBuffer transformed_image = image.to_format(tf_bgra8); // on 64bit systems, the destination buffer is 64 bit per pixel // thus, we have to copy each pixel individually (no memcpy) for (int y = 0; y < image.get_height(); ++y) { const uint32_t* src = (const uint32_t*)transformed_image.get_line(y); unsigned long* dst = &data[2 + (y * image.get_width())]; for (int x = 0; x < image.get_width(); ++x) { dst[x] = src[x]; } } // set icon geometry unsigned long* geom = (unsigned long*)malloc(4 * sizeof(unsigned long)); geom[0] = geom[1] = 0; // x, y geom[2] = image.get_width(); geom[3] = image.get_height(); Atom propertyGeom = XInternAtom(handle.display, "_NET_WM_ICON_GEOMETRY", 0); XChangeProperty(handle.display, handle.window, propertyGeom, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)geom, 4); // set icon data Atom property = XInternAtom(handle.display, "_NET_WM_ICON", 0); XChangeProperty(handle.display, handle.window, property, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)data, size); }
PixelBuffer IconSet_Impl::create_bitmap_data(const PixelBuffer &image) { // Convert pixel buffer to DIB compatible format: PixelBuffer bmp_image = image.to_format(tf_bgra8); // Note that the APIs use pre-multiplied alpha, which means that the red, // green and blue channel values in the bitmap must be pre-multiplied with // the alpha channel value. For example, if the alpha channel value is x, // the red, green and blue channels must be multiplied by x and divided by // 0xff prior to the call. int w = bmp_image.get_width(); int h = bmp_image.get_height(); unsigned int *p = (unsigned int *) bmp_image.get_data(); for (int y = 0; y < h; y++) { int index = y * w; unsigned int *line = p + index; for (int x = 0; x < w; x++) { unsigned int a = ((line[x] >> 24) & 0xff); unsigned int r = ((line[x] >> 16) & 0xff); unsigned int g = ((line[x] >> 8) & 0xff); unsigned int b = (line[x] & 0xff); r = r * a / 255; g = g * a / 255; b = b * a / 255; line[x] = (a << 24) + (r << 16) + (g << 8) + b; } } // Flip image upside down for (int y = 0; y < h/2; y++) { for (int x = 0; x < w; x++) { unsigned int l1 = p[y*w+x]; unsigned int l2 = p[(w-1-y)*w+x]; p[(w-1-y)*w+x] = l1; p[y*w+x] = l2; } } return bmp_image; }
CollisionOutline::CollisionOutline( const PixelBuffer &pbuf, int alpha_limit, OutlineAccuracy accuracy) : impl(std::make_shared<CollisionOutline_Impl>()) { if( pbuf.get_format() == tf_rgba8 ) { OutlineProviderBitmap outline_provider(pbuf, alpha_limit); *this = CollisionOutline(outline_provider.get_contours(), outline_provider.get_size(), accuracy ); } else { OutlineProviderBitmap outline_provider(pbuf, alpha_limit); *this = CollisionOutline(outline_provider.get_contours(), outline_provider.get_size(), accuracy_raw ); } set_rotation_hotspot(origin_center); }
void Texture2DArray::set_image(GraphicContext &context, int array_index, const PixelBuffer &image, int level) { impl->provider->copy_from(context, 0, 0, array_index, level, image, image.get_size()); }
OutlineProviderBitmap_Impl::OutlineProviderBitmap_Impl( const PixelBuffer &pbuf, int alpha_limit, bool get_insides) : data(0), get_insides(get_insides), alpha_limit(alpha_limit), //double_precision(false), //consecutive_left_turns(0), //consecutive_right_turns(0), alpha_pixel(3), pb(pbuf), last_point(0,0), last_dir(DIR_LEFT) { if( pbuf.get_format() != tf_rgba8 ) { // the image contains no alpha - add only a rectangle Contour contour; contour.get_points().push_back( Pointf(0.0f, 0.0f) ); contour.get_points().push_back( Pointf(0.0f, float(height)) ); contour.get_points().push_back( Pointf(float(width), float(height)) ); contour.get_points().push_back( Pointf(float(width), 0.0f) ); contours.push_back(contour); return; } height = pbuf.get_height(); width = pbuf.get_width(); // allocate a grid of unsigned chars, this represents the corners between pixels. // We will only use the first 4 bits of each char: // (1 << 0) 0x1 : the pixel to the upper left // (1 << 1) 0x2 : the pixel to the upper right // (1 << 2) 0x4 : the pixel to the lower left // (1 << 3) 0x8 : the pixel to the lower right data = new unsigned char[(height+1)*(width+1)]; // The image part for(int y = 0; y <= height; y++) { for(int x = 0; x <= width; x++) { get_corner(x,y) = 0x0; if(is_opaque(x-1,y-1)) get_corner(x,y) |= 0x1; if(is_opaque(x,y-1)) get_corner(x,y) |= 0x2; if(is_opaque(x-1,y)) get_corner(x,y) |= 0x4; if(is_opaque(x,y)) get_corner(x,y) |= 0x8; } } find_contours(); }
GameTerrain::GameTerrain( GraphicContext &gc, const std::string &heightmap_png, const std::string &texture_png, const std::string &areas_png, const std::string &borders_png, int area_count, float vertical_scale) : num_vertices(0) { color_areas = PNGProvider::load(areas_png).to_format(tf_r8); PixelBuffer pb = PNGProvider::load(heightmap_png).to_format(tf_rgba8); int width = pb.get_width()-1; int height = pb.get_height()-1; num_vertices = width*height*3*4 /*+ width*6*2 + height*6*2 + 6*/; vertex_buffer = VertexArrayBuffer(gc, num_vertices*sizeof(Vertex)); vertex_buffer.lock(cl_access_write_only); Vertex *vertex_data = reinterpret_cast<Vertex *>(vertex_buffer.get_data()); int pitch = pb.get_pitch(); unsigned char *data = reinterpret_cast<unsigned char *>(pb.get_data()); for (int y = 0; y < height; y++) { unsigned int *line1 = reinterpret_cast<unsigned int *>(data + y*pitch); unsigned int *line2 = reinterpret_cast<unsigned int *>(data + (y+1)*pitch); Vertex *vertex_line = vertex_data + 3*4*width*y; for (int x = 0; x < width; x++) { float height1 = (line1[x] >> 24) * vertical_scale; float height2 = (line1[x+1] >> 24) * vertical_scale; float height3 = (line2[x] >> 24) * vertical_scale; float height4 = (line2[x+1] >> 24) * vertical_scale; float height5 = (height1 + height2 + height3 + height4) / 4.0f; Vertex *vertex_quad = vertex_line + x*3*4; Vec3f positions[12] = { Vec3f(x+0.0f, height1, y+0.0f), Vec3f(x+1.0f, height2, y+0.0f), Vec3f(x+0.5f, height5, y+0.5f), Vec3f(x+1.0f, height2, y+0.0f), Vec3f(x+1.0f, height4, y+1.0f), Vec3f(x+0.5f, height5, y+0.5f), Vec3f(x+1.0f, height4, y+1.0f), Vec3f(x+0.0f, height3, y+1.0f), Vec3f(x+0.5f, height5, y+0.5f), Vec3f(x+0.0f, height3, y+1.0f), Vec3f(x+0.0f, height1, y+0.0f), Vec3f(x+0.5f, height5, y+0.5f) }; for (int i = 0; i < 12; i++) vertex_quad[i].position = positions[i]; Vec3f normal1 = calc_normal(x, y, data, width, height, pitch); Vec3f normal2 = calc_normal(x+1, y, data, width, height, pitch); Vec3f normal3 = calc_normal(x, y+1, data, width, height, pitch); Vec3f normal4 = calc_normal(x+1, y+1, data, width, height, pitch); Vec3f normal5 = (normal1+normal2+normal3+normal4)/4.0f; vertex_quad[0].normal = normal1; vertex_quad[1].normal = normal2; vertex_quad[2].normal = normal5; vertex_quad[3].normal = normal2; vertex_quad[4].normal = normal4; vertex_quad[5].normal = normal5; vertex_quad[6].normal = normal4; vertex_quad[7].normal = normal3; vertex_quad[8].normal = normal5; vertex_quad[9].normal = normal3; vertex_quad[10].normal = normal1; vertex_quad[11].normal = normal5; } } vertex_data += width*height*3*4; /* for (int y = 0; y < height; y++) { unsigned int *line1 = reinterpret_cast<unsigned int *>(data + y*pitch); unsigned int *line2 = reinterpret_cast<unsigned int *>(data + (y+1)*pitch); float scale = 0.4f; float height1 = (line1[0] >> 24)*scale; float height2 = (line2[0] >> 24)*scale; float height3 = (line1[width] >> 24)*scale; float height4 = (line2[width] >> 24)*scale; vertex_data[y*6*2+0].position = Vec3f(0, -0.1f, (float)y); vertex_data[y*6*2+1].position = Vec3f(0, (float)height1, (float)y); vertex_data[y*6*2+2].position = Vec3f(0, (float)height2, (float)y+1); vertex_data[y*6*2+3].position = Vec3f(0, (float)height2, (float)y+1); vertex_data[y*6*2+4].position = Vec3f(0, -0.1f, (float)y+1); vertex_data[y*6*2+5].position = Vec3f(0, -0.1f, (float)y); vertex_data[y*6*2+11].position = Vec3f((float)width+1, -0.1f, (float)y); vertex_data[y*6*2+10].position = Vec3f((float)width+1, (float)height3, (float)y); vertex_data[y*6*2+9].position = Vec3f((float)width+1, (float)height4, (float)y+1); vertex_data[y*6*2+8].position = Vec3f((float)width+1, (float)height4, (float)y+1); vertex_data[y*6*2+7].position = Vec3f((float)width+1, -0.1f, (float)y+1); vertex_data[y*6*2+6].position = Vec3f((float)width+1, -0.1f, (float)y); for (int i = 0; i < 6; i++) vertex_data[y*6*2+i].normal = Vec3f(-1, 0, 0); for (int i = 0; i < 6; i++) vertex_data[y*6*2+6+i].normal = Vec3f(1, 0, 0); } vertex_data += height*6*2; unsigned int *line1 = reinterpret_cast<unsigned int *>(data); unsigned int *line2 = reinterpret_cast<unsigned int *>(data + height*pitch); for (int x = 0; x < width; x++) { float scale = 0.4f; float height1 = (line1[x] >> 24)*scale; float height2 = (line1[x+1] >> 24)*scale; float height3 = (line2[x] >> 24)*scale; float height4 = (line2[x+1] >> 24)*scale; vertex_data[x*6*2+5].position = Vec3f((float)x, -0.1f, 0); vertex_data[x*6*2+4].position = Vec3f((float)x, (float)height1, 0); vertex_data[x*6*2+3].position = Vec3f((float)x+1, (float)height2, 0); vertex_data[x*6*2+2].position = Vec3f((float)x+1, (float)height2, 0); vertex_data[x*6*2+1].position = Vec3f((float)x+1, -0.1f, 0); vertex_data[x*6*2+0].position = Vec3f((float)x, -0.1f, 0); vertex_data[x*6*2+6].position = Vec3f((float)x, -0.1f, (float)height+1); vertex_data[x*6*2+7].position = Vec3f((float)x, (float)height3, (float)height+1); vertex_data[x*6*2+8].position = Vec3f((float)x+1, (float)height4, (float)height+1); vertex_data[x*6*2+9].position = Vec3f((float)x+1, (float)height4, (float)height+1); vertex_data[x*6*2+10].position = Vec3f((float)x+1, -0.1f, (float)height+1); vertex_data[x*6*2+11].position = Vec3f((float)x, -0.1f, (float)height+1); for (int i = 0; i < 6; i++) vertex_data[x*6*2+i].normal = Vec3f(0, 0, -1); for (int i = 0; i < 6; i++) vertex_data[x*6*2+6+i].normal = Vec3f(0, 0, 1); } vertex_data += width*6*2; vertex_data[0].position = Vec3f(0, -0.1f, 0); vertex_data[1].position = Vec3f((float)width, -0.1f, 0); vertex_data[2].position = Vec3f((float)width, -0.1f, (float)height); vertex_data[3].position = Vec3f((float)width, -0.1f, (float)height); vertex_data[4].position = Vec3f(0, -0.1f, (float)height); vertex_data[5].position = Vec3f(0, -0.1f, 0); for (int i = 0; i < 6; i++) vertex_data[i].normal = Vec3f(0, -1, 0); */ vertex_buffer.unlock(); size = Size(width+1, height+1); this->area_count = area_count; VirtualDirectory vdir; shader_program = ProgramObject::load(gc, "Resources/map_vertex.glsl", "Resources/map_fragment.glsl", vdir); shader_program.bind_attribute_location(0, "in_position"); shader_program.bind_attribute_location(1, "in_normal"); if (!shader_program.link()) throw Exception("Map shader program failed to link: " + shader_program.get_info_log()); texture_base = Texture2D(gc, texture_png); texture_base.set_min_filter(filter_linear); texture_base.set_mag_filter(filter_linear); // Change the values between area colors to avoid GPUs merging them together PixelBuffer image = ImageProviderFactory::load(areas_png).to_format(tf_rgba8); unsigned int* image_data = reinterpret_cast<unsigned int*>(image.get_data()); int image_total_pixels = image.get_width()*image.get_height(); for (int i = 0; i < image_total_pixels; i++) { unsigned int area_color = (image_data[i]>>24)*255/area_count; image_data[i] = (area_color<<24)+(area_color<<16)+(area_color<<8)+area_color; } texture_areas = Texture2D(gc, image.get_size()); texture_areas.set_image(image); texture_areas.set_min_filter(filter_nearest); texture_areas.set_mag_filter(filter_nearest); texture_borders = Texture2D(gc, borders_png); texture_borders.set_min_filter(filter_linear); texture_borders.set_mag_filter(filter_linear); }
Texture2D::Texture2D(GraphicContext &context, const PixelBuffer &image, bool is_srgb) { *this = Texture2D(context, image, image.get_size(), is_srgb); }
PerlinNoise_PixelWriter_RGB8(PixelBuffer &pbuff) : pitch(pbuff.get_pitch()), current_ptr((uint8_t *) pbuff.get_data()), line_start_ptr(current_ptr) { }
PerlinNoise_PixelWriter_RGBA8(PixelBuffer &pbuff) : pitch(pbuff.get_pitch() / pbuff.get_bytes_per_pixel()), current_ptr((uint32_t *) pbuff.get_data()), line_start_ptr(current_ptr) { }
PerlinNoise_PixelWriter_R32f(PixelBuffer &pbuff) : pitch(pbuff.get_pitch() / sizeof(float)), current_ptr((float *) pbuff.get_data()), line_start_ptr(current_ptr) { }
void TextureCube::set_image(GraphicContext &context, TextureCubeDirection cube_direction, PixelBuffer &image, int level) { int array_index = static_cast<int>(cube_direction); impl->provider->copy_from(context, 0, 0, array_index, level, image, image.get_size()); }
void Texture3D::set_image(GraphicContext &context, PixelBuffer &image, int depth, int level) { impl->provider->copy_from(context, 0, 0, depth, level, image, image.get_size()); }