OpenGL

0

Program nie wczytuje tekstury.

 #  include <stdio.h>
#  include <stdlib.h>
#  include <errno.h>
#  include <windows.h>
#  include <wingdi.h>

#  include <GL/gl.h>

/*
 * Make this header file work with C and C++ source code...
 */

/*
extern void *LoadDIBitmap(char *filename, BITMAPINFO **info);
extern int  SaveDIBitmap(char *filename, BITMAPINFO *info, void *bits);
extern void *ReadDIBitmap(BITMAPINFO **info);
extern int  PrintDIBitmap(HWND owner, BITMAPINFO *info, void *bits);

extern GLubyte  *ConvertRGB(BITMAPINFO *info, void *bits);

 */

/*
 * 'LoadDIBitmap()' - Load a DIB/BMP file from disk.
 *
 * Returns a pointer to the bitmap if successful, NULL otherwise...
 */

void *
LoadDIBitmap(char   *filename,  /* I - File to load */
             BITMAPINFO **info)     /* O - Bitmap information */
{
  FILE          *fp;        /* Open file pointer */
  void          *bits;      /* Bitmap pixel bits */
  long          bitsize,    /* Size of bitmap */
            infosize;   /* Size of header information */
  BITMAPFILEHEADER  header;     /* File header */

 /*
  * Try opening the file; use "rb" mode to read this *binary* file.
  */

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

 /*
  * Read the file header and any following bitmap information...
  */

  if (fread(&header, sizeof(BITMAPFILEHEADER), 1, fp) < 1)
  {
   /*
    * Couldn't read the file header - return NULL...
    */

    fclose(fp);
    return (NULL);
  };

  if (header.bfType != 'MB')    /* Check for BM reversed... */
  {
   /*
    * Not a bitmap file - return NULL...
    */

    fclose(fp);
    return (NULL);
  };

  infosize = header.bfOffBits - sizeof(BITMAPFILEHEADER);
  if ((*info = (BITMAPINFO *)malloc(infosize)) == NULL)
  {
   /*
    * Couldn't allocate memory for bitmap info - return NULL...
    */

    fclose(fp);
    return (NULL);
  };

  if (fread(*info, 1, infosize, fp) < infosize)
  {
   /*
    * Couldn't read the bitmap header - return NULL...
    */

    free(*info);
    fclose(fp);
    return (NULL);
  };

 /*
  * Now that we have all the header info read in, allocate memory for the
  * bitmap and read *it* in...
  */

  if ((bitsize = (*info)->bmiHeader.biSizeImage) == 0)
    bitsize = ((*info)->bmiHeader.biWidth *
               (*info)->bmiHeader.biBitCount + 7) / 8 *
          abs((*info)->bmiHeader.biHeight);

  if ((bits = malloc(bitsize)) == NULL)
  {
   /*
    * Couldn't allocate memory - return NULL!
    */

    free(*info);
    fclose(fp);
    return (NULL);
  };

  if (fread(bits, 1, bitsize, fp) < bitsize)
  {
   /*
    * Couldn't read bitmap - free memory and return NULL!
    */

    free(*info);
    free(bits);
    fclose(fp);
    return (NULL);
  };

 /*
  * OK, everything went fine - return the allocated bitmap...
  */

  fclose(fp);
  return (bits);
}

/*
 * 'SaveDIBitmap()' - Save a bitmap to a DIB/BMP file on disk.
 *
 * Returns 0 if successful, non-zero otherwise...
 */

int
SaveDIBitmap(char       *filename,  /* I - File to save to */
         BITMAPINFO *info,      /* I - Bitmap information */
             void       *bits)      /* I - Bitmap pixel bits */
{
  FILE          *fp;        /* Open file pointer */
  long          size,       /* Size of file */
            infosize,   /* Size of bitmap info */
            bitsize;    /* Size of bitmap pixels */
  BITMAPFILEHEADER  header;     /* File header */

 /*
  * Try opening the file; use "wb" mode to write this *binary* file.
  */

  if ((fp = fopen(filename, "wb")) == NULL)
    return (-1);

  if (info->bmiHeader.biSizeImage == 0) /* Figure out the bitmap size */
    bitsize = (info->bmiHeader.biWidth *
               info->bmiHeader.biBitCount + 7) / 8 *
          abs(info->bmiHeader.biHeight);
  else
    bitsize = info->bmiHeader.biSizeImage;

  infosize = sizeof(BITMAPINFOHEADER);
  switch (info->bmiHeader.biCompression)
  {
    case BI_BITFIELDS :
        infosize += 12;         /* Add 3 RGB doubleword masks */
        if (info->bmiHeader.biClrUsed == 0)
      break;
    case BI_RGB :
        if (info->bmiHeader.biBitCount > 8 &&
            info->bmiHeader.biClrUsed == 0)
      break;
    case BI_RLE8 :
    case BI_RLE4 :
        if (info->bmiHeader.biClrUsed == 0)
          infosize += (1 << info->bmiHeader.biBitCount) * 4;
    else
          infosize += info->bmiHeader.biClrUsed * 4;
    break;
  };

  size = sizeof(BITMAPFILEHEADER) + infosize + bitsize;

 /*
  * Write the file header, bitmap information, and bitmap pixel data...
  */

  header.bfType      = 'BM';        /* Non-portable... sigh */
  header.bfSize      = size;
  header.bfReserved1 = 0;
  header.bfReserved2 = 0;
  header.bfOffBits   = sizeof(BITMAPFILEHEADER) + infosize;

  if (fwrite(&header, 1, sizeof(BITMAPFILEHEADER), fp) < sizeof(BITMAPFILEHEADER))
  {
   /*
    * Couldn't write the file header - return...
    */

    fclose(fp);
    return (-1);
  };

  if (fwrite(info, 1, infosize, fp) < infosize)
  {
   /*
    * Couldn't write the bitmap header - return...
    */

    fclose(fp);
    return (-1);
  };

  if (fwrite(bits, 1, bitsize, fp) < bitsize)
  {
   /*
    * Couldn't write the bitmap - return...
    */

    fclose(fp);
    return (-1);
  };

 /*
  * OK, everything went fine - return...
  */

  fclose(fp);
  return (0);
}

/*
 * 'ReadDIBitmap()' - Read the current OpenGL viewport into a
 *                    24-bit RGB bitmap.
 *
 * Returns the bitmap pixels if successful and NULL otherwise.
 */

void *
ReadDIBitmap(BITMAPINFO **info)     /* O - Bitmap information */
{
  long      i, j,           /* Looping var */
        bitsize,        /* Total size of bitmap */
        width;          /* Aligned width of a scanline */
  GLint     viewport[4];        /* Current viewport */
  void      *bits;          /* RGB bits */
  GLubyte   *rgb,           /* RGB looping var */
        temp;           /* Temporary var for swapping */

 /*
  * Grab the current viewport...
  */

  glGetIntegerv(GL_VIEWPORT, viewport);

 /*
  * Allocate memory for the header and bitmap...
  */

  if ((*info = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER))) == NULL)
  {
   /*
    * Couldn't allocate memory for bitmap info - return NULL...
    */

    return (NULL);
  };

  width   = viewport[2] * 3;        /* Real width of scanline */
  width   = (width + 3) & ~3;       /* Aligned to 4 bytes */
  bitsize = width * viewport[3];    /* Size of bitmap, aligned */

  if ((bits = calloc(bitsize, 1)) == NULL)
  {
   /*
    * Couldn't allocate memory for bitmap pixels - return NULL...
    */

    free(*info);
    return (NULL);
  };

 /*
  * Read pixels from the framebuffer...
  */

  glFinish();               /* Finish all OpenGL commands */
  glPixelStorei(GL_PACK_ALIGNMENT, 4);  /* Force 4-byte alignment */
  glPixelStorei(GL_PACK_ROW_LENGTH, 0);
  glPixelStorei(GL_PACK_SKIP_ROWS, 0);
  glPixelStorei(GL_PACK_SKIP_PIXELS, 0);

  glReadPixels(0, 0, viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE,
               bits);

 /*
  * Swap red and blue for the bitmap...
  */

  for (i = 0; i < viewport[3]; i ++)
    for (j = 0, rgb = ((GLubyte *)bits) + i * width;
         j < viewport[2];
     j ++, rgb += 3)
    {
      temp   = rgb[0];
      rgb[0] = rgb[2];
      rgb[2] = temp;
    };

 /*
  * Finally, initialize the bitmap header information...
  */

  (*info)->bmiHeader.biSize          = sizeof(BITMAPINFOHEADER);
  (*info)->bmiHeader.biWidth         = viewport[2];
  (*info)->bmiHeader.biHeight        = viewport[3];
  (*info)->bmiHeader.biPlanes        = 1;
  (*info)->bmiHeader.biBitCount      = 24;
  (*info)->bmiHeader.biCompression   = BI_RGB;
  (*info)->bmiHeader.biSizeImage     = bitsize;
  (*info)->bmiHeader.biXPelsPerMeter = 2952; /* 75 DPI */
  (*info)->bmiHeader.biYPelsPerMeter = 2952; /* 75 DPI */
  (*info)->bmiHeader.biClrUsed       = 0;
  (*info)->bmiHeader.biClrImportant  = 0;

  return (bits);
}

/*
 * 'PrintDIBitmap()' - Print a bitmap to a GDI printer.
 */

int
PrintDIBitmap(HWND       owner,     /* I - Owner/parent window */
              BITMAPINFO *info,     /* I - Bitmap information */
              void       *bits)     /* I - Bitmap pixel bits */
{
  PRINTDLG  pd;         /* Print dialog information */
  long      xsize,          /* Size of printed image */
        ysize,
        xoffset,        /* Offset from edges for image */
        yoffset;
  RECT      rect;           /* Page rectangle */
  DOCINFO   di;         /* Document info */
  HDC       hdc;            /* Device context for bitmap */
  HBITMAP   bitmap;         /* Bitmap image */
  HBRUSH    brush;          /* Background brush for page */
  HCURSOR   busy,           /* Busy cursor */
        oldcursor;      /* Old cursor */

 /*
  * Range check...
  */

  if (info == NULL || bits == NULL)
    return (0);

 /*
  * Initialize a PRINTDLG structure before displaying a standard Windows
  * print dialog...
  */

  memset(&pd, 0, sizeof(pd));
  pd.lStructSize = sizeof(pd);
  pd.hwndOwner   = owner;
  pd.Flags       = PD_RETURNDC;
  pd.hInstance   = NULL;
  if (!PrintDlg(&pd))
    return (0);     /* User chose 'cancel'... */

 /*
  * OK, user wants to print, so set the cursor to 'busy' and start the
  * print job...
  */

  busy      = LoadCursor(NULL, IDC_WAIT);
  oldcursor = SetCursor(busy);

  SetMapMode(pd.hDC, MM_TEXT);
  di.cbSize      = sizeof(DOCINFO);
  di.lpszDocName = "OpenGL Image";
  di.lpszOutput  = NULL;

  StartDoc(pd.hDC, &di);
  StartPage(pd.hDC);

 /*
  * Clear the background to white...
  */

  rect.top    = 0;
  rect.left   = 0;
  rect.right  = GetDeviceCaps(pd.hDC, HORZRES);
  rect.bottom = GetDeviceCaps(pd.hDC, VERTRES);
  brush       = CreateSolidBrush(0x00ffffff);
  FillRect(pd.hDC, &rect, brush);

 /*
  * Stretch the bitmap to fit the page...
  */

  hdc    = CreateCompatibleDC(pd.hDC);
  bitmap = CreateDIBitmap(hdc, &(info->bmiHeader), CBM_INIT, bits, info,
                          DIB_RGB_COLORS);
  SelectObject(hdc, bitmap);

  xsize = rect.right;
  ysize = xsize * info->bmiHeader.biHeight / info->bmiHeader.biWidth;
  if (ysize > rect.bottom)
  {
    ysize = rect.bottom;
    xsize = ysize * info->bmiHeader.biWidth / info->bmiHeader.biHeight;
  };

  xoffset = (rect.right - xsize) / 2;
  yoffset = (rect.bottom - ysize) / 2;

  StretchBlt(pd.hDC, xoffset, yoffset, xsize, ysize,
             hdc, 0, 0, info->bmiHeader.biWidth, info->bmiHeader.biHeight,
             SRCCOPY);

 /*
  * That's it.  End the print job and free anything we allocated...
  */

  EndPage(pd.hDC);
  EndDoc(pd.hDC);
  DeleteDC(pd.hDC);

  DeleteObject(bitmap);
  DeleteObject(brush);
  DeleteObject(busy);
  DeleteDC(hdc);

 /*
  * Restore the cursor and return...
  */

  SetCursor(oldcursor);

  return (1);
}

/*
 * 'ConvertRGB()' - Convert a DIB/BMP image to 24-bit RGB pixels.
 *
 * Returns an RGB pixel array if successful and NULL otherwise.
 */

GLubyte *
ConvertRGB(BITMAPINFO *info,        /* I - Original bitmap information */
           void       *bits)        /* I - Original bitmap pixels */
{
  int       i, j,           /* Looping vars */
        bitsize,        /* Total size of bitmap */
        width;          /* Aligned width of bitmap */
  GLubyte   *newbits;       /* New RGB bits */
  GLubyte   *from, *to,     /* RGB looping vars */
        temp;           /* Temporary var for swapping */

 /*
  * Copy the original bitmap to the new array, converting as necessary.
  */

  switch (info->bmiHeader.biCompression)
  {
    case BI_RGB :
        if (info->bmiHeader.biBitCount == 24)
    {
          width   = 3 * info->bmiHeader.biWidth;
          width   = (width + 3) & ~3;
          bitsize = width * info->bmiHeader.biHeight;
          if ((newbits = (GLubyte *)calloc(bitsize, 1)) == NULL)
            return (NULL);
         /*
          * Swap red & blue in a 24-bit image...
          */

          for (i = 0; i < info->bmiHeader.biHeight; i ++)
        for (j = 0, from = ((GLubyte *)bits) + i * width,
                 to = newbits + i * width;
         j < info->bmiHeader.biWidth;
         j ++, from += 3, to += 3)
            {
              to[0] = from[2];
              to[1] = from[1];
              to[2] = from[0];
            };
    };
        if (info->bmiHeader.biBitCount == 32)
    {
          width   = 4 * info->bmiHeader.biWidth;
          bitsize = width * info->bmiHeader.biHeight;
          if ((newbits = (GLubyte *)calloc(bitsize, 1)) == NULL)
            return (NULL);

         /*
          * Swap red & blue in a 32-bit image...
          */

          for (i = 0; i < info->bmiHeader.biHeight; i ++)
        for (j = 0, from = ((GLubyte *)bits) + i * width,
                 to = newbits + i * width;
         j < info->bmiHeader.biWidth;
         j ++, from += 4, to += 4)
            {
              to[0] = from[2];
              to[1] = from[1];
              to[2] = from[0];
              to[3] = from[3];
            };
    };
    break;
    case BI_RLE4 :
    case BI_RLE8 :
    case BI_BITFIELDS :
        break;
  };

  return (newbits);
}

/*
 * End of "$Id: bitmap.c,v 1.2 1996/01/09 22:52:53 mike Exp mike $".
 */
0

A jakie jest pytanie?

0

Wszystko działa. Kompilator nie pokazuje żadnych błędów, a mimo to widać jedynie kulę bez tekstury. Dlaczego?

 #include <windows.h>
#include "gl.h"
#include <GL/glut.h>
#include <GL/glu.h>
#include "bitmap.cpp"

int sw,sh;
GLfloat spin = 0, distance = 2;
GLuint NazwyTekstur[1];

bool LoadBMPTexture(char * FileName)
{
   GLvoid * obrazek,* zlyobrazek;
   BITMAPINFO * infoBitmapy;

   zlyobrazek = LoadDIBitmap(FileName, &infoBitmapy);
   if(zlyobrazek == NULL)
   {
    return false;//nie udalo sie
   }
   obrazek = ConvertRGB(infoBitmapy, zlyobrazek);
   free(zlyobrazek);
   if(obrazek == NULL)
   {
    free(infoBitmapy);
    return false;//nie udalo sie
   }

   glTexImage2D(GL_TEXTURE_2D,
                0, // level
                GL_RGBA, // internalFormat
                infoBitmapy->bmiHeader.biWidth,
                infoBitmapy->bmiHeader.biHeight,
                0, // border
                GL_RGBA, // format
                GL_UNSIGNED_BYTE, // type
                obrazek);
   free(obrazek);
   free(infoBitmapy);
   return true;
}

void initTextures()
{
    glGenTextures(1, NazwyTekstur); //1 - ilosc "nazw" do zarezerwowania

   glBindTexture(GL_TEXTURE_2D, NazwyTekstur[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_LINEAR);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
   LoadBMPTexture("earth2alfa.bmp");

   glEnable(GL_TEXTURE_2D);
}

void init(void)
{
   glEnable(GL_DEPTH_TEST);
   glPixelStorei(GL_UNPACK_ALIGNMENT, 4);   /* Force 4-byte alignment */

   initTextures();

   glEnable(GL_TEXTURE_2D);
   glEnable(GL_BLEND);
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   glEnable(GL_LIGHTING);
   glEnable(GL_LIGHT0);
   GLfloat lp[] = {3, 0, 0, 1};
   glLightfv(GL_LIGHT0, GL_POSITION, lp);
}

void display(void)
{
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   glLoadIdentity();

   glTranslatef(0.0, 0.0, -distance);

   glRotatef(spin, 0, 0.5, 0);

   glBindTexture(GL_TEXTURE_2D, NazwyTekstur[0]);

   glRotatef(-90, 1, 0, 0);
   GLUquadricObj * obj = gluNewQuadric();
   gluQuadricTexture(obj, GL_TRUE);
   gluSphere(obj, 1, 30, 30);
   gluDeleteQuadric(obj);

   glBindTexture(GL_TEXTURE_2D, NazwyTekstur[0]);
   glutSwapBuffers();
}

void reshape(int w, int h)
{
    sw = w; sh = h;
   glViewport (0, 0, (GLsizei) w, (GLsizei) h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluPerspective(60.0, (GLfloat)w/h, 0.1, 100);
   glMatrixMode(GL_MODELVIEW);
}

void keyboard(unsigned char key, int x, int y)
{
   switch (key) {
      case 27:
         exit(0);
   }
}

void idle()
{
   spin += 1;
   if (spin > 360.0f) spin -= 360.0f;
   if (GetKeyState(VK_DOWN) & 0x80000000) distance += 0.1;
   if (GetKeyState(VK_UP) & 0x80000000) distance -= 0.1;
   glutPostRedisplay();
   //Sleep(10);
}

int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
   glutInitWindowSize(500, 300);
   glutInitWindowPosition (100, 100);
   glutCreateWindow(argv[0]);
   init();

   glutReshapeFunc(reshape);
   glutKeyboardFunc(keyboard);
   glutDisplayFunc(display);
   glutIdleFunc(idle);
   glutMainLoop();
   return 0;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0