Jump to content
  • Advertisement
Sign in to follow this  
nick2price

OpenGL Program crashes for some reason

This topic is 3527 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have created a program which uses texture mapping (A topic which has killed me! as all examples use depreciated libraries) This is my program
#include "stdafx.h"

#include "glut.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <windows.h>

int LoadBitmap(char *filename) 
{    int num_texture=-1; //Counter to keep track of the last loaded texture
    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
}

void drawCube(void) 

{ 
    glEnable(GL_DEPTH_TEST); // We enable the depth test (also called z buffer)
    glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); // Polygon rasterization mode (polygon filled)
    
    glEnable(GL_TEXTURE_2D); // This Enable the Texture mapping
    float fSize = .35;
    GLuint tList[1];
    
    
    glGenTextures(1, tList);

    tList[1] = LoadBitmap("texture1.bmp"); 
    
glBegin(GL_QUADS);
		// Front Face
		glNormal3f( 0.0f, 0.0f, 0.5f);					
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
		glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
		// Back Face
		glNormal3f( 0.0f, 0.0f,-0.5f);					
		glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
		glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
		// Top Face
		glNormal3f( 0.0f, 0.5f, 0.0f);					
		glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
		glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
		// Bottom Face
		glNormal3f( 0.0f,-0.5f, 0.0f);					
		glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
		glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
		glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
		// Right Face
		glNormal3f( 0.5f, 0.0f, 0.0f);					
		glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
		glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
		// Left Face
		glNormal3f(-0.5f, 0.0f, 0.0f);					
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
		glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
	glEnd();




}

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

   glutDisplayFunc(drawCube); 
  

   glutMainLoop();
   return 0;
}

When i compile and run the program, i get a pop up saying Run-Time Check Failure #2 - Stack around the variable 'tList' was corrupted. > Coursework.exe!drawCube() Line 128 + 0xf bytes C++ What would be causing this error? cheers [Edited by - nick2price on November 16, 2008 6:14:57 PM]

Share this post


Link to post
Share on other sites
Advertisement
Use [source][/source] tags for large amounts of code. You can edit your post and add them now.

You are using an array incorrectly. In C and C++, arrays are 0 indexed. So the valid indices are 0..N, where N is the size of the array.

// ...
GLuint tList[1];

glGenTextures(1, tList);

tList[1] = LoadBitmap("texture1.bmp");
// ...


Here you have an array of size 1. The first (and only) element is at index 0.

Also, you request a texture id from OpenGL, then ignore it by overwriting it. Instead, see if you can pass the texture handle to the LoadBitmap() function.

Share this post


Link to post
Share on other sites
Because then i am only uing one texture at the moment, i changed it a bit so that it doesnt use an array.

GLuint tList;


glGenTextures(1, &tList);

tList = LoadBitmap("texture1.bmp");



I dont know if this is ok?
I am also unsure as to what u mean when u say i am overriding the texture id and to instead try passing the texture handle to my LoadBitmap method. I am tottally new to c++ and glut, so my questions are problably really silly sounding. I have tried for ages to learn texture mapping, but so many tutorials seem old and are using discontinued libraries. So any help would be so greatful
cheers

Share this post


Link to post
Share on other sites
Yes, you can do this:

GLuint tList;
glGenTextures(1, &tList);



Think about what it means to call glGenTextures(). It means "Hey, OpenGL. Could you hand me a shiny new texture handle (or set of handles) that no one else is using please?".

So now you have a shiny new texture handle in "tList". Except what do you do next, you totally ignore that value by writing over it with the return value of LoadBitmap().

Where does the texture handle in LoadBitmap come from? An arbitrary value in the function - its not guarenteed to be unused (in fact, looking at the code I think it always uses texture id 0 - that is bad).

We can change LoadBitmap() to accept a GLuint that tells it which texture to store the data in:

bool LoadBitmap(const char *filename, int texture)
{
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;


if( (l_file = fopen(filename, "rb"))==NULL) return false; // 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, texture);

// 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 true;
}


Of course, if you were using C++ we could clean up the function even more. It isn't clear what language you are using - C or C++?

Either way, we can now call the function like so:

GLuint texture;
glGenTextures(1, &texture);
LoadBitmap("texture1.bmp",texture);


You should note that loading a texture from disk every time you draw the cube isn't a great idea. It would be far better to load the texture at start up, and store the texture id somewhere. Then, every time you go do draw the cube you can just use the pre-loaded texture.

Share this post


Link to post
Share on other sites
I am using C++ for this, visual c++. When i get everything working, i will (attempt to) seperate things into different classes, and i will make sure i load it up at startup (makes sense). I have changed it so it is more like the way you have shown, it is not liking the for loop in the LoadBitmap method now though. A lot of errors pointing to this. Is this the way you would do texture mapping? I have tried doing it from putting a few examples together, so i am not even sure if i am doing it a very good way.

[Edited by - nick2price on November 17, 2008 5:03:26 AM]

Share this post


Link to post
Share on other sites
I don't know why - if you don't post the exact code or the error messages [smile] Copy and paste is your friend here.

Here is a complete example I threw together. I removed your drawing code - you'll have to put it back in. On my system, I can see a textured teapot. There probably should be more error checking in LoadBitmap().

#include "windows.h"
#include "gl/gl.h"
#include "glut.h"

#include <vector>
#include <string>
#include <fstream>

bool LoadBitmap(const std::string &filename, int texture)
{
std::ifstream file(filename.c_str(),std::ios::binary);

if(!file)
{
return false;
}

BITMAPFILEHEADER fileheader;
BITMAPINFOHEADER infoheader;

file.read(reinterpret_cast<char *>(&fileheader), sizeof(fileheader));
file.read(reinterpret_cast<char *>(&infoheader), sizeof(infoheader));

std::vector<byte> texturedata;
unsigned amount = infoheader.biWidth * infoheader.biHeight;
texturedata.reserve(amount * 4);

for(unsigned i = 0; i < amount; i++)
{
RGBTRIPLE rgb = {255,255,255};

file.read(reinterpret_cast<char *>(&rgb), sizeof(rgb));
texturedata.push_back(rgb.rgbtRed);
texturedata.push_back(rgb.rgbtGreen);
texturedata.push_back(rgb.rgbtBlue);
texturedata.push_back(255);
}

glBindTexture(GL_TEXTURE_2D, texture);


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_NEAREST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

void *raw = &texturedata.front();
glTexImage2D(GL_TEXTURE_2D, 0, 4, infoheader.biWidth, infoheader.biHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, raw);
gluBuild2DMipmaps(GL_TEXTURE_2D, 4, infoheader.biWidth, infoheader.biHeight, GL_RGBA, GL_UNSIGNED_BYTE, raw);

return true;
}

GLuint texture = 0;

void draw()
{
glClear(GL_COLOR_BUFFER_BIT);

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,texture);


glutSolidTeapot(0.5);
}

int win;

void keyboard(unsigned char key, int x, int y)
{
if(key == 'q')
{
glutDestroyWindow(win);
exit(0);
}
}

int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);
glutInitWindowSize(800,400);
glutInitWindowPosition(100,100);

win = glutCreateWindow("Hello");

glutDisplayFunc(draw);
glutKeyboardFunc(keyboard);

glClearColor(0,0,0,0);

glGenTextures(1, &texture);

bool b = LoadBitmap("texture1.bmp",texture);

if(!b)
{
MessageBox(NULL,L"failed to load bitmap",L"Hello",MB_OK);
return 1;
}

glutMainLoop();
}


Share this post


Link to post
Share on other sites
Thats kool, can i just ask a question though. Somthing is happening which was happening to me in another program where i tried doing texture mapping. At first, i didnt have an image in my folder and i got returned the error prompt. So i put an .bmp image in my folder, size 64*64, and when i run the program, i get a window with nothing in the middle. So basically i just get a frame with a hole in the middle, if u get what i mean (tottally seethrough). Why would this be happening?

Share this post


Link to post
Share on other sites
Yes, I got a blank screen a couple of times too. I don't know why this happens. I don't really use GLUT so it could be some aspect of it that I am not familiar with. Look for some samples online (that is what I did when typing up that [grin]) and see how they work.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!