Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

justin12343

Member Since 19 Jan 2010
Offline Last Active Feb 06 2013 09:14 AM
-----

Topics I've Started

Porting point sprites from DirectX

21 December 2012 - 03:09 PM

I've hit a road block in the development of my OpenGL renderer regarding the size of point sprites. I have been writing the features of my renderers for DirectX first and then I immediately port them to OpenGL after I get them working, since Windows is my primary platform and DirectX seems to be easier to write for (come get it haters lol). I noticed that you can't set the point size for each point sprite individually in OpenGL as you can in DirectX (and OpenGLES), unless you use a shader. My readings tell me that I can cheat using the Z value and distance attenuation to achieve the same effect. My question is  how do I use this to make my point sprites look exactly the same in OpenGL as they would in DirectX? I trying to avoid taking the shader route for this because I want my engine to be able to run on older hardware.


Opengl texture alpha channel

13 December 2012 - 12:58 PM

I'm having trouble getting the alpha channel of a texture loadded with SDL 1.3 and SDL_Image to work correctly. The problem is that according to the Texture display window in gEDebugger, the alpha value of each pixel is set to 0, causing the texture to appear fully transparent. If I disable blending or load a format that does not have an alpha channel, the texture displays just fine as expected. What could I be doing wrong?

bool OGLRenderer::Initialize(int backWidth, int backHeight, int backBpp, bool fullscreen)
{
ctx = SDL_GL_CreateContext(pWin);
	SDL_GL_SetSwapInterval(1);
glEnable( GL_TEXTURE_2D);
	glEnable( GL_BLEND);	// allow alpha blending
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
/*glEnable( GL_DEPTH_TEST);
	glDepthFunc( GL_LESS);*/
glDisable( GL_DEPTH_TEST);
glDisable( GL_CULL_FACE );
glDisable( GL_ALPHA_TEST);
glDisable( GL_LIGHTING);
int OpenGLVersion[2];
glGetIntegerv(GL_MAJOR_VERSION, &OpenGLVersion[0]);
glGetIntegerv(GL_MINOR_VERSION, &OpenGLVersion[1]);
printf( "Renderer initialized successfully using the OpenGL %i.%i backend.\n", OpenGLVersion[0], OpenGLVersion[1]);
int flags = IMG_INIT_PNG|IMG_INIT_JPG|IMG_INIT_TIF|IMG_INIT_WEBP;
if(IMG_Init(flags)&flags != flags)
{
  printf("SDL_Image failed to initialize.\n");
  printf("%s\n", IMG_GetError());
  return false;
}
return true;
}
GLuint OGLRenderer::create_texture( SDL_Surface *surf)
{
GLenum Mode;
if (surf->format->BytesPerPixel == 4) // contains an alpha channel
{
  if (surf->format->Rshift == 24 && surf->format->Aloss == 0 ) Mode = GL_ABGR_EXT;
   else if ( surf->format->Rshift == 16 && surf->format->Aloss == 8 ) Mode = GL_BGRA;
   else if ( surf->format->Rshift == 16 && surf->format->Ashift == 24 ) Mode = GL_BGRA;
   else if ( surf->format->Rshift == 0 && surf->format->Ashift == 24 ) Mode = GL_RGBA;
   else throw std::logic_error("Pixel Format not recognized for GL display");
}
else if (surf->format->BytesPerPixel == 3) // no alpha channel
{
  if (surf->format->Rshift == 16 ) Mode = GL_BGR;
   else if ( surf->format->Rshift == 0 ) Mode = GL_RGB;
   else throw std::logic_error("Pixel Format not recognized for GL display");
}
else throw std::logic_error("Pixel Format not recognized for GL display");

GLuint tex;
glPixelStorei( GL_UNPACK_ALIGNMENT, surf->format->BytesPerPixel);
glGenTextures( 1, &tex);
glBindTexture( GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, surf->format->BytesPerPixel, surf->w, surf->h, 0, Mode, GL_UNSIGNED_BYTE, surf->pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
return tex;
}
void OGLRenderer::draw_sprite( int index, float frame, float x, float y, float xscale, float yscale, float angle, int col)
{
if (index < 0 || index >= spriteList.size())
  return;
Sprite *tmp = spriteList[index];
if (frame < 0 || frame >= tmp->Frames.size())
  return;
if (!tmp->loaded)
  InitializeSprite( tmp);
int subImage = clamp_value((int)floor( (float)frame), 0, tmp->FrameCount-1);
unsigned int color = 0xffffffff;
unsigned int red = 255;
unsigned int blue = 255;
unsigned int green = 255;
if (col != -1)
{
  red = (col & 0x00FF0000) >> 16;
  green = (col & 0x0000FF00) >> 8;
  blue = (col & 0x000000FF);
}
Rect r;
r.left = x - tmp->CenterX;
r.top = y - tmp->CenterY;
r.right = r.left + tmp->FrameWidth;
r.bottom = r.top + tmp->FrameHeight;
OGLFrame *pFrame = reinterpret_cast<OGLFrame*>(tmp->Frames[subImage]);
glBindTexture( GL_TEXTURE_2D, pFrame->texture);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
/*glPushMatrix();
glTranslatef( r.left, r.top, 0);
glRotatef( camera_angle, 0, 0, 0);
glScalef( xscale, yscale, 1);*/
glBegin( GL_QUADS);
glTexCoord2f( 0, 0); glColor4f( (float)red/255, (float)green/255, (float)blue/255, alpha); glVertex3f( r.left, r.top, depth);
glTexCoord2f( 1, 0); glColor4f( (float)red/255, (float)green/255, (float)blue/255, alpha); glVertex3f( r.right, r.top, depth);
glTexCoord2f( 1, 1); glColor4f( (float)red/255, (float)green/255, (float)blue/255, alpha); glVertex3f( r.right, r.bottom, depth);
glTexCoord2f( 0, 1); glColor4f( (float)red/255, (float)green/255, (float)blue/255, alpha); glVertex3f( r.left, r.bottom, depth);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
//glPopMatrix();
}

Create OpenGL texture from SDL surface

05 December 2012 - 08:42 AM

I'm having trouble getting a SDL_Surface into OpenGL where as I'm only able to render a white box. What I'm trying to do is take a sprite sheet and cut it into tiles and then send the tiles to the video card for use as an OpenGl texture later. I don't have so much of a clue of what the problem could be, since OpenGL or SDL doesn't seem to report an error. Could it be that my formats are wrong?

bool OGLRenderer::InitializeSprite( Sprite *spr)
{
if (spr == NULL)
  return false;
if (spr->loaded)
  return true;
SDL_Surface *surf = 0;
if (!spr->fromData)
{
  surf = IMG_Load( spr->fname.c_str());
  if (surf == NULL)
  {
   printf("Could not load sprite %s.\n%s\n", spr->fname.c_str(), IMG_GetError());
   return false;
  }
}
else
{
  SDL_RWops *ops = SDL_RWFromMem( (void*)spr->data, spr->dataSize);
  if (ops == NULL)
  {
   printf("Could not load sprite located at %p\n%s\n", spr->data, SDL_GetError());
   return false;
  }
  surf = IMG_Load_RW( ops, 1);
  if (surf == NULL)
  {
   printf("Could not load sprite located at %p\n%s\n", spr->data, IMG_GetError());
   return false;
  }
}
//Convert To 32 bit RGBA format
if (surf->format->Rmask != rmask)
{
  SDL_Surface *tmp = SDL_CreateRGBSurface( SDL_SWSURFACE, surf->w, surf->h, surf->format->BitsPerPixel, rmask, gmask, bmask, amask);
  SDL_BlitSurface( surf, NULL, tmp, NULL);
  SDL_FreeSurface( surf);
  surf = tmp;
}
int fw = spr->FrameWidth == -1 ? spr->ImageWidth : spr->FrameWidth;
int fh = spr->FrameHeight == -1 ? spr->ImageHeight : spr->FrameHeight;
for (int i = 0; i < spr->FrameCount; ++i)
{
  SDL_Rect rect;
  rect.x = (i % (spr->ImageWidth/fw) *fw);
  rect.y = (i / (spr->ImageWidth/fw) *fh);
  rect.w = rect.x + fw;
  rect.h = rect.y + fh;
  SDL_Surface *f = SDL_CreateRGBSurface( SDL_SWSURFACE, fw, fh, surf->format->BitsPerPixel, surf->format->Rmask, surf->format->Gmask, surf->format->Bmask, surf->format->Amask);
  //++f->refcount;
  if (SDL_BlitSurface( surf, &rect, f, NULL) == -1)
  {
   SDL_FreeSurface( f);
   SDL_FreeSurface( surf);
   printf( "Could not load sprite.\n%s\n", SDL_GetError());
   return false;
  }
  SDL_SetColorKey( f, SDL_SRCCOLORKEY, spr->ColorKey);
  OGLFrame *frame = new OGLFrame( spr);
  frame->surf = f;
  glGenTextures( 1, &frame->texture);
  glBindTexture( GL_TEXTURE_2D, frame->texture);
  glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, f->w, f->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, f->pixels);
  if (glGetError() != GL_NO_ERROR)
  {
   printf( "There was an error loading the frame.\n%s\n", gluErrorString(glGetError()));
  }
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  //glPixelStorei( GL_UNPACK_ROW_LENGTH, f->pitch);
  create_mask( frame->GetMask(), f, fw, fh, spr->ColorKey);
  spr->Frames.push_back( frame);
}
SDL_FreeSurface( surf);
spr->loaded = true;
return true;
}

void OGLRenderer::draw_sprite( int index, float frame, float x, float y, float xscale, float yscale, float angle, int col)
{
if (index < 0 || index >= spriteList.size())
  return;
Sprite *tmp = spriteList[index];
if (frame < 0 || frame >= tmp->Frames.size())
  return;
if (!tmp->loaded)
  InitializeSprite( tmp);
int subImage = clamp_value((int)floor( (float)frame), 0, tmp->FrameCount-1);
unsigned int color = 0xffffffff;
unsigned int red = 255;
unsigned int blue = 255;
unsigned int green = 255;
unsigned int a = (int)floor(255*alpha);
if (col != -1)
{
  red = (col & 0x00FF0000) >> 16;
  green = (col & 0x0000FF00) >> 8;
  blue = (col & 0x000000FF);
  color = MAKE_COLOR( a, red, green, blue);
}
Rect r;
r.left = x - tmp->CenterX;
r.top = y - tmp->CenterY;
r.right = r.left + tmp->FrameWidth;
r.bottom = r.top + tmp->FrameHeight;
OGLFrame *pFrame = reinterpret_cast<OGLFrame*>(tmp->Frames[subImage]);
glBindTexture( GL_TEXTURE_2D, pFrame->texture);
/*glPushMatrix();
glTranslatef( r.left, r.top, 0);
glRotatef( camera_angle, 0, 0, 0);
glScalef( xscale, yscale, 1);*/
glBegin( GL_QUADS);
glTexCoord2f( 0, 0); /*glColor4i( red, green, blue, a);*/ glVertex3f( r.left, r.top, depth);
glTexCoord2f( 0, 1); /*glColor4i( red, green, blue, a);*/ glVertex3f( r.left, r.bottom, depth);
glTexCoord2f( 1, 1); /*glColor4i( red, green, blue, a);*/ glVertex3f( r.right, r.bottom, depth);
glTexCoord2f( 1, 0); /*glColor4i( red, green, blue, a);*/ glVertex3f( r.right, r.top, depth);
glEnd();
//glPopMatrix();
}

Child class with same variable

11 August 2012 - 01:59 PM

I've run into a problem with inheritance in AngelScript. I finally got around to implementing parent objects into my engine, so I thought I would use simple polymorphism to keep from copying and pasting the parent's code into the child's code.

A basic object in my game would look like this:
class objActor_controller
{
	 Object @object;
	 float x;
	 float y;

	 int animation;
	 int[] animation_begin;
	 int[] animation_end;

	 objActor_controller(Object @obj)
	 {
	 	 @this.object = obj;
	 	 x = object.x;
	 	 y = object.y;
	 }

	 void Create()
	 {
	 	 //Does some initial setup
	 }
}

Lets say I decide to write a child class:
class objPlayer_controller : objActor_controller
{
	 Object @object;
	 float x;
	 float y;
	 Child_controller(Object @obj)
	 {
		  @this.object = obj;
		  x = object.x;
		  y = object.y;
	 }
	 void Create()
	 {
	 	 objActor_controller::Create();
		  //Sets up animations specific for this character...
	 }

	 void Step()
	 {
	 	 x += 1;
	 	 y += 1;
	 }
}

Using the method above makes the compiler complain about name conflicts with x, y and @object since my game editor automatically adds these. Since the C++ equivilent allows for it, Shouldn't AngelScript allow this too?

Create Texture from SDL_Surface

16 July 2012 - 10:01 AM

I'm putting together a bitmap font system with SDL_TTF, SDL_image, and DirectX 9 but I'm having some problems converting a SDL_Surface returned from IMG_Load into a IDirect3DTexture9.

bool Font::CreateFromBitmap()
{
SDL_Surface *surf = IMG_Load( mFname.c_str());
//SDL_SetColorKey(surf, SDL_RLEACCEL, surf->format->colorkey);
Uint16 i = mFirstChar;
for (int y = 0; y < surf->h; y += mHeight)
{
  for (int x = 0; x < surf->w; x += mWidth)
  {
   SDL_Surface *pCharSurf = SDL_CreateRGBSurface( SDL_SWSURFACE, mWidth, mHeight, surf->format->BitsPerPixel, surf->format->Rmask, surf->format->Gmask, surf->format->Bmask, surf->format->Amask);
   surf->refcount++;
   pCharSurf->refcount++;
   SDL_Rect rect;
   rect.x = x;
   rect.y = y;
   rect.w = mWidth;
   rect.h = mHeight;
   if (SDL_BlitSurface( surf, &rect, pCharSurf, NULL) == -1)
   {
	printf( "Failed to load font at '%s' in %s", i, mName);
	SDL_FreeSurface( surf);
	Release();
	return false;
   }
   Character *pChar = CreateChar( pCharSurf); //<------------------
   if (pChar == NULL)
   {
	printf( "Failed to load font at '%s' in %s", i, mName);
	SDL_FreeSurface( surf);
	Release();
	return false;
   }
   chars[i] = pChar;
  
   if (i == mLastChar)
   {
	goto end;
   }
   else
   {
	++i;
   }
  }
}
end:
SDL_FreeSurface( surf);
return true;
}

This function is used when creating a font from an image file instead of a .ttf font. It's supposed to copy a portion from the image onto a small surface using SDL_BlitSurface then pass that to a overloaded Font::CreateChar function.

Character *DX9Font::CreateChar( SDL_Surface *surf)
{
DX9Character *pChar = new DX9Character;
pChar->surface = surf;
pChar->w = surf->w;
D3DFORMAT format = D3DFMT_A8R8G8B8;
if (surf->format->BitsPerPixel == 32)
{
  if (surf->format->Rmask == 0x000000ff)
  {
   format = D3DFMT_A8B8G8R8;
  
   if (surf->format->Amask == 0x00000000)
   {
	format = D3DFMT_X8B8G8R8;
   }
  }
  else
  {
   format = D3DFMT_A8R8G8B8;
  
   if (surf->format->Amask == 0x00000000)
   {
	format = D3DFMT_X8R8G8B8;
   }
  }
}
if (surf->format->BitsPerPixel == 24)
{
  format = D3DFMT_R8G8B8;
}
if (surf->format->BitsPerPixel == 16)
{
  format = D3DFMT_R5G6B5;
}
if (surf->format->BitsPerPixel == 8)
{
  format = D3DFMT_R3G3B2;
}
D3DXCreateTexture( pEngine->GetDevice(), surf->w, surf->h, 1, D3DUSAGE_DYNAMIC, format, D3DPOOL_DEFAULT, &pChar->texture);
D3DLOCKED_RECT rect;
SDL_LockSurface( surf);
if FAILED( pChar->texture->LockRect( 0, &rect, NULL, D3DLOCK_DISCARD))
{
  delete pChar;
  return 0;
}
char *src = (char*)surf->pixels;

Uint32 rows = surf->h;
Uint32 size = surf->w * surf->format->BytesPerPixel;
char *dest = (char*)rect.pBits;
while(rows--)
	{
		memcpy( dest, src, size);
		src += surf->pitch;
		dest += rect.Pitch;
	}
pChar->texture->UnlockRect( 0);
SDL_UnlockSurface( surf);
return pChar;
}

Here is where the surface is memcpy'ed into a DirectX texture. The problem is when the texture is rendered, all I get is black boxes or completely transparent black boxes if the image had an alpha channel. The ttf font surfaces use the exact same function above and works fine, but not surfaces returned from IMG_Load. What could be the problem?

PARTNERS