• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.


  • Content count

  • Joined

  • Last visited

Community Reputation

255 Neutral

About thecoast47

  • Rank
  1. Recently i've been messing around with interpolation methods on scalar fields because im trying to make the scalar field of discrete points, continuous. I think I understand how bi-linear interpolation works. To my knowledge,In order to interpolate a value(using bilinear interpolation) you have to do three "lerps" using four discrete neighbor points on the field. But when it comes to higher order interpolation methods, I'm lost. I know how to use quadratic interpolation  to interpolate a value using 3 discrete points on a function. How would I use quadratic interpolation on a scalar field?  
  2. thanks for the input. Do you know any popular line/polygon simplification algorithms?    *EDIT*       I changed it so that I only iterate through p0 and p1 and now it works completely. Now I feel really,REALLY stupid.
  3. I recently implemented a marching squares algorithm to generate a polygon for an arbitrary image.   Here is an example of my marching squares implementation:   As you can see it works,however, the marching squares algorithm gives me more data than I really need for a polygon. So a polygon simplification algorithm would be needed.   I'm currently trying to implement the Ramer–Douglas–Peucker algorithm. The problem is that I don't know what condition's to set to end the recursion. Currently, the either the algorithm runs in an infinite loop or terminates without correctly simplifying the line/polygon.   My interpretation of the algorithm is as followed: -for the current line segment compute the vertex with the farthest perpendicular distance. -if the farthest perpendicular distance is greater than the user defined "tolerance" do recursion, otherwise terminate recursion.   Can someone point out what i'm doing wrong here?   Here's my flawed code: void smoothCurve(Particle* p0, Particle* p1,float tolerance,std::vector<Particle*>& vertexList,std::vector<Particle*>& outPut , std::vector<bool>& isRejected){ Vector2 displacement; Vector2 projectionArm; Vector2 projectedPoint; Vector2 pointToLineDisp; Vector2& x0 = p0->curPos; Vector2& x1 = p1->curPos; float dot; float currentDist = 0; float maxDist = 0; unsigned int maxIndex = 0; displacement = x1- x0; //calculates maximum distance from the line segment for(unsigned int I = 1; I < vertexList.size()-1;I++){ Particle*& currentVertex = vertexList[I]; Vector2& curVertexPos= currentVertex->curPos; projectionArm = curVertexPos - x0; dot = (projectionArm*displacement)/(displacement*displacement); projectedPoint = x0 + (displacement * dot); pointToLineDisp = projectedPoint - curVertexPos; currentDist = pointToLineDisp.getMagnitude(); if(currentDist > maxDist){ maxDist = currentDist; maxIndex = I; } } if(maxDist >= tolerance && outPut[maxIndex] == NULL ){ Particle* criticalParticle = vertexList[maxIndex]; outPut[maxIndex] = criticalParticle; smoothCurve(p0,criticalParticle,tolerance,vertexList,outPut,isRejected); smoothCurve(criticalParticle,p1,tolerance,vertexList,outPut,isRejected); } } void simplifyPolygon(float tolerance,std::vector<Particle*>& vertexList){ std::vector<Particle*> outPut; std::vector<bool> isRejected; outPut.resize(vertexList.size()); isRejected.resize(vertexList.size()); for(unsigned int I = 0; I < vertexList.size();I++){ outPut[I] = NULL; isRejected[I] = false; } Particle* x0 = vertexList[0]; Particle* x1 = vertexList[vertexList.size()-1]; outPut[0] = x0; outPut[vertexList.size()-1] = x1; smoothCurve(x0,x1,10.0f,vertexList,outPut,isRejected); for(unsigned int I = 0; I < outPut.size();I++){ Particle * cp = outPut[I]; if(cp == NULL){ delete vertexList[I]; } } vertexList.clear(); for(unsigned int I = 0; I < outPut.size();I++){ Particle * cp = outPut[I]; if(cp != NULL){ vertexList.push_back(cp); } } }
  4. This is what I get when i try to render a 305x298 bitmap 
  5. I'm currently trying to read bitmaps without using an image library. My current implementation can read bitmaps ,however, issues occur when both the width and height are not of base 2.  To be more specific, when I tired to render a 922x910 bitmap ,the colors didn't come in correctly. Sometimes bitmaps of different resolutions turnout looking "stretched" and without the correct colors.   To get my bitmaps I let microsoft paint convert png's, jpegs and other formats to .bmp. The ultimate purpose for all of this is to implement the marching squares method so I can generate polygons from sprites. How do I deal with this?    My bitmap code so far: #ifndef COLOR_VECTOR #define COLOR_VECTOR struct ColorVector{ unsigned char r; unsigned char g; unsigned char b; unsigned char a; }; #endif   class uBitmap{ public: uBitmap(std::string path,BYTE redColorKey, BYTE greenColorKey,BYTE blueColorKey); ~uBitmap(); unsigned int getWidth(); unsigned int getHeight(); long int getPixel(int x, int y); ColorVector getPixelVector(int x, int y); void resizeBuffer(unsigned int size); void clearBuffer(); void putPixel(int x, int y, BYTE r, BYTE g, BYTE b); void saveBitmap(std::string filename); void renderImage(); private: BITMAPFILEHEADER bitmapHeader_; BITMAPINFOHEADER bitmapInfoHeader_; BYTE* rgbPixelData_; BYTE* rgbaPixelData_; ColorVector colorKey_; };     uBitmap::uBitmap(std::string path,BYTE redColorKey, BYTE greenColorKey,BYTE blueColorKey){ BITMAPFILEHEADER& fileHeader = bitmapHeader_; BITMAPINFOHEADER& infoHeader = bitmapInfoHeader_; BYTE*& pixelData = rgbPixelData_; bitmapInfoHeader_.biWidth = 0; bitmapInfoHeader_.biHeight = 0; rgbPixelData_ = NULL; rgbaPixelData_ = NULL; std::ifstream file(path.data(),std::ios::binary); if(file.is_open()){ file.read((char*)&bitmapHeader_ ,sizeof(BITMAPFILEHEADER)); file.read((char*)&bitmapInfoHeader_,sizeof(BITMAPINFOHEADER)); rgbPixelData_ = new BYTE[infoHeader.biSizeImage]; file.read((char*)rgbPixelData_,infoHeader.biSizeImage); } file.close(); } uBitmap::~uBitmap(){ if(rgbPixelData_ != NULL){ delete[] rgbPixelData_; } if(rgbaPixelData_ != NULL){ delete[] rgbaPixelData_; } } unsigned int uBitmap::getWidth(){ return bitmapInfoHeader_.biWidth; } unsigned int uBitmap::getHeight(){ return bitmapInfoHeader_.biHeight; } /*long int uBitmap::getPixel(int x, int y){// attempting to pack color components into an integer ColorVector pix = getPixelVector(x,y); return (pix.b << 24) | (pix.g << 16) | (pix.r << 8) ; }*/ ColorVector uBitmap::getPixelVector(int x, int y){ ColorVector curElement; unsigned int firstComponent = (y*getWidth()+x)*3;//which is the blue color vector component curElement.b = *(rgbPixelData_+firstComponent); //reading first component (blue) curElement.g = *(rgbPixelData_+firstComponent+1);//reading second component (green) curElement.r = *(rgbPixelData_+firstComponent+2);//reading third component (red) return curElement; } void uBitmap::renderImage(){ glBegin(GL_POINTS); for(unsigned int y = 0; y < getHeight();y++){ for(unsigned int x = 0; x < getWidth();x++){ ColorVector c = getPixelVector(x,getHeight() - y); glColor3ub(c.r,c.g ,c.b); glVertex2i(x,y); } } glEnd(); } Please note:I realize that using immediate mode to render a bitmap is a horrible idea,however, its more a debugging function than anything else. Just putting that out there.    *EDIT* I seemed to have fixed the problem. You guys were completely right about the padding. All I did was slightly modify the constructor to fix my problem: uBitmap::uBitmap(std::string path,BYTE redColorKey, BYTE greenColorKey,BYTE blueColorKey{ BITMAPFILEHEADER& fileHeader = bitmapHeader_; BITMAPINFOHEADER& infoHeader = bitmapInfoHeader_; BYTE*& pixelData = rgbPixelData_; bitmapInfoHeader_.biWidth = 0; bitmapInfoHeader_.biHeight = 0; rgbPixelData_ = NULL; rgbaPixelData_ = NULL; std::ifstream file(path.data(),std::ios::binary); if(file.is_open()){ file.read((char*)&bitmapHeader_ ,sizeof(BITMAPFILEHEADER)); file.read((char*)&bitmapInfoHeader_,sizeof(BITMAPINFOHEADER)); int desiredRow = int(ceilf((((float)getWidth())*3.0f) / 4.0f) * 4.0f); int rowPadding = desiredRow - (getWidth()*3); rgbPixelData_ = new BYTE[ (getWidth()*getHeight()*3) + (rowPadding*getHeight()); for(unsigned int I = 0; I < getHeight();I++){ file.read(((char*)rgbPixelData_)+(I*getWidth()*3),desiredRow); } } file.close(); }
  6. I think you should take a look at this: http://www.mediafire.com/?3d6tk67ppq3h4lb
  7. You're probably right about that. I'm very new to numerical methods in general. 
  8. I'm trying to implement a function that calculates the integral of a function f'(x) using the midpoint method.  Here's what I came up with: float CMATH::midPointIntegrate(float steps,float x1, float(*F)(float x) ){ float stepSize = x1/steps; float integral = 0.0f; float xn = 0; float y0 = 0.0f; float ymid = 0.0f; float y1 = 0.0f; for(int I = 0; I < steps; I++){ y0 = F(xn); ymid = F(xn+stepSize*0.5f); y1 = F(xn+stepSize); integral+= y0*stepSize*0.5f + (ymid - y0)*stepSize*0.25f + ymid*stepSize*0.5f + (y1-ymid)*stepSize*0.25f; xn+=stepSize; } return integral; }     It appears to work, however, I was under the impression that the midpoint method requires less steps in order to calculate the integral.  Can anyone confirm that this is the correct implementation of the midpoint method because ,at the moment, i'm not really sure.
  9. Take a look at hardwire's post here:[url="http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=4&t=1952&start=15&sid=ac8f739422f0fc789578f8c84a6e5cab"] http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=4&t=1952&start=15&sid=ac8f739422f0fc789578f8c84a6e5cab[/url] In his post he explicitly describes how to implement both static friction and dynamic friction. The dynamic friction method seems to solve the problem of bodies slowly separating away from each other while also adding some nice subtle effects.
  10. At what line exactly does the application crash? *edit* I think you need to post ALL of the method/function/constructor definitions for both classes if you want anyone to solve your problem.
  11. Apparently this is verlet integration: [source lang="cpp"]void Particle::integrate(float timestep){ Vec2 Temp = P.Position; P.Position += P.Position - P.OldPosition + P.Acceleration*Timestep*Timestep; P.OldPosition = Temp; } [/source] I got it from this [url="http://www.gamedev.net/page/resources/_/technical/math-and-physics/a-verlet-based-approach-for-2d-game-physics-r2714"]article,[/url]
  12. [quote name='Canvas' timestamp='1339716779' post='4949357'] could you explain that abit more? if possible? [/quote] What specifically would you like me to explain? The math behind the rotation? Or the Code i posted?
  13. I think the general idea is loop through each source pixel and multiply the pixel position by a rotation matrix. Rotation is relative to the origin, so you have to subtract each pixel by the center of the image before you multiply by the rotation matrix. Here some code i wrote to rotate images in visual basic. [source lang="vb"]Public Sub rotate(source As PictureBox, dest As PictureBox, ByVal deg As Single) 'i guess you could think of the PictureBox as SDL_surface Dim cpex As Long Dim cpey As Long Dim cpeColor As Long Dim tx As Double Dim ty As Double Dim tpx As Double Dim tpy As Double Dim Icos As Double Dim Isin As Double Dim sw As Double Dim sh As Double Dim rad As Double Dim cx As Double Dim cy As Double sw = source.Width sh = source.Height rad = deg * (PI / 180) 'convert degrees to radians Icos = Cos(rad) Isin = Sin(rad) cx = sw / 2 'compute center of the image cy = sh / 2 'compute center of the image dest.Cls 'this clears the destination "Surface" 'C.P.E ->current picture element For cpey = 0 To source.Height - 5 For cpex = 0 To source.Width - 5 cpeColor = GetPixel(source.hdc, cpex, cpey) tx = cpex - cx ty = cpey - cy tpx = ((Icos * tx) - (Isin * ty)) tpy = ((Isin * tx) + (Icos * ty)) dest.PSet (tpx + cx, tpy + cy), cpeColor Next cpex Next cpey End Sub[/source]
  14. It looks like your blitting parts of the spritesheet to locations that dont exist on the newly allocated surface. Right now im failing to understand the purpose of the dstrect variable. It looks like you should just set that parameter to NULL. Again i'm not sure why you're creating new surfaces of the same image just to render certain areas of that image when you can do the same thing with SDL_BlitSurface. It honestly just seems like a waste of memory. Anyway,who am i to judge? Here's a SDL app that loads the individual tiles from the sprite sheet into separate surfaces. [source lang="cpp"]#include <SDL/SDL.h> #include <SDL/SDL_image.h> #include <stdlib.h> #include <Math.h> #include <vector> SDL_Surface * mainSurface = NULL; SDL_Event g_Event; SDL_Surface * spriteSheet = NULL; std::vector<SDL_Surface*> subSurfaceList; bool running = true; void handleEvents(SDL_Event & event){ if(event.type == SDL_QUIT){ running = false; } } void getSubSurfaces(){ SDL_Rect sheetArea; sheetArea.w = 32; sheetArea.h = 32; for(unsigned int y = 0; y < 4; y++){ for(unsigned int x = 0; x < 7; x++){ sheetArea.x = x*32; sheetArea.y = y*32; SDL_Surface * newSurface = SDL_CreateRGBSurface(SDL_HWSURFACE,32,32,32,0,0,0,0); SDL_BlitSurface(spriteSheet,&sheetArea,newSurface,NULL); subSurfaceList.push_back(newSurface); } } } void clearSurface(SDL_Surface * surface,int r,int g, int b){ SDL_Rect rect; rect.x = 0; rect.y = 0; rect.w = surface->w; rect.h = surface->h; Uint32 color = SDL_MapRGB(surface->format,r,g,b); SDL_FillRect(surface,&rect,color); } int main ( int argc, char** argv ){ //initalizing SDL if(SDL_Init(SDL_INIT_VIDEO) == -1){ fprintf(stderr,"Failed to Initalize Video\n"); return 0; }else{ fprintf(stdout,"Suceeded to Initalize Video\n"); atexit(SDL_Quit); } //setup window mainSurface = SDL_SetVideoMode(640,480,32,SDL_RESIZABLE | SDL_HWACCEL | SDL_DOUBLEBUF); //load sprite spriteSheet = IMG_Load("spriteSheet.png"); getSubSurfaces(); //begin main loop int index = 0; int size = subSurfaceList.size(); SDL_Rect sheetArea; sheetArea.x = 0; sheetArea.y = 0; sheetArea.w = 32; sheetArea.h = 32; while(running){ SDL_PollEvent(&g_Event); SDL_Flip(mainSurface); handleEvents(g_Event); clearSurface(mainSurface,0,0,0); index = (index +1) % size; SDL_BlitSurface(subSurfaceList[index],&sheetArea,mainSurface,NULL); SDL_Delay(1000); } return 0; }[/source] Again i'm not sure why you're loading tiles into separate surfaces, I highly recommend that you just use the sprite sheet itself as the source and blit parts of the sprite sheet onto the main surface like this: [source lang="cpp"]void renderExplosion(int x,int y,int intensity,int orientation,SDL_Surface* explositonSheet,SDL_Surface * mainSurface){ SDL_Rect sheetArea; SDL_Rect sheetPosition; sheetPosition.x = x; sheetPosition.y = y; sheetPosition.w = mainSurface->w; sheetPosition.h = mainSurface->h; sheetArea.w = 32; sheetArea.h = 32; sheetArea.x = (orientation%7 )*32; sheetArea.y = (intensity%4)*32; SDL_BlitSurface(explositonSheet,&sheetArea,mainSurface,&sheetPosition); }[/source]
  15. Basically i am trying to read a binary file stored in a zip folder. The binary file in the zip folder stores information for individual polygons. This is the class header. This class is responsible for transferring information from ConvexHull objects that i'd like to store into binary files. Its also responsible for reading information from the binary file. Once that information is read i can create a ConvexHull object and then reinitialize the geometry object. (hope that made sense i dont know a better way to put that) [source lang="cpp"]class Geometry{ static const unsigned int MAX_VERTEX_ELEMENTS = 50; static const unsigned int MAX_CHAR_ELEMENTS = 10; public: Geometry(); ~Geometry(); ConvexHull * loadGeometryIntoMemory(MultiGrid<ConvexHull> * hullGridPtr); void storeHullData(ConvexHull * ch); void writeHullDataToFile(std::ofstream & file); void readHullDataFromFile(std::ifstream & file); void readHullDataFromBuffer(std::istringstream& file); void initAllFields(); private: unsigned int vrecsFilled_;//V for vertex unsigned int krecsFilled_;//K for keyword char textureKeyword_[MAX_CHAR_ELEMENTS]; float vx_[MAX_VERTEX_ELEMENTS]; float vy_[MAX_VERTEX_ELEMENTS]; bool translate_; float fakeFriction_; };[/source] This is how i write to my binary file: [source lang="cpp"]void Geometry::writeHullDataToFile(std::ofstream & file){ file.write((char*)&vrecsFilled_,sizeof(vrecsFilled_)); for(unsigned int K = 0; K < vrecsFilled_;K++){ float & x = vx_[K]; float & y = vy_[K]; file.write((char*)&x,sizeof(x)); file.write((char*)&y,sizeof(y)); } file.write((char*)&krecsFilled_,sizeof(krecsFilled_)); for(unsigned int K = 0; K < krecsFilled_;K++){ char & c = textureKeyword_[K]; file.write((char*)&c,sizeof©); } //write parameters last file.write((char*)&fakeFriction_,sizeof(fakeFriction_)); file.write((char*)&translate_,sizeof(translate_)); }[/source] This is where i load the binary file into a buffer from the zip folder (using PhyicsFS) and attempt to read it. I try read the binary data by calling the method "readHullDataFromBuffer(file);" [source lang="cpp"] static void loadGeometryFromArchive(std::vector<std::string>& pathList,HullRegistry* hRegistry,MultiGrid<ConvexHull>* hullGrid){ PHYSFS_sint64 file_size = -1; int length_read = 0; char * bytes = NULL; unsigned int listSize = 0; Geometry primitiveData; ConvexHull * currentHull = NULL; for(unsigned int K = 0; K < pathList.size();K++){ std::string& p = pathList[K]; std::string path ="geometry/"+p; if(PHYSFS_exists(path.data()) == 1){ //create file and stream bytes into a buffer PHYSFS_file* myfile = PHYSFS_openRead(path.data()); file_size = PHYSFS_fileLength(myfile); bytes = new char[file_size]; //writes the bytes from file in archive to bytes array length_read = PHYSFS_read(myfile, bytes,1,PHYSFS_fileLength(myfile)); const char * errList = PHYSFS_getLastError(); _cprintf(errList); //Okay now i've got the binary file loaded in the buffer //i can only read the first number in the file before errors occur std::istringstream file(bytes,std::istringstream::binary | std::istringstream::in); //the first 4 bytes of the geometry file contains a number that represents the amount of polygons written to the file. file.read((char*)&listSize,sizeof(listSize));// i succesfully read the correct number,however,this is where my luck ends for(unsigned int K = 0; K < listSize;K++){ primitiveData.initAllFields(); primitiveData.readHullDataFromBuffer(file);//I then attempt to read each record using the buffer but this fails currentHull = primitiveData.loadGeometryIntoMemory(hullGrid); hRegistry->getStaticHullList().push_back(currentHull); } delete[] bytes; PHYSFS_close(myfile); } } }[/source] I figured I could use std::istringstream like i would use std::ifsream. But with this I can only read the first number in the binary file before i get errors. [source lang="cpp"]void Geometry::readHullDataFromBuffer(std::istringstream& file){ file.read((char*)&vrecsFilled_,sizeof(vrecsFilled_)); for(unsigned int K = 0; K < vrecsFilled_;K++){ float & x = vx_[K]; float & y = vy_[K]; file.read((char*)&x,sizeof(x)); file.read((char*)&y,sizeof(y)); } file.read((char*)&krecsFilled_,sizeof(krecsFilled_)); for(unsigned int K = 0; K < krecsFilled_;K++){ char & c = textureKeyword_[K]; file.read((char*)&c,sizeof©); } file.read((char*)&fakeFriction_,sizeof(fakeFriction_)); file.read((char*)&translate_,sizeof(translate_)); }[/source] Basically, after i read the first number in the array, file.fail() becomes true and, anything after that is 0; Can someone tell me why the previous method fails at the first character? Is this an issue with PhysicsFS or is it my own code? Okay so i solved my own issue. I basically just track the position of the array and then use memcpy to read the values. Here is what i now use to read the records: [source lang="cpp"]void Geometry::readHullDataFromBuffer(char * bytes,long & position){ memcpy(&vrecsFilled_,bytes+position,sizeof(vrecsFilled_)); position+=sizeof(vrecsFilled_); for(unsigned int K = 0; K < vrecsFilled_;K++){ float & x = vx_[K]; float & y = vy_[K]; memcpy(&x,bytes+position,sizeof(x)); position+=sizeof(x); memcpy(&y,bytes+position,sizeof(y)); position+=sizeof(y); } memcpy(&krecsFilled_,bytes+position,sizeof(krecsFilled_)); position+=sizeof(krecsFilled_); for(unsigned int K = 0; K < krecsFilled_;K++){ char & c = textureKeyword_[K]; memcpy(&c,bytes+position,sizeof©); position+=sizeof©; } memcpy(&fakeFriction_,bytes+position,sizeof(fakeFriction_)); position+=sizeof(fakeFriction_); memcpy(&translate_,bytes+position,sizeof(translate_)); position+=sizeof(translate_); }[/source] Thank you all for your help.