Problem with loading a texture in openGL

Started by
4 comments, last by krootushas 13 years, 7 months ago
Hi!
Im trying to load a texture into an OpenGL scene.. The compiler doesn't give me any errors.. But when the program starts up I end up with windows error handler(Tells me to send a error report or ignore it).. However I use the default OpenGL code generated by CB.. Then I made some research about loading a texture into OpenGL without using SDL or something like that..I found this tutorial very helpful: http://www.nullterminator.net/gltexture.html .
Hope you can give me some advice on how to fix this..
Here is my code:
#include <windows.h>#include <gl/gl.h>#include <stdio.h>#include <stdlib.h>LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);void EnableOpenGL(HWND hwnd, HDC*, HGLRC*);void DisableOpenGL(HWND, HDC, HGLRC);GLuint LoadTextureBMP(const char * filename,int wrap){GLuint texture;int width,height;BYTE * data;FILE * file;file = fopen(filename,"rb");if(file == NULL) return 0;width = 256;height = 256;data = malloc(width * height * 3);fread(data,width*height*3,1,file);fclose(file);glGenTextures(1,&texture);glBindTexture(GL_TEXTURE_2D,texture);glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,wrap ? GL_REPEAT : GL_CLAMP);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,wrap ? GL_REPEAT : GL_CLAMP);glTexImage2D(GL_TEXTURE_2D,0,3,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,data);free(data);return texture;}int WINAPI WinMain(HINSTANCE hInstance,                   HINSTANCE hPrevInstance,                   LPSTR lpCmdLine,                   int nCmdShow){    WNDCLASSEX wcex;    HWND hwnd;    HDC hDC;    HGLRC hRC;    MSG msg;    BOOL bQuit = FALSE;    float theta = 0.0f;    GLuint texture;    /* register window class */    wcex.cbSize = sizeof(WNDCLASSEX);    wcex.style = CS_OWNDC;    wcex.lpfnWndProc = WindowProc;    wcex.cbClsExtra = 0;    wcex.cbWndExtra = 0;    wcex.hInstance = hInstance;    wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);    wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);    wcex.lpszMenuName = NULL;    wcex.lpszClassName = "GLSample";    wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);;    if (!RegisterClassEx(&wcex))        return 0;    /* create main window */    hwnd = CreateWindowEx(0,                          "GLSample",                          "OpenGL Sample",                          WS_OVERLAPPEDWINDOW,                          CW_USEDEFAULT,                          CW_USEDEFAULT,                          256,                          256,                          NULL,                          NULL,                          hInstance,                          NULL);    ShowWindow(hwnd, nCmdShow);    /* enable OpenGL for the window */    EnableOpenGL(hwnd, &hDC, &hRC);    /* Enable Texture */    LoadTextureBMP("texture.bmp",TRUE);    /* program main loop */    while (!bQuit)    {        /* check for messages */        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))        {            /* handle or dispatch messages */            if (msg.message == WM_QUIT)            {                bQuit = TRUE;            }            else            {                TranslateMessage(&msg);                DispatchMessage(&msg);            }        }        else        {            /* OpenGL animation code goes here */            glClearColor(0.0f, 0.0f, 0.0f, 0.0f);            glClear(GL_COLOR_BUFFER_BIT);            glEnable(GL_TEXTURE_2D);            glBindTexture(GL_TEXTURE_2D,texture);            glPushMatrix();            glRotatef(theta, 0.0f, 0.0f, 1.0f);        glTexCoord2d(0.0,0.0); glVertex2d(-1.0,-1.0);        glTexCoord2d(1.0,0.0); glVertex2d(+1.0,-1.0);        glTexCoord2d(1.0,1.0); glVertex2d(+1.0,+1.0);        glTexCoord2d(0.0,1.0); glVertex2d(-1.0,+1.0);        glEnd();        glPopMatrix();            glPopMatrix();            SwapBuffers(hDC);            theta += 1.0f;            Sleep (1);        }    }    /* shutdown OpenGL */    DisableOpenGL(hwnd, hDC, hRC);    /* destroy the window explicitly */    DestroyWindow(hwnd);    return msg.wParam;}LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){    switch (uMsg)    {        case WM_CLOSE:            PostQuitMessage(0);        break;        case WM_DESTROY:            return 0;        case WM_KEYDOWN:        {            switch (wParam)            {                case VK_ESCAPE:                    PostQuitMessage(0);                break;            }        }        break;        default:            return DefWindowProc(hwnd, uMsg, wParam, lParam);    }    return 0;}void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC){    PIXELFORMATDESCRIPTOR pfd;    int iFormat;    /* get the device context (DC) */    *hDC = GetDC(hwnd);    /* set the pixel format for the DC */    ZeroMemory(&pfd, sizeof(pfd));    pfd.nSize = sizeof(pfd);    pfd.nVersion = 1;    pfd.dwFlags = PFD_DRAW_TO_WINDOW |                  PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;    pfd.iPixelType = PFD_TYPE_RGBA;    pfd.cColorBits = 24;    pfd.cDepthBits = 16;    pfd.iLayerType = PFD_MAIN_PLANE;    iFormat = ChoosePixelFormat(*hDC, &pfd);    SetPixelFormat(*hDC, iFormat, &pfd);    /* create and enable the render context (RC) */    *hRC = wglCreateContext(*hDC);    wglMakeCurrent(*hDC, *hRC);}void DisableOpenGL (HWND hwnd, HDC hDC, HGLRC hRC){    wglMakeCurrent(NULL, NULL);    wglDeleteContext(hRC);    ReleaseDC(hwnd, hDC);}

-Xrid3r

Edit: Move this thread to the OpenGL topic..
Advertisement
Your data is RGB (3 bytes per pixel), but you tell OpenGL to use the data as GL_RGBA, which is 4 bytes per pixel. Try using GL_RGB.

EDIT: (In addition, I guess you mean to use texture = LoadTextureBMP, as in the code you posted the texture variable is never assigned in WinMain).
Quote:Original post by Erik Rufelt
Your data is RGB (3 bytes per pixel), but you tell OpenGL to use the data as GL_RGBA, which is 4 bytes per pixel. Try using GL_RGB.


Thanks! that did work.. Now there's another problem.. You see.. Now I've got a black window that doesn't display my texture at all.. Any advice on this? Do I need to declare a normal for the surface?

Edit: Yes, That's true.. But I still got this black window to deal with..
You need to add a glBegin(GL_QUADS) after your call to glRotatef. You never tell OpenGL that you begin drawing, so the glVertex2d are ignored.
Quote:Original post by Erik Rufelt
You need to add a glBegin(GL_QUADS) after your call to glRotatef. You never tell OpenGL that you begin drawing, so the glVertex2d are ignored.


Hehe, I saw it just before I read your last replay!
Thanks man it all worked out now.. And thanks for the fast replay!
Hi. Can someone tell where i do mistake?
I wrote the bmp class. And added bmp loader in class constructor.
it should look like this http://3.ly/myqt but mine look this http://3.ly/ZdNZ









//----------bitmap.h-------------------------------------------------------------






#include <string>
#include <string.h>
using namespace std;


class BMP
{
public:

BMP(string filess);
~BMP();
string filename;
unsigned short int type; //2 /* Magic identifier */
unsigned int size; //4 /* File size in bytes */
unsigned short int reserved1; //2
unsigned short int reserved2; //2
unsigned int offset; //4
unsigned int header_size; //4 /* Header size in bytes */
int width; //4
int height; //4 /* Width and height of image */
unsigned short int planes; //2 /* Number of colour planes */
unsigned short int bits; //2 /* Bits per pixel */
unsigned int compression; //4 /* Compression type */
unsigned int imagesize; //4 /* Image size in bytes */
int xresolution; //4
int yresolution; //4 /* Pixels per meter */
unsigned int ncolours; //4 /* Number of colours */
unsigned int importantcolours;//4 /* Important colours */



long filesize;
char c_array[53];
int BMP::chartoI(char i1, char i2, char i3,char i4);
unsigned int BMP::chartoUI(char i1, char i2, char i3,char i4);
unsigned short int BMP::chartoUSI (char i1,char i2);
char * buffer;
};



//--------------bitmap.cpp-------------------------------------------------------



#include "bitmap.h"
#include <fstream>
#include <string>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
using namespace std;




int BMP::chartoI(char i1, char i2, char i3,char i4)
{
return (int)(((unsigned char)i4 << 24) |
((unsigned char)i3 << 16) |
((unsigned char)i2 << 8) |
(unsigned char)i1);

}



unsigned int BMP::chartoUI(char i1, char i2, char i3,char i4)
{
return (unsigned int)(((unsigned char)i4 << 24) |
((unsigned char)i3 << 16) |
((unsigned char)i2 << 8) |
(unsigned char)i1);
}




unsigned short int BMP::chartoUSI (char i1,char i2)
{
return (unsigned short int)(((unsigned char)i2 << 8) |
(unsigned char)i1);
}



BMP::BMP(string filename)
{
BMP::filename = filename;
FILE * pfile;

filesize = 0;
pfile = fopen(filename.c_str(),"rb");
rewind (pfile);

// get file size

fseek(pfile,filesize,SEEK_END);
filesize = ftell(pfile);
rewind(pfile);

//create buffer for bmp body

buffer = (char*) malloc( filesize-((sizeof(char))*54));

// reading bmp header

fread(c_array,1,54,pfile);

//reading body

fread (buffer,1,(filesize),pfile);
fclose(pfile);

// i made this to test are loader works. Its just create new file
// and write header bufer to it, and then boddy.

FILE * files;
files = fopen("BMP_COPY_LOG.bmp","wb");
fwrite(c_array,1,54,files);
fwrite(buffer,1,(filesize),files);
fclose(files);



type = chartoUSI(c_array[0] ,c_array[1]);//2 /* Magic identifier*/
size = chartoUI(c_array[2] ,c_array[3],c_array[4] ,c_array[5]);//4 /* File size in bytes*/
reserved1 = chartoUSI(c_array[6] ,c_array[7]);//2reserved2 = chartoUSI (c_array[8] ,c_array[9]);//2
offset = chartoUI(c_array[10],c_array[11] ,c_array[12],c_array[13]);//4
header_size = chartoUI(c_array[14],c_array[15] ,c_array[16],c_array[17]);//4 /* Header size in bytes */
width = chartoIc_array[18],c_array[19] ,c_array[20],c_array[21]);//4
height = chartoI(c_array[22],c_array[23] ,c_array[24],c_array[25]);//4 /* Width and height of image */
planes = chartoUSI (c_array[26],c_array[27]);//2 /* Number of colour planes */
bits = chartoUSI (c_array[28],c_array[29]);//2 /* Bits per pixel*/
compression = chartoUI(c_array[30],c_array[31] ,c_array[32],c_array[33]);//4 /* Compression type */
imagesize = chartoUI(c_array[34],c_array[35] ,c_array[36],c_array[37]);//4 /* Image size in bytes */
xresolution = chartoI(c_array[38],c_array[39] ,c_array[40],c_array[41]);//4
yresolution = chartoI(c_array[42],c_array[43] ,c_array[44],c_array[45]);//4 /* Pixels per meter */
ncolours = chartoUI(c_array[46],c_array[47] ,c_array[48],c_array[49]);//4 /* Number of colours */
importantcolours = chartoUI (c_array[50],c_array[51] ,c_array[52],c_array[53]);//4 /* Important colours */


}

BMP::~BMP()
{
free(buffer);
delete [] c_array;
}



//---------------------------main------------------------------------------------

#include <iostream>
#include <stdlib.h>
#include "poligonas.h"
#include "mdl.h"
#include "bitmap.h"



#include <glut.h>

modelis mdl("untitled.x");
BMP bmp("lol.bmp");




using namespace std;


GLuint loadTexture() {
GLuint textureId;
glGenTextures(1, &textureId); //Make room for our texture
glBindTexture(GL_TEXTURE_2D, textureId); //Tell OpenGL which texture to edit
//Map the image to the texture
glTexImage2D(GL_TEXTURE_2D, //Always GL_TEXTURE_2D
0, //0 for now
GL_RGB, //Format OpenGL uses for image
bmp.width, bmp.height, //Width and height
0, //The border of the image
GL_RGB, //GL_RGB, because pixels are stored in RGB format
GL_UNSIGNED_BYTE, //GL_UNSIGNED_BYTE, because pixels are stored
//as unsigned numbers
bmp.buffer); //The actual pixel data
//Returns the id of the texture

return textureId;
}


GLuint _textureId = loadTexture();

//Called when a key is pressed
void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: //Escape key
exit(0);
}
}

//Initializes 3D rendering
void initRendering() {
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL); //Enable color
glClearColor(0.7f, 0.9f, 1.0f, 1.0f); //Change the background to sky blue
}

//Called when the window is resized
void handleResize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (double)w / (double)h, 1.0, 200.0);
}

float _angle = 30.0f;
float _cameraAngle = 0.0f;


//Draws the 3D scene
void drawScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glTranslatef(0.0f, 1.0f, -6.0f);

GLfloat ambientLight[] = {0.2f, 0.2f, 0.2f, 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);

GLfloat directedLight[] = {0.7f, 0.7f, 0.7f, 1.0f};
GLfloat directedLightPos[] = {-10.0f, 15.0f, 20.0f, 0.0f};
glLightfv(GL_LIGHT0, GL_DIFFUSE, directedLight);
glLightfv(GL_LIGHT0, GL_POSITION, directedLightPos);

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _textureId);

//Bottom
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glColor3f(1.0f, 0.2f, 0.2f);
glBegin(GL_QUADS);

glNormal3f(0.0, 1.0f, 0.0f); glTexCoord2f(0.0f, 0.0f);
glVertex3f(-2.5f, -2.5f, 2.5f); glTexCoord2f(0.0f, 1.0f);
glVertex3f(2.5f, -2.5f, 2.5f); glTexCoord2f(1.0f, 1.0f);
glVertex3f(2.5f, -2.5f, -2.5f); glTexCoord2f(1.0f, 0.0f);
glVertex3f(-2.5f, -2.5f, -2.5f);

glEnd();

//Back
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_TRIANGLES);

glNormal3f(0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-2.5f, -2.5f, -2.5f);
glTexCoord2f(5.0f, 5.0f);
glVertex3f(0.0f, 2.5f, -2.5f);
glTexCoord2f(10.0f, 0.0f);
glVertex3f(2.5f, -2.5f, -2.5f);

glEnd();

//Left
glDisable(GL_TEXTURE_2D);
glColor3f(1.0f, 0.7f, 0.3f);
glBegin(GL_QUADS);

glNormal3f(1.0f, 0.0f, 0.0f);
glVertex3f(-2.5f, -2.5f, 2.5f);
glVertex3f(-2.5f, -2.5f, -2.5f);
glVertex3f(-2.5f, 2.5f, -2.5f);
glVertex3f(-2.5f, 2.5f, 2.5f);

glEnd();

glutSwapBuffers();
}

void update(int value) {
_angle += 2.0f;
if (_angle > 360) {
_angle -= 360;
}

glutPostRedisplay();
glutTimerFunc(25, update, 0);
}

int main(int argc, char** argv) {
//Initialize GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 400);

//Create the window
glutCreateWindow("lol");
initRendering();

//Set handler functions
glutDisplayFunc(drawScene);
glutKeyboardFunc(handleKeypress);
glutReshapeFunc(handleResize);

glutTimerFunc(25, update, 0); //Add a timer

glutMainLoop();
system("pause");
return 0;



// The main body is from videotutorialsrock.com
// You should take a look at this function GLuint "loadTexture()" becouse
// the loader works fine (i think so :) ).
}

This topic is closed to new replies.

Advertisement