mvEngine Development Thread

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

User avatar
mv2112
Chaos Rift Junior
Chaos Rift Junior
Posts: 240
Joined: Sat Feb 20, 2010 4:15 am
Current Project: Java Tower Defence Game
Favorite Gaming Platforms: N64/Xbox 360/PC/GameCube
Programming Language of Choice: C/++, Java
Location: /usr/home/mv2112
Contact:

Re: mvEngine Development Thread

Post by mv2112 »

Im starting to sort of get the hang of the basics of openGL, however im trying to load a texture from an SDL_surface and its loading wrong. When i render the texture it is inverted and it has no red...
http://pastebin.com/psMhrpwb
My load texture func^^
XianForce
Chaos Rift Devotee
Chaos Rift Devotee
Posts: 767
Joined: Wed Oct 29, 2008 8:36 pm

Re: mvEngine Development Thread

Post by XianForce »

I'm sorry for not going through your code before I post, but the two solutions that instantly pop into my head are:

1) Your not matching your vertex coordinates and texture coordinates up right... That can cause the image to be flipped
2) When your rendering the opaque quad, you don't have any red in it.


So like if I had an image of a white circle and tried to render it onto a green quad (0, 1.0, 0 - rgb format), the circle will actually be green when rendered.
User avatar
dandymcgee
ES Beta Backer
ES Beta Backer
Posts: 4709
Joined: Tue Apr 29, 2008 3:24 pm
Current Project: https://github.com/dbechrd/RicoTech
Favorite Gaming Platforms: NES, Sega Genesis, PS2, PC
Programming Language of Choice: C
Location: San Francisco
Contact:

Re: mvEngine Development Thread

Post by dandymcgee »

Falco Girgis wrote:It is imperative that I can broadcast my narcissistic commit strings to the Twitter! Tweet Tweet, bitches! :twisted:
User avatar
mv2112
Chaos Rift Junior
Chaos Rift Junior
Posts: 240
Joined: Sat Feb 20, 2010 4:15 am
Current Project: Java Tower Defence Game
Favorite Gaming Platforms: N64/Xbox 360/PC/GameCube
Programming Language of Choice: C/++, Java
Location: /usr/home/mv2112
Contact:

Re: mvEngine Development Thread

Post by mv2112 »

I got the code i'm using partly from the 4'th post on that thread

I also didnt mean to say inverted, i meant that the image is slightly rotated and mirrored so its the same image twice and the color red is gone...
Link to image
User avatar
mv2112
Chaos Rift Junior
Chaos Rift Junior
Posts: 240
Joined: Sat Feb 20, 2010 4:15 am
Current Project: Java Tower Defence Game
Favorite Gaming Platforms: N64/Xbox 360/PC/GameCube
Programming Language of Choice: C/++, Java
Location: /usr/home/mv2112
Contact:

Re: mvEngine Development Thread

Post by mv2112 »

I got the colors right, but the image is still mirrored, like the link i posted but with normal colors...
User avatar
dandymcgee
ES Beta Backer
ES Beta Backer
Posts: 4709
Joined: Tue Apr 29, 2008 3:24 pm
Current Project: https://github.com/dbechrd/RicoTech
Favorite Gaming Platforms: NES, Sega Genesis, PS2, PC
Programming Language of Choice: C
Location: San Francisco
Contact:

Re: mvEngine Development Thread

Post by dandymcgee »

mv2112 wrote:I got the colors right, but the image is still mirrored, like the link i posted but with normal colors...
That's a texCoord mistake like XianForce mentioned earlier. Read up on ordering vertices and texture coordinates properly in opengl. (Hint: Get it right first without TexCoords using only colored vertices, then add the texture into the mix.)

Edit: Maybe this will help: http://www.gamedev.net/reference/articl ... cle947.asp (Scroll down to the bottom "A Textured Quad").
Falco Girgis wrote:It is imperative that I can broadcast my narcissistic commit strings to the Twitter! Tweet Tweet, bitches! :twisted:
User avatar
mv2112
Chaos Rift Junior
Chaos Rift Junior
Posts: 240
Joined: Sat Feb 20, 2010 4:15 am
Current Project: Java Tower Defence Game
Favorite Gaming Platforms: N64/Xbox 360/PC/GameCube
Programming Language of Choice: C/++, Java
Location: /usr/home/mv2112
Contact:

Re: mvEngine Development Thread

Post by mv2112 »

dandymcgee wrote:
mv2112 wrote:I got the colors right, but the image is still mirrored, like the link i posted but with normal colors...
That's a texCoord mistake like XianForce mentioned earlier. Read up on ordering vertices and texture coordinates properly in opengl. (Hint: Get it right first without TexCoords using only colored vertices, then add the texture into the mix.)

Edit: Maybe this will help: http://www.gamedev.net/reference/articl ... cle947.asp (Scroll down to the bottom "A Textured Quad").
Yup, thats what it was. However now if i render another primitive that is colored, that color bleeds on to the texture. I rendered a red square and my texture turned red. How can i fix this...
XianForce
Chaos Rift Devotee
Chaos Rift Devotee
Posts: 767
Joined: Wed Oct 29, 2008 8:36 pm

Re: mvEngine Development Thread

Post by XianForce »

mv2112 wrote:
dandymcgee wrote:
mv2112 wrote:I got the colors right, but the image is still mirrored, like the link i posted but with normal colors...
That's a texCoord mistake like XianForce mentioned earlier. Read up on ordering vertices and texture coordinates properly in opengl. (Hint: Get it right first without TexCoords using only colored vertices, then add the texture into the mix.)

Edit: Maybe this will help: http://www.gamedev.net/reference/articl ... cle947.asp (Scroll down to the bottom "A Textured Quad").
Yup, thats what it was. However now if i render another primitive that is colored, that color bleeds on to the texture. I rendered a red square and my texture turned red. How can i fix this...
Render a white primitive.

From what I understand, the texture that is mapped to a primitive, can only use what color(s) is/are available from the primitive.
qpHalcy0n
Respected Programmer
Respected Programmer
Posts: 387
Joined: Fri Dec 19, 2008 3:33 pm
Location: Dallas
Contact:

Re: mvEngine Development Thread

Post by qpHalcy0n »

The default pixel modulation operation is GL_MODULATE.

This takes the source color and source texel data and performs a mix of them by color multiplication. If you want the texture to appear as it does on its own, simply don't pass a color when rendering, or change the modulation op to GL_REPLACE.

glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );

Rendering a white primitive will fix the problem in a roundabout way ( any texel source color multiplied by one is itself ). That is what's going on there for you.
XianForce
Chaos Rift Devotee
Chaos Rift Devotee
Posts: 767
Joined: Wed Oct 29, 2008 8:36 pm

Re: mvEngine Development Thread

Post by XianForce »

qpHalcy0n wrote:The default pixel modulation operation is GL_MODULATE.

This takes the source color and source texel data and performs a mix of them by color multiplication. If you want the texture to appear as it does on its own, simply don't pass a color when rendering, or change the modulation op to GL_REPLACE.

glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );

Rendering a white primitive will fix the problem in a roundabout way ( any texel source color multiplied by one is itself ). That is what's going on there for you.
Oooh, thanks for explaining that =D. Learning something new everyday haha.
User avatar
mv2112
Chaos Rift Junior
Chaos Rift Junior
Posts: 240
Joined: Sat Feb 20, 2010 4:15 am
Current Project: Java Tower Defence Game
Favorite Gaming Platforms: N64/Xbox 360/PC/GameCube
Programming Language of Choice: C/++, Java
Location: /usr/home/mv2112
Contact:

Re: mvEngine Development Thread

Post by mv2112 »

I'm starting to like openGL. I just learned how to rotate an object around it's center! My adventure through openGL continues...
User avatar
eatcomics
ES Beta Backer
ES Beta Backer
Posts: 2528
Joined: Sat Mar 08, 2008 7:52 pm
Location: Illinois

Re: mvEngine Development Thread

Post by eatcomics »

I love OGL too :D its like the god of graphics APIs
Image
User avatar
mv2112
Chaos Rift Junior
Chaos Rift Junior
Posts: 240
Joined: Sat Feb 20, 2010 4:15 am
Current Project: Java Tower Defence Game
Favorite Gaming Platforms: N64/Xbox 360/PC/GameCube
Programming Language of Choice: C/++, Java
Location: /usr/home/mv2112
Contact:

Re: mvEngine Development Thread

Post by mv2112 »

So i've been using SDL_Surfaces to load images and i though i would try to load a bitmap manually and i almost succeeded, However the image appears black and white. I was basing my code off of this dudes code. After learing about bit operations and stuff like that, i understand most of the code i wrote but not exactly how the pixel data is organized in the arrays, here is the code i wrote:

Code: Select all

GLuint LoadBMP(const char*file)
{
	ifstream File;
	char shortbuffer[2], intbuffer[4];
	unsigned int Offset=NULL;
	unsigned int header=NULL;
	signed int width=NULL;
	signed int height=NULL;
	int bpr=NULL;
	int size=NULL;
	
	File.open(file,ifstream::binary);
	File.read(shortbuffer,2); //format check
	if(shortbuffer[0]!='B'||shortbuffer[1]!='M')
	{
		File.close();
		assert(!"Error 1");
		return NULL;
	}
	File.ignore(8); //skip the next 4,2 and 2 bytes
	//get buffer offset for pixel data
	File.read(intbuffer,4);
	Offset=(((unsigned char)intbuffer[3]<<24)|
			((unsigned char)intbuffer[2]<<16)|
			((unsigned char)intbuffer[1]<<8)|
			((unsigned char)intbuffer[0]));
	intbuffer={0,0,0,0};
	File.read(intbuffer,4);
	header=(((unsigned char)intbuffer[3]<<24)|
			((unsigned char)intbuffer[2]<<16)|
			((unsigned char)intbuffer[1]<<8)|
			((unsigned char)intbuffer[0]));
	intbuffer={0,0,0,0};
	if(header!=40)
	{
		File.close();
		assert(!"Error 2");
		return NULL;
	}
	File.read(intbuffer,4);
	width=(((unsigned char)intbuffer[3]<<24)|
			((unsigned char)intbuffer[2]<<16)|
			((unsigned char)intbuffer[1]<<8)|
			((unsigned char)intbuffer[0]));
	File.read(intbuffer,4);
	height=(((unsigned char)intbuffer[3]<<24)| //shift in reverse order becuase they were written from left to right maybe?
			((unsigned char)intbuffer[2]<<16)|
			((unsigned char)intbuffer[1]<<8)|
			((unsigned char)intbuffer[0]));
	
	bpr=((width * 3 + 3) / 4) * 4 - (width * 3 % 4); //dont get this
	size=bpr*height;
	
	char*buffer=new char[size];
	char*data=new char[width*height*3];
	
	File.seekg(Offset,std::ios_base::beg);
	File.read(buffer,size);
	
	for(int y=0;y<height;y++)
	{
		for(int x=0;x<width;x++)
		{
			for(int c=0;c<3;c++)
			{
				data[3 * (width * y + x) + c]=buffer[bpr * y + 3 * x + (2 - c)]; //dont get this either...
			}
		}
	}
	File.close();
	delete [] buffer;
	GLuint Texture;
	glGenTextures(1,&Texture);
	glBindTexture(GL_TEXTURE_2D,Texture);
	
	glTexImage2D(GL_TEXTURE_2D,0,3,width,height,0,GL_BGR,GL_UNSIGNED_BYTE,data);
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glFinish();
    delete [] data;
	return Texture;
}
I mostly dont understand the code inside the triple for loop. Can anyone fill me in? Thanks.
qpHalcy0n
Respected Programmer
Respected Programmer
Posts: 387
Joined: Fri Dec 19, 2008 3:33 pm
Location: Dallas
Contact:

Re: mvEngine Development Thread

Post by qpHalcy0n »

Alright, I'm going to save you some time and just tell you that this guy's code is barre none some of the WORST image loading code I have ever seen in my entire life. It is needlessly arcane, it is totally incomplete (he leaves out things in the header that would make this significantly easier), and not to mention, this won't work on all bitmaps.

The size of a structure or class is the size of the types that make it up. IN ORDER! This is key. So rather than doing this horrendously arcane bitshift junk for header reading (although, sure it's "cool" and you can "wow" people with it...although those who know what they're doing will scoff at it), you can simply read in the headers (bitmap has 2 of them) as a single object.

The header layout is like so:

Code: Select all

typedef struct
{
    unsigned short type;                     // Will code out to 0x4D42 which is 19778 in decimal. This equates to "BM" in 8 bit ASCII
    unsigned int     size;                     // This is the size of the chunk
    unsigned short  reserved1;            // Reserved
    unsigned short  reserved2;            // Reserved
    unsigned int      offsetBits;            // pixmap offset (in bytes from beginning of file)
} s_bitmap_header;


typedef struct
{
    unsigned int      bmpSize;               // Pixmap size (bytes)
    int                    bmpWidth;            // Pixmap width (pixels)
    int                    bmpHeight;           // Pixmap height (pixels)
    unsigned short   bmpPlanes;           // Image bitplanes
    unsigned short   bmpBitDepth;        // Image depth (bits per pixel)     <--- important
    unsigned int       bmpCompress;      // Compression tag
    unsigned int       bmpImageSize;      // Physical size
    int                     bmpXPixelsPerMeter;     // Physical size in meters on x
    int                     bmpYPixelsPerMeter;     // Physical size in meters on y
    unsigned int       bmpClrUsed;              
    unsigned int       bmpClrImportant;          
} s_bitmap_info_header;
Now when you read it, it becomes very simple:

Code: Select all

// Assuming you have a valid FILE
FILE* bmpFile;
if( ( bmpFile = fopen( fileName, "rb" ) ) == NULL )
        return false;  //gtfo


// Read Header //
s_bitmap_header fHeader;
fread( &fHeader, sizeof( s_bitmap_header ), 1, bmpFile ); 

// Magic number doesnt check out //
if( fHeader.type != 19778 )
{
      fclose( bmpFile );
      return false;
}

// Read second header //
s_bitmap_info_header fInfoHeader;
fread( &fInfoHeader, sizeof( s_bitmap_info_header ), 1, bmpFile );

int imgWidth = fInfoHeader.bmpWidth;
int imgHeight = fInfoHeader.bmpHeight;
int bpp           = fInfoHeader.bmpBitDepth;

// Allocate the pixmap //
unsigned int pixmapSize = imgWidth * imgHeight * ( bpp / 8 );          // bpp / 8 yields size in bytes
unsigned char* pix = new unsigned char[pixmapSize];

// Read pixmap into buffer //
fread( pix, sizeof( unsigned char ), totalSize, bmpFile );

// Ba-da-bing....clean up your shit, do whatever else you have to do, and done //
}
User avatar
mv2112
Chaos Rift Junior
Chaos Rift Junior
Posts: 240
Joined: Sat Feb 20, 2010 4:15 am
Current Project: Java Tower Defence Game
Favorite Gaming Platforms: N64/Xbox 360/PC/GameCube
Programming Language of Choice: C/++, Java
Location: /usr/home/mv2112
Contact:

Re: mvEngine Development Thread

Post by mv2112 »

qpHalcy0n wrote:

Code: Select all

// Assuming you have a valid FILE
FILE* bmpFile;
if( ( bmpFile = fopen( fileName, "rb" ) ) == NULL )
        return false;  //gtfo


// Read Header //
s_bitmap_header fHeader;
fread( &fHeader, sizeof( s_bitmap_header ), 1, bmpFile ); 

// Magic number doesnt check out //
if( fHeader.type != 19778 )
{
      fclose( bmpFile );
      return false;
}

// Read second header //
s_bitmap_info_header fInfoHeader;
fread( &fInfoHeader, sizeof( s_bitmap_info_header ), 1, bmpFile );

int imgWidth = fInfoHeader.bmpWidth;
int imgHeight = fInfoHeader.bmpHeight;
int bpp           = fInfoHeader.bmpBitDepth;

// Allocate the pixmap //
unsigned int pixmapSize = imgWidth * imgHeight * ( bpp / 8 );          // bpp / 8 yields size in bytes
unsigned char* pix = new unsigned char[pixmapSize];

// Read pixmap into buffer //
fread( pix, sizeof( unsigned char ), totalSize, bmpFile );

// Ba-da-bing....clean up your shit, do whatever else you have to do, and done //
}
Where do you get the totalSize variable in the last fread() function?
Post Reply