Archived

This topic is now archived and is closed to further replies.

Dalton

Texture mapping 2D quads

Recommended Posts

I'm starting up a 2D engine with OpenGL. I'm using the glEnable2d() and glDisable2D() functions shown [url="http://www.gamedev.net/community/forums/topic.asp?topic_id=104791"]here[/url] to get into 2D mode. My problem is with texture mapping. My texture loads successfully, stored at texture[0], a global GLuint (I am using the texture loading process explained by[url="http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=06"] NeHe tutorial 6[/url]). The texture doesn't display when I map it to the vertices of a 2D quad. Perhaps it's because I'm using glTexCoord2f in 2D mode? Also, is there some way to map a texture directly from the coordinates of the pixels of the bitmap, instead of working on a 0.0-1.0 range? Code:
//DrawColRect()//

//Draws a coloured rectangular quad

//Assumes you have begun GL_QUADS

void DrawColRect(int x,int y,int width,int height,char r,char g,char b)
{
	glColor3ub(r,g,b);		//Set the colour

	glVertex2d(x,y);
	glVertex2d(x+width,y);
	glVertex2d(x+width,y+height);
	glVertex2d(x,y+height);
}

//BlitTextRect()//

//Blits a textured rectanglular quad

//Assumes you have begun GL_QUADS

//Assumes you have bound the correct texture

void DrawTextRect(int x,int y,int width,int height,int left,int top,int right,int bottom)
{
	glTexCoord2f(0.0,1.0);
	glVertex2d(x,y);
	glTexCoord2f(0.0,1.0);
	glVertex2d(x+width,y);
	glTexCoord2f(0.0,1.0);
	glVertex2d(x+width,y+height);
	glTexCoord2f(0.0,1.0);
	glVertex2d(x,y+height);
}

//DrawGLScene()//

//Does all the drawing - called by WinMain

int DrawGLScene()
{
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);	//Clear the background

	glLoadIdentity();		//Reset the modelview matrix


	glEnable2D();			//Enable 2D


	glBindTexture(GL_TEXTURE_2D,texture[0]);			//Select Our Texture to draw with


	glBegin(GL_QUADS);		//We're here to draw rectangles!

	
	//Drawing goes here - tiles, sprites, what have you

	DrawColRect(32,32,32,32,155,155,30);
	DrawTextRect(480,320,32,32,32,32,32,32);

	glEnd();

	glDisable2D();

	return true;
}
The colored rect displays fine. The textured rect shows up too, but it is textureless. [edited by - Dalton on April 4, 2004 3:20:23 PM]

Share this post


Link to post
Share on other sites
as far as I can tell, you haven''t enabled textures yet. a call to glEnable( GL_TEXTURE_2D ); should do it. then, when you want to draw an untextured something, I believe you just bind texture 0 -- glBindTexture( GL_TEXTURE_2D, 0 );

hopefully that works for you

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
You need to enable texturing when you draw the textured quad.

If you haven''t already, you might want to purchase the OpenGL programming guide (red book) if you are serious about getting into OpenGL programming. It has a good chapter on texture-mapping.

Share this post


Link to post
Share on other sites
http://fly.cc.fer.hr/~unreal/theredbook/

That is a great link for OpenGL programming.

Another great one (especially for beginners) is
http://nehe.gamedev.net

Texturemapping like you are trying to do is the fastest way to
do 2D stuff in OpenGL, but if you just want to draw pixels, look
into glDrawPixels and related functions. Hope that helps.

It said "Requires Windows 98 or better", so I installed Linux.

Share this post


Link to post
Share on other sites
Well, I think I know part of the problem. As a DirectDraw afficiando, I'm used to (x,y)=(0,0) being in the top left of the screen. It seems I'm working in an environment where (x,y)=(0,0) is in the bottom left of the screen. So I was drawing my vertices in the wrong order, counter-clockwise. I fixed the order, but still the texture doesn't show up. Here:

	glTexCoord2f(0.0f,0.0f); glVertex2d(x,y);
glTexCoord2f(0.0f,1.0f); glVertex2d(x,y+height);
glTexCoord2f(1.0f,1.0f); glVertex2d(x+width,y+height);
glTexCoord2f(1.0f,0.0f); glVertex2d(x+width,y);

Is something still amiss?

[edited by - Dalton on April 4, 2004 8:30:12 PM]

Share this post


Link to post
Share on other sites
The following is a program that I wrote that renders a flame

Please feel free to use my code.

Note: I am not responsible what so ever in what ever damage it
may cause nor am I responsible for any missuse of this code.

flame.c:
//#include "pow.h"
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include </usr/include/GL/gl.h>
#include </usr/include/GL/glu.h>
#include </usr/include/GL/glut.h>
#include "texture.h"
#define maxpar 80
#define PARTICLE 1
#define maxsize 90
float ParXPos[maxpar],ParYPos[maxpar],ParZPos[maxpar],Yamt[maxpar];
float Red[maxpar],Green[maxpar],Blue[maxpar];
static float xrot=50,yrot=0,zrot=0;

void GLUTCALLBACK renderScene(void)
{
int i;
double tim;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glClearDepth(1.0f);
glLoadIdentity ();
glBindTexture(GL_TEXTURE_2D, Texture[0]);
//glRotatef(zrot, 0.0, 1.0, 0.0);
//glRotatef(xrot, 1.0, 0.0, 0.0);
zrot+=0.9;
if (zrot>360) zrot=0;
for (i=0;i //glColor4f(Red,Green[i],Blue[i],1);
//glColor4f(Red[i],Green[i],Blue[i],1);
//printf("%f",Red[i]);
glTranslatef (ParXPos[i], ParYPos[i], -1.0);
glCallList(PARTICLE);
}
for (i=0;i ParYPos[i]-=Yamt[i];
//ParXPos[i]+=0.9;
if (ParYPos[i]<-630) {
ParYPos[i]=270;
//ParXPos[i]=rand()%10+-5;
}
}
glutSwapBuffers();
glFlush();
}
void ParInit(void)
{
int i,h=1,it=0;
float x,y,z;
for (i=0;i if (it==0) xrot+=1.5;
if (it==1) xrot-=1.5;
if (xrot>50) it=1;
if (xrot<4) it=0;
ParXPos[i]=0;
ParYPos[i]=0;
ParZPos[i]=rand()%40+-20;
Yamt[i]=rand()%4+2;
Green[i]=15/(float)(rand()%255+1);
Red[i]=15/(float)(rand()%255+1);
Blue[i]=15/(float)(rand()%255+1);
}
glNewList(PARTICLE, GL_COMPILE);
glBegin(GL_QUADS);
glVertex3f(-maxsize,-maxsize,2);
glTexCoord2f(0.0, 1.0);
glVertex3f(-maxsize,maxsize,2);
glTexCoord2f(0.0, 0.0);
glVertex3f(maxsize,maxsize,2);
glTexCoord2f(1.0, 0.0);
glVertex3f(maxsize,-maxsize,2);
glTexCoord2f(1.0, 1.0);
glEnd();
glEndList();
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(600,600);
glutCreateWindow("FIRE DONE BY WYATT");

glMatrixMode (GL_PROJECTION);
glFrustum (-100.0, 100.0, 100.0, -1000.0, 1.5, 2000.0);
glTranslatef (0.0, 0.0, -5.0); /* viewing transformation */
glViewport (0, 0, 600, 600);
glScalef (1.0, 1.0, 1.0);
glMatrixMode (GL_MODELVIEW);
TextureInit();
BitMapLoad("mask.bmp", 0,0);
ParInit();

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);

glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glDisable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glShadeModel(GL_FLAT);
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);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable(GL_TEXTURE_2D);

glutIdleFunc(renderScene);
glutDisplayFunc(renderScene);
glutMainLoop();
}


texture.h:

#include <malloc.h>
#define maxtex 25
unsigned int Texture[maxtex];
unsigned char *Image[maxtex+1];
void TextureInit()
{
glGenTextures(maxtex, &Texture[0]);
}
void BitMapLoad(char *Name, int mipmap)
{
static int num=-1;
FILE *bmp;
unsigned r,g,b;
int ii, i,temp;
unsigned long Size_X=0, Size_Y=0;

if ((bmp = fopen(Name, "r"))==NULL) {
printf("Could not open %s!!!\n", Name);
exit(1);
} else num++;


fseek(bmp, 18, SEEK_SET);
for (i=0;i<4;i++) {
temp=fgetc(bmp);
Size_X+=(temp<<8*i);
}
for (i=0;i<4;i++) {
temp=fgetc(bmp);
Size_Y+=(temp<<8*i);
}
if ((Image[num]=malloc(((Size_X*Size_Y)*sizeof(int)*3)))==NULL) {
printf("Could not allocate memory!");
exit(1);
}

fseek(bmp, 54, SEEK_SET);
for (ii=0;ii for (temp=0;temp for (i=0;i b=fgetc(bmp);
g=fgetc(bmp);
r=fgetc(bmp);
//col=(r+g+b)/3;
Image[num][(ii*Size_X*3)+i]=r;
Image[num][(ii*Size_X*3)+i+1]=g;
Image[num][(ii*Size_X*3)+i+2]=b;
}
}
glBindTexture(GL_TEXTURE_2D, Texture[num]);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, 0);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if (mipmap==1) {
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_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, (unsigned int)Size_X, (unsigned int)Size_Y,
GL_RGB, GL_UNSIGNED_BYTE,
&Image[num][0]);
}
if (mipmap==0) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, Size_X, Size_Y, 0, GL_RGB, GL_UNSIGNED_BYTE, &Image[num][0]);
}
printf("\n%ld, %ld\n", Size_X, Size_Y);
fclose (bmp);
}

Share this post


Link to post
Share on other sites
Shiiiiiiit the fact of the matter is, I am a stupid noob. I was loading the texture before even creating my window, or initializing OpenGL.

Share this post


Link to post
Share on other sites
You may also want to note that all textures in OpenGL must have
even widths and heights. Example a texture sized: 129, 128 won''t work, however a texture 128, 128 will.

Share this post


Link to post
Share on other sites