000
16.02.2006, 21:16 Uhr
~123vorbei
Gast
|
Hi, ich versuche seit einigen Tagen eine Kugel mit OpenGL zu texturieren, aber erhalte immer nur eine einfarbige untexturierte Kugel als Ausgabe, und mittlerweile fällt mir nicht mehr viel ein woran ich rumprobieren könnte.
Soweit ich weiß, müssen folgende Schritte erfolgen damit die Textur zu sehen ist: 1:bmp laden und eine ID zuweisen, damit OpenGL sie verwenden kann 2:Vektorkoordinaten des Objekts Texturkoordinaten zuweisen. 3:Objekt zeichnen
Auszug aus dem Objektkonstruktor:
Zitat: |
int num_texture=-1; texture=this->LoadBitmap("tex2.bmp ");
|
in texture wird die TexturID gespeichert, und num_texture wird von dieser LoadBitmap Funktion zurückgegeben, die scheinbar funktioniert, ich habe sie auch nahezu 1:1 aus einem Tutorial übernehmen können, in der Schleife in der die RGB Koordinaten ausgelesen werden, konnte ich die einzelnen Farbpixel abgreifen:
Zitat: |
int Planet::LoadBitmap(char *filename) { int i, j=0; //Index variables FILE *l_file; //File pointer unsigned char *l_texture; //The pointer to the memory zone in which we will load the texture
// windows.h gives us these types to work with the Bitmap files BITMAPFILEHEADER fileheader; BITMAPINFOHEADER infoheader; RGBTRIPLE rgb;
num_texture++; // The counter of the current texture is increased
if( (l_file = fopen(filename, "rb"))==NULL) return (-1); // Open the file for reading
fread(&fileheader, sizeof(fileheader), 1, l_file); // Read the fileheader
fseek(l_file, sizeof(fileheader), SEEK_SET); // Jump the fileheader fread(&infoheader, sizeof(infoheader), 1, l_file); // and read the infoheader
// Now we need to allocate the memory for our image (width * height * color deep) l_texture = (byte *) malloc(infoheader.biWidth * infoheader.biHeight * 4); // And fill it with zeros memset(l_texture, 0, infoheader.biWidth * infoheader.biHeight * 4);
// At this point we can read every pixel of the image for (i=0; i < infoheader.biWidth*infoheader.biHeight; i++) { // We load an RGB value from the file fread(&rgb, sizeof(rgb), 1, l_file);
// And store it l_texture[j+0] = rgb.rgbtRed; // Red component l_texture[j+1] = rgb.rgbtGreen; // Green component l_texture[j+2] = rgb.rgbtBlue; // Blue component l_texture[j+3] = 255; // Alpha value j += 4; // Go to the next position }
fclose(l_file); // Closes the file stream
glBindTexture(GL_TEXTURE_2D, num_texture); // Bind the ID texture specified by the 2nd parameter
// The next commands sets the texture parameters glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // If the u,v coordinates overflow the range 0,1 the image is repeated glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // The magnification function ("linear" produces better results) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); //The minifying function
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); // We don't combine the color with the original surface color, use only the texture map. // Finally we define the 2d texture glTexImage2D(GL_TEXTURE_2D, 0, 4, infoheader.biWidth, infoheader.biHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, l_texture);
// And create 2d mipmaps for the minifying function gluBuild2DMipmaps(GL_TEXTURE_2D, 4, infoheader.biWidth, infoheader.biHeight, GL_RGBA, GL_UNSIGNED_BYTE, l_texture);
free(l_texture); // Free the memory we used to load the texture
return (num_texture); // Returns the current texture OpenGL ID }
|
Hier die eigentliche Zeichenfunktion für das Objekt:
Zitat: |
void Planet::draw(float erdrotation, float distance) { glLoadIdentity(); glTranslatef(xpos,ypos,zpos); glRotatef(23,0,0,1); // natuerliche Schiefstellung um 23° glRotatef(90,1,0.0f,0.0f); // Ausrichtung des Drahtgitters glRotatef(erdrotation,0,0,1); // Erdrotation glColor3f(0.5f,1.5f,1.5f);
glBegin(GL_LINES); // Drehachse glColor3f(1,0,0); glVertex3f(0,0,radius+radius/5); glVertex3f(0,0,-radius-radius/5); glEnd(); glColor3f(0.5f,1.5f,1.5f); GLUquadricObj *qkugel; glEnable(GL_TEXTURE_2D); qkugel = gluNewQuadric(); gluQuadricDrawStyle( qkugel, GLU_FILL ); glTexGenf(GL_S,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP); //richtig verwendet? glTexGenf(GL_T,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP); gluQuadricTexture(qkugel,GL_TRUE); glBindTexture(GL_TEXTURE_2D, texture); gluSphere(qkugel,double(radius), 15, 15); // Erdkugel Log_L1("texture", "%d", num_texture); gluDeleteQuadric( qkugel ); glFlush(); glDisable(GL_TEXTURE_2D); }
|
Ich glaube ich habe vergessen den Vektoren die Texturkoordinaten zuzweisen. Das muss ich ja bei einer Kugel nicht von Hand machen, sondern OpenGL übernimmt das ja für mich soweit ich weiß mit dem Befehl glTexGen, aber wo genau in die Zeichenfunktion muss dieser?
Und in welchen Viewmode muss ich umschalten wenn ich die Sphere zeichne? Ich nehme an GL_TEXTURE.(richtig) ? Habs schon getestet, also vor dem Zeichnen der Kugel auf GL_TEXTURE gesetzt, und danach auf GL_MODELVIEW, hat aber auch nicht funktioniert.
Besten Dank für jede Hilfe. |