I'm programming in c++ in opengl.
I'm supposed to make a texture and I made the following code:
void makeCheckImage(void){
int i, j, c;
for (i = 0; i < checkImageHeight; i++) {
for (j = 0; j < checkImageWidth; j++) {
c = ((((i&0x8)==0)^((j&0x8))==0))*255;
checkImage[i][j][0] = (GLubyte) c;
checkImage[i][j][1] = (GLubyte) c;
checkImage[i][j][2] = (GLubyte) c;
checkImage[i][j][3] = (GLubyte) 255;
}
}
}
void init(void){
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
makeCheckImage();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_2D, texName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth,
checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
checkImage);
}
my problem is that this beautiful piece of code (or maybe not) is applying textures to the whole scene! And I just want it to apply to one object...
Can anybody help me?
glEnable(GL_TEXTURE_2D);
//Draw object
glDisable(GL_TEXTURE_2D);
Related
I have problem freetype and OpenGL. I need just draw all loaded symbols on single texture. Here's:
FT_Init_FreeType(&lib);
FT_New_Face(lib, "C:\\verdana.ttf", 0, &face);
FT_Set_Pixel_Sizes(face, 0, size);
auto ww = 256 * size;
auto hh = size;
std::vector<unsigned char> buffer(ww * hh, 0);
int off = 0;
for (int c = 0; c < 256; c++)
{
FT_UInt GlyphIndex;
GlyphIndex = FT_Get_Char_Index(face, c);
FT_Load_Char(face, GlyphIndex, FT_LOAD_RENDER);
FT_Bitmap bmp = face->glyph->bitmap;
int advance = (face->glyph->advance.x >> 6);
int bW = bmp.width;
int bH = bmp.rows;
for (int h = 0; h < bH; ++h) {
for (int w = 0; w < bW; ++w) {
buffer[h * bW + off + w] = bmp.buffer[w + bW * h];
}
}
off += advance;
}
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, ww, hh, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &buffer[0]);
I tried many ways to do this. But all I get is absolutely black texture...
What's wrong with my code?
I think the problem is that some values between 0-255 is not visible or drawable character and that's why you get nothing.
you should check for GlyphIndex:
GlyphIndex = FT_Get_Char_Index(face, c);
if (!GlyphIndex) continue;
then you can expect freetype to draw the rest of characters for you.
hallelujah, I got solution!
This should look like this:
for (int c = 0; c < 256; c++)
{
FT_UInt GlyphIndex;
GlyphIndex = FT_Get_Char_Index(face, c);
FT_Load_Char(face, GlyphIndex, FT_LOAD_RENDER);
FT_Bitmap bmp = face->glyph->bitmap;
int advance = (face->glyph->advance.x >> 6);
int bW = bmp.width;
int bH = bmp.rows;
for (int h = 0; h < bH; ++h) {
for (int w = 0; w < bW; ++w) {
buffer[h * ww + off + w] = bmp.buffer[w + bW * h];
}
}
off += advance;
}
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, ww, hh, 0, GL_RED, GL_UNSIGNED_BYTE, &buffer[0]);
I am creating a flat surface and applying a texture for it. But for some reason the texture is not getting applied properly. I am getting something like this.
This is the code that I am using (I have a class for applying textures),
for(int i = 0; i < 512; i++) {
for(int j = 0; j < 512; j++) {
int c = ((((i&0x8)==0)^(((j&0x8))==0)))*255;
checkImage[i][j][0] = (GLubyte) c;
checkImage[i][j][1] = (GLubyte) c;
checkImage[i][j][2] = (GLubyte) c;
checkImage[i][j][3] = (GLubyte)255;
//cout<<"("<<(int)dataForPixel.rgbtRed<<","<<(int)dataForPixel.rgbtGreen<<","<<(int)dataForPixel.rgbtBlue<<")";
}
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_2D, texName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
imageX,
imageY,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
checkImage
);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBindTexture(GL_TEXTURE_2D, texName);
glBegin(GL_QUADS);
glTexCoord2d(0.0, 0.0); glVertex3d(-100, -100, 0.0);
glTexCoord2d(0.0, 1.0); glVertex3d(-100, 100, 0.0);
glTexCoord2d(1.0, 1.0); glVertex3d( 100, 100, 0.0);
glTexCoord2d(1.0, 0.0); glVertex3d( 100, -100, 0.0);
glEnd();
The image is a 512 x 512 image.
Why is the texture not applying properly.
UPDATE:
The c value is just for producing a chess board pattern which consists of squares of 8 pixels width and height of alternating black and white.
Ok I found out the problem. Seems i was trying to allocate the checkImage memory dynamically but not in one go. So there were gaps in the memory which the OpenGL did not bother with.
Once I fixed it to allocate the memory as one big chunk it worked.
(i've updated the code the new better one)
http://www.flickr.com/photos/pkerkm/8251188947/in/photostream
good directions
http://www.flickr.com/photos/pkerkm/8252258464/in/photostream
bad directions
We are using SOIL library
C++
openGL
We drew the symbols of N, S, W, E on one of the images we are displaying, because we thought that the images are being flipped or displayed incorrectly. We were right, but not sure why and how to fix it. Our W is up, E is down, S is right and N is left. This means, that the symbol N is on the left side, as to where it should be on the up part.
Here is the code where we generate the 3-dimmentional array and our pictures.
void genTex(){
texture[0]=SOIL_load_OGL_texture // load an image file directly as a new OpenGL texture
(
"C:\\Users\\Pkerkm\\Documents\\Visual Studio 2010\\Projects\\files\\gameprojecgraphics\\bloodwall2.png",
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
void /*GraphicsEngine::*/generateMap(){
int i, k, j;
double coordinates[8][3];
for(i=0; i<MAPWIDTH; i++){
for(j=0; j<MAPHEIGHT; j++){
for(k=0; k<MAPDEPTH; k++){
if(stage[i][j][k]==0){
//do nothing
}
else if (stage[i][j][k]==1){
getWallCoordinates(coordinates, i, j, k);
if(j==0 || stage[i][j-1][k]==0){
drawWall(coordinates[0],coordinates[1],coordinates[2],coordinates[3],true);
}
if(j<MAPHEIGHT-1 && stage[i][j+1][k]==0){drawWall(coordinates[7],coordinates[6],coordinates[5],coordinates[4],false);
}
if(i==0 || stage[i-1][j][k]==0){drawWall(coordinates[7],coordinates[4],coordinates[0],coordinates[3],false);
}
if(k==MAPDEPTH-1 || stage[i][j][k+1]==0){drawWall(coordinates[7],coordinates[3],coordinates[2],coordinates[6],false);
}
if(i==MAPWIDTH-1 || stage[i+1][j][k]==0){drawWall(coordinates[6],coordinates[2],coordinates[1],coordinates[5],false);
}
if(k==0 || stage[i][j][k-1]==0){drawWall(coordinates[5],coordinates[1],coordinates[0],coordinates[4],false);
}
}
}
}
}
}
void /*GraphicsEngine::*/drawWall(double a[3],double b[3], double c[3], double d[3], bool floor){
//glColor3f(1.0,0.0,1.0);
if(floor){
glBindTexture(GL_TEXTURE_2D, texture[1]);
}else{
glBindTexture(GL_TEXTURE_2D, texture[0]);
}
//GLuint tex;
//glGenTextures(1, &tex);
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_MODULATE );
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
//tex = LoadTexture("wallsprite.png");
//glBindTexture(GL_TEXTURE_2D, tex);
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
//glNormal3f(0, 1, 0);
glTexCoord2d(0.0,0.0);
glVertex3dv(a);
glTexCoord2d(-1.0,0.0);
//glVertex3dv(b);
glVertex3dv(d);
glTexCoord2d(-1.0,-1.0);
glVertex3dv(c);
glTexCoord2d(0.0,-1.0);
//glVertex3iv(d);
glVertex3dv(b);
glEnd();
/*glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-2.0, 1.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(0.0, 1.0, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f(0.0, -1.0, 0.0);*/
glDisable( GL_TEXTURE_2D );
}
}
I am thinking the problem is in here, but not sure how to fix it
void /*GraphicsEngine::*/getWallCoordinates(double coordinates[8][3], double x, double y, double z){
int i;
for(i=0;i<8; i++){
if((i/4)>=1){
coordinates[i][1]=BLOCKHEIGHT*(y+1);
}else{
coordinates[i][1]=BLOCKHEIGHT*y;
}
if((i/2)%2==0){
coordinates[i][2]=BLOCKDEPTH*z;
}else{
coordinates[i][2]=BLOCKDEPTH*(z+1);
}
if((i%4)%3==0){
coordinates[i][0]=BLOCKWIDTH*x;
}else{
coordinates[i][0]=BLOCKWIDTH*(x+1);
}
}
}
Simply switch the glTexCoord2f instructions around to rotate the texture by 90 degrees.
I'm trying to generate textures like so:
#define checkImageWidth 64
#define checkImageHeight 64
static GLubyte checkImage[checkImageHeight][checkImageWidth][4];
static GLubyte otherImage[checkImageHeight][checkImageWidth][4];
static GLuint texName[2];
void makeCheckImages(void)
{
int i, j, c;
for (i = 0; i < checkImageHeight; i++) {
for (j = 0; j < checkImageWidth; j++) {
c = ((((i&0x8)==0)^((j&0x8))==0))*255;
checkImage[i][j][0] = (GLubyte) c;
checkImage[i][j][1] = (GLubyte) c;
checkImage[i][j][2] = (GLubyte) c;
checkImage[i][j][3] = (GLubyte) 255;
c = ((((i&0x10)==0)^((j&0x10))==0))*255;
otherImage[i][j][0] = (GLubyte) c;
otherImage[i][j][1] = (GLubyte) 0;
otherImage[i][j][2] = (GLubyte) 0;
otherImage[i][j][3] = (GLubyte) 255;
}
}
}
void init(void)
{
glClearColor (1.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
makeCheckImages();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(2, texName);
glBindTexture(GL_TEXTURE_2D, texName[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth,
checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
checkImage);
glBindTexture(GL_TEXTURE_2D, texName[1]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth,
checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
otherImage);
glEnable(GL_TEXTURE_2D);
engineGL.current.tex = texName[1];
}
But when I check the values of texName[0] and [1] they are both 0, I do not understand why, what am I doing wrong. Thanks.
You probably are calling glGenTextures before creating the OpenGL context, and that will generate a GL error. Don't try to create textures before you've initialized OpenGL.
I had this problem, and glGetError() was returning 0.
In my case it was caused by calling glGenTextures(...) on a different thread to the one the GL context was created on (because I was loading the textures asynchronously). Calling it from the main thread after the async load made glGenTextures(...) start working again.
Try calling glGetError. It should tell you in more detail what went wrong. In general, if an OpenGL function fails, the first thing you do should be to ask OpenGL why it failed. It knows, because it just tried to execute the function.
It's much harder for us to guess at what might have gone wrong.
In my case, I was "lazy loading" my texture, so the glGenTexture was inside a glBegin / glEnd command !
before calling glGenTexture, your opengl context must be created and XXXMakeCurrent'ed
Do I have to set up my gl context in a certain way to bind textures. I'm following a tutorial. I start by doing:
#define checkImageWidth 64
#define checkImageHeight 64
static GLubyte checkImage[checkImageHeight][checkImageWidth][4];
static GLuint texName;
void makeCheckImage(void)
{
int i, j, c;
for (i = 0; i < checkImageHeight; i++) {
for (j = 0; j < checkImageWidth; j++) {
c = ((((i&0x8)==0)^((j&0x8))==0))*255;
checkImage[i][j][0] = (GLubyte) c;
checkImage[i][j][1] = (GLubyte) c;
checkImage[i][j][2] = (GLubyte) c;
checkImage[i][j][3] = (GLubyte) 255;
}
}
}
void initt(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
makeCheckImage();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_2D, texName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth,
checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
checkImage);
engineGL.current.tex = texName;
}
In my rendering I do:
PolygonTesselator.Begin_Contour();
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBindTexture(GL_TEXTURE_2D, current.tex);
if(layer[currentlayer].Shapes[i].Contour[c].DrawingPoints.size() > 0)
{
glColor4f(
layer[currentlayer].Shapes[i].Color.r,
layer[currentlayer].Shapes[i].Color.g,
layer[currentlayer].Shapes[i].Color.b,
layer[currentlayer].Shapes[i].Color.a);
}
for(unsigned int j = 0; j < layer[currentlayer].Shapes[i].Contour[c].DrawingPoints.size(); ++j)
{
gluTessVertex(PolygonTesselator.tobj,&layer[currentlayer].Shapes[i].Contour[c].DrawingPoints[j][0],
&layer[currentlayer].Shapes[i].Contour[c].DrawingPoints[j][0]);
}
PolygonTesselator.End_Contour();
}
glDisable(GL_TEXTURE_2D);
}
However it still renders the color and not the texture at all. I'd atleast expect to see black or something but its as if the bind fails. Am I missing something?
Thanks
It looks like from that code that you don't set any UVs.
Edit: Does it make any difference using GL_MODULATE instead of GL_DECAL? (Am taking guesses here because I suspect the problem lies in code you haven't provided, or in gluTessVertex itself ...