PDA

View Full Version : Put an image as backgroun in a quad



ejgutierrez
03-29-2016, 03:52 AM
You can read a piece of code: the idea is to fullfill a polygon quad with a texture ( the image is repeated inside the quad).

The code is : coliru.stacked-crooked.com/a/400b648e7442eeb3 ( dont know why i cant attach URL)
I want that the image would repeat only once: in other words to put the image as background of the polygon. Im in a 800x600 window, and i would like to put a billiards table for example 600x400 ( in a quad defined by the glvertex3i). It could be glvertex2i and implemented in 2D,as is a 2D game.

Any help would be apreciated

Also i have a better code to support any jpg file instead of loadtexture and readjpeg( i think):


GLuint MyLoadTexture(std::string const filename)
{
GLuint texname = 0;
/* this is actually tied to the OpenGL context, so this should
* actually be a map GLcontext -> std::string -> texturename */
static std::map<std::string, GLuint> loaded_textures;
if( loaded_textures.find(filename) != loaded_textures.end() ) {
texname = loaded_textures[filename];
glBindTexture(GL_TEXTURE_2D, texname);
return texname;
}

int width,height;
std::vector<uint8_t> image;
if( ReadJPEG(filename, &image, &width, &height) ) {
std::cerr
<< "error reading JPEG"
<< std::endl;
return 0;
}

glGenTextures(1, &texname);
if( !texname ) {
std::cerr
<< "error generating OpenGL texture name"
<< std::endl;
return 0;
}

glBindTexture(GL_TEXTURE_2D, texname);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_LINEAR);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_RE PLACE);

/* glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGB,
width, height, 0,
GL_RGB,
GL_UNSIGNED_BYTE, buffer );
*/
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGB,
width, height, 0,
GL_RGB,
GL_UNSIGNED_BYTE, &image[0]);

loaded_textures[filename] = texname;

return texname;
}

int ReadJPEG(
std::string const filename,
std::vector<uint8_t> *image,
int *width, int *height )
{
if( !image ) {
return -1;
}

FILE * const infile = fopen(filename.c_str(), "rb");
if( !infile ) {
std::cerr
<< "error opening file "
<< filename
<< " : "
<< strerror(errno)
<< std::endl;
return -2;
}

struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);

jpeg_create_decompress(&cinfo);

jpeg_stdio_src(&cinfo, infile);
jpeg_read_header(&cinfo, TRUE);
jpeg_calc_output_dimensions(&cinfo);
jpeg_start_decompress(&cinfo);

if( width ) { *width = cinfo.output_width; }
if( height ) { *height = cinfo.output_height; }

size_t const stride = cinfo.output_width * cinfo.output_components;
image->resize(cinfo.output_height * stride);

for(size_t i = 0; i < cinfo.output_height;) {
uint8_t * const row = &(*image)[stride * i];
i += jpeg_read_scanlines(&cinfo, (unsigned char**)&row, 1);
}
jpeg_finish_decompress(&cinfo);

fclose(infile);
return 0;
}

ejgutierrez
03-29-2016, 03:55 AM
You can read a piece of code: the idea is to fullfill a polygon quad with a texture ( the image is repeated inside the quad).

I want that the image would repeat only once: in other words to put the image as background of the polygon. Im in a 800x600 window, and i would like to put a billiards table for example 600x400 ( in a quad defined by the glvertex3i). It could be glvertex2i and implemented in 2D,as is a 2D game.

Any help would be apreciated

Also i have a better code to support any jpg file instead of loadtexture and readjpeg( i think):


GLuint MyLoadTexture(std::string const filename)
{
GLuint texname = 0;
/* this is actually tied to the OpenGL context, so this should
* actually be a map GLcontext -> std::string -> texturename */
static std::map<std::string, GLuint> loaded_textures;
if( loaded_textures.find(filename) != loaded_textures.end() ) {
texname = loaded_textures[filename];
glBindTexture(GL_TEXTURE_2D, texname);
return texname;
}

int width,height;
std::vector<uint8_t> image;
if( ReadJPEG(filename, &image, &width, &height) ) {
std::cerr
<< "error reading JPEG"
<< std::endl;
return 0;
}

glGenTextures(1, &texname);
if( !texname ) {
std::cerr
<< "error generating OpenGL texture name"
<< std::endl;
return 0;
}

glBindTexture(GL_TEXTURE_2D, texname);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_LINEAR);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_RE PLACE);

/* glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGB,
width, height, 0,
GL_RGB,
GL_UNSIGNED_BYTE, buffer );
*/
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGB,
width, height, 0,
GL_RGB,
GL_UNSIGNED_BYTE, &image[0]);

loaded_textures[filename] = texname;

return texname;
}

int ReadJPEG(
std::string const filename,
std::vector<uint8_t> *image,
int *width, int *height )
{
if( !image ) {
return -1;
}

FILE * const infile = fopen(filename.c_str(), "rb");
if( !infile ) {
std::cerr
<< "error opening file "
<< filename
<< " : "
<< strerror(errno)
<< std::endl;
return -2;
}

struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);

jpeg_create_decompress(&cinfo);

jpeg_stdio_src(&cinfo, infile);
jpeg_read_header(&cinfo, TRUE);
jpeg_calc_output_dimensions(&cinfo);
jpeg_start_decompress(&cinfo);

if( width ) { *width = cinfo.output_width; }
if( height ) { *height = cinfo.output_height; }

size_t const stride = cinfo.output_width * cinfo.output_components;
image->resize(cinfo.output_height * stride);

for(size_t i = 0; i < cinfo.output_height;) {
uint8_t * const row = &(*image)[stride * i];
i += jpeg_read_scanlines(&cinfo, (unsigned char**)&row, 1);
}
jpeg_finish_decompress(&cinfo);

fclose(infile);
return 0;
}

The code is: coliru.stacked-crooked.com/a/400b648e7442eeb3

ejgutierrez
04-05-2016, 11:47 PM
Please can anyone help ??

reaktor24
04-06-2016, 04:03 AM
You need to research texture wrapping using GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T.

Here is a link with some info:
http://gamedev.stackexchange.com/questions/62548/what-does-changing-gl-texture-wrap-s-t-do