PDA

View Full Version : Problem with PNG texture



Tiago C. Carvalho
04-02-2005, 01:28 PM
I did some code, Im just a begginer, to import png files, to try to make a 2D like game, but the thing is th ecode works, but only with images like 32x32, 64x64, 128x128, 256x256, 512x512, things like these, and the quality of the image is not like the original either.

I tried to put the code in here, but it says something about ( and html tags.. but anyway, i can send the code if you want.

Thank you for your attetion,
Tiago

RigidBody
04-02-2005, 01:40 PM
i guess you try to use png files as textures.

in opengl, usually, textures need to have a size that is a power of two (2, 4, 8, etc...)

there is an extension that allows you to use textures with different sizes (i have to admit i've never used them). but if you want to keep it simple, there is the function gluScaleImage which allows you to scale an image of arbitrary size to a size which has a power of 2.

RigidBody
04-02-2005, 01:44 PM
and...if you want to post code here, click on the <code> button below.

Tiago C. Carvalho
04-02-2005, 03:02 PM
Thanks for the reply, how does this gluScaleImage function works?

Im trying to make a game where I can modify the content just with txt files, like what images to load and where, where i can click, display a matrix of images and later i want to try to put some text with opengl, with i have miserable failed until now, =P

Here is the code and thank you for your attetion:


#include <windows.h>
#include "gl/glut.h"
#include <stdlib.h>
#include <fstream.h>
#include "png/png.h"

char *screen=new char[40];
char *buttons=new char[40];
char *map=new char[40];
GLuint *texture;
GLuint *texturemap;

static GLuint pngBind(char *filename, int wrapst, int minf, int magf, int alpha)
{
png_structp png_ptr;
png_infop info_ptr;
unsigned int sig_read = 0;
FILE *fp;

if ((fp = fopen(filename, "rb")) == NULL)
return false;

png_ptr=png_create_read_struct(PNG_LIBPNG_VER_STRI NG,NULL,NULL,NULL);

if (png_ptr == NULL)
{
fclose(fp);
return false;
}

info_ptr = png_create_info_struct(png_ptr);

if (info_ptr == NULL)
{
fclose(fp);
png_destroy_read_struct(&amp;png_ptr, png_infopp_NULL, png_infopp_NULL);
return false;
}

if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&amp;png_ptr, &amp;info_ptr, png_infopp_NULL);
fclose(fp);
return false;
}

png_init_io(png_ptr, fp);

png_set_sig_bytes(png_ptr, sig_read);

png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);

int height = png_get_image_height(png_ptr, info_ptr);
int width = png_get_image_width(png_ptr, info_ptr);

int row=png_get_rowbytes(png_ptr, info_ptr);

int channels=png_get_channels(png_ptr, info_ptr);

channels++;

GLubyte image[height][width][channels];

bool putalpha=false;
for (int i =0; i<height; i++)
for (int j =0; j<width; j++)
for (int k =0; k<channels; k++)
if (alpha==1)
{
if (k!=3)
{
image[i][j][k]=(GLubyte)info_ptr->row_pointers[i][(j*(channels-1))+k];
if (k==2)
if (image[i][j][k]==10 &amp;&amp; image[i][j][k-1]==10 &amp;&amp; image[i][j][k-2]==10)
putalpha=true;
}
else if (putalpha==true)
{
image[i][j][k]=0;
putalpha=false;
}
else
image[i][j][k]=255;
}
else
image[i][j][k]=(GLubyte)info_ptr->row_pointers[i][(j*(channels-1))+k];

if (alpha==0)
{
for (int i =0; i<height; i++)
for (int j =0; j<width; j++)
image[i][j][3]=255;
}

static GLuint texName;

glGenTextures(1, &amp;texName);
glBindTexture(GL_TEXTURE_2D, texName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapst);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapst);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,magf);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,minf);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width,
height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);

fclose(fp);

return texName;
}

void BindTexture(const char* name, int tipo)
{
ifstream file;
int temp;

char *newname=new char[40];
strcpy(newname,name);
strcat(newname,"_image.txt");

file.open(newname);
file>>temp;

if (tipo==0)
{
free(texture);
texture=new GLuint[temp];
glGenTextures(temp, texture);
}
else if (tipo==1)
{
free(texturemap);
texturemap=new GLuint[temp];
glGenTextures(temp, texturemap);
}

int alpha;
char text[40];
for (int i=0;i<temp;i++)
{
file>>alpha;
file>>text;
if (tipo==0)
texture[i]=pngBind(text,GL_CLAMP,GL_LINEAR,GL_LINEAR,alpha);
else if (tipo==1)
texturemap[i]=pngBind(text,GL_CLAMP,GL_LINEAR,GL_LINEAR,alpha);
}

file.close();
}

void DisplayMap(void)
{
ifstream file;
int x,y;

char *mapposition=new char[40];
strcpy(mapposition,map);
strcat(mapposition,"_position.txt");

file.open(mapposition);
file>>x;
file>>y;

int matrix[x][y];

for (int i=0;i<x;i++)
for (int j=0;j<y;j++)
{
file>>matrix[i][j];
}

glEnable(GL_TEXTURE_2D);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_NOTEQUAL,0);

for (int i=0;i<x;i++)
for (int j=0;j<y;j++)
{
glBindTexture(GL_TEXTURE_2D, texturemap[matrix[i][j]]);
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex2f (50+32*i ,440-(32*(j+1)));
glTexCoord2f(0,1); glVertex2f (50+32*i ,440-(32*j) );
glTexCoord2f(1,1); glVertex2f (50+32*(i+1),440-(32*j) );
glTexCoord2f(1,0); glVertex2f (50+32*(i+1),440-(32*(j+1)));
glEnd();
}

glDisable(GL_ALPHA_TEST);
glDisable(GL_TEXTURE_2D);

file.close();
}

void Clear(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0, 1.0, 1.0);
}

void Update(void)
{
glutPostRedisplay();
}

void Display(void)
{
ifstream file;
int temp;

char *screenposition=new char[40];
strcpy(screenposition,screen);
strcat(screenposition,"_position.txt");

file.open(screenposition);
file>>temp;

glEnable(GL_TEXTURE_2D);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_NOTEQUAL,0);

float temp2[4];
for (int i=0;i<temp;i++)
{
glBindTexture(GL_TEXTURE_2D, texture[i]);
glBegin(GL_QUADS);
for (int k=0;k<4;k++)
{
for (int j=0;j<4;j++)
file>>temp2[j];
glTexCoord2f(temp2[0],temp2[1]); glVertex2f (temp2[2],temp2[3]);
}
glEnd();
}

glDisable(GL_ALPHA_TEST);
glDisable(GL_TEXTURE_2D);

file.close();

glutSwapBuffers();
}

void KeyPress(unsigned char key, int x, int y)
{
switch (key)
{
case 27: /*ESC*/ glutDestroyWindow(glutGetWindow()); exit(0); break;
}
}

void Mouse(int button, int state, int x, int y)
{
switch (button)
{
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN)
{
ifstream file;
file.open(buttons);

int temp;
file>>temp;
for (int i=0;i<temp;i++)
{
int tipo;
file>>tipo;

int temp2[4];
for (int j=0;j<4;j++)
file>>temp2[j];
if (x>temp2[0] &amp;&amp; x<temp2[1] &amp;&amp; y>temp2[2] &amp;&amp; y<temp2[3])
{
if (tipo==0)
{
free(screen);screen=new char[40];
file>>screen;
free(buttons);buttons=new char[40];
file>>buttons;
BindTexture(screen,0);
Clear();
Update();
return;
}
else if (tipo==1)
exit(0);
else if (tipo==2)
{
free(screen);screen=new char[40];
file>>screen;
free(buttons);buttons=new char[40];
file>>buttons;
free(map);map=new char[40];
file>>map;
BindTexture(screen,0);
BindTexture(map,1);
Clear();
DisplayMap();
Update();
return;
}
}
else if (tipo==0)
{
char temp3[40];
file>>temp3;
file>>temp3;
}
else if (tipo==2)
{
char temp3[40];
file>>temp3;
file>>temp3;
file>>temp3;
}
}
file.close();
}
break;

default:
break;
}
}

int main(int argc, char * argv[])
{
screen="display/menu";
buttons="mouse/menu.txt";
map=NULL;

glutInit( &amp;argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE);
glutGameModeString( "640x480:16@60" );
glutEnterGameMode();
gluOrtho2D(0.0,640,0.0,480);
glutDisplayFunc( Display );
glutKeyboardFunc( KeyPress );
glutMouseFunc( Mouse );
// glutIdleFunc( Update );

BindTexture(screen,0);
Clear();
glutMainLoop();

return 0;
}

Tiago C. Carvalho
04-02-2005, 03:07 PM
The txts files that i use, in the Display folder:

menu_image.txt:


6

0 image/f11.png
0 image/f12.png
0 image/f13.png
0 image/f14.png
0 image/f15.png
0 image/f16.png
menu_position.txt


6

0.0 1.0 0 224
0.0 0.0 0 480
1.0 0.0 256 480
1.0 1.0 256 224

0.0 0.875 0 0
0.0 0.0 0 224
1.0 0.0 256 224
1.0 0.875 256 0

0.0 1.0 256 224
0.0 0.0 256 480
1.0 0.0 512 480
1.0 1.0 512 224

0.0 0.875 256 0
0.0 0.0 256 224
1.0 0.0 512 224
1.0 0.875 512 0

0.0 1.0 512 224
0.0 0.0 512 480
0.5 0.0 640 480
0.5 1.0 640 224

0.0 0.875 512 0
0.0 0.0 512 224
0.5 0.0 640 224
0.5 0.875 640 0
In the Mouse folder:

menu.txt


4

2

400 590 50 125

display/menu3
mouse/menu2.txt
map/map

0

400 590 150 225

display/menu2
mouse/menu2.txt

0

400 590 250 325

display/menu3
mouse/menu3.txt

1

400 590 350 425
And there is a Image folder too, and Map folder to display a matrix of images, i had to use 6 images of 256x256 to display a 640x480 image..