2

我有一个代码应该渲染两个球体,每个球体都有不同的纹理,但它不起作用,即使构建成功。它说:变量'textureId'周围的堆栈已损坏。原始代码(仅适用于一个纹理和一个球体)在这里。http://www.dreamincode.net/forums/topic/253361-texture-mapping-and-glutsolidsphere/

编码 :

#include <iostream>
#include <fstream>
#include <stdlib.h> 
#include <cmath>
#include <GL/glut.h>
using namespace std;

const float SIZE = 10.0f;
#define M_PI    (3.14159265)
GLUquadricObj *sphere = NULL;
GLUquadricObj *sphere2 = NULL;

float _angle = 0;
GLuint _textureId[2];

namespace {
//Converts a four-character array to an integer, using little-endian form
int toInt(const char* bytes) {
    return (int)(((unsigned char)bytes[3] << 24) |
        ((unsigned char)bytes[2] << 16) |
        ((unsigned char)bytes[1] << 8) |
        (unsigned char)bytes[0]);
}

//Reads the next four bytes as an integer, using little-endian form
int readInt(ifstream &input) {
    char buffer[4];
    input.read(buffer, 4);
    return toInt(buffer);
}
}


class Image {
public:
    Image(char* ps, int w, int h);
    ~Image();

    /* An array of the form (R1, G1, B1, R2, G2, B2, ...) indicating the
     * color of each pixel in image.  Color components range from 0 to 255.
     * The array starts the bottom-left pixel, then moves right to the end
     * of the row, then moves up to the next column, and so on.  This is the
     * format in which OpenGL likes images.
     */
    char* pixels;
    int width;
    int height;
};

Image::Image(char* ps, int w, int h) : pixels(ps), width(w), height(h) {



}
Image::~Image() {



}

Image* loadBMP(const char* filename);

Image* loadBMP(const char* filename) {
ifstream infile(filename, ifstream::binary);
infile.seekg(10, std::ios::cur);
int dataOffset = readInt(infile);

//Read the header
int headerSize = readInt(infile);
int width = readInt(infile);
int height = readInt(infile);

//Read the data
int bytesPerRow = ((width * 3 + 3) / 4) * 4 - (width * 3 % 4);
int size = bytesPerRow * height;
char* pixels = new char[size];
infile.seekg(dataOffset, ios_base::beg);
infile.read(pixels, size);
infile.close();
//Get the data into the right format
char* pixels2 = new char[width * height * 3];
for(int y = 0; y < height; y++) {
    for(int x = 0; x < width; x++) {
        for(int c = 0; c < 3; c++) {
            pixels2[3*(width*y + x) + c] = pixels[bytesPerRow*y + 3*x (2 - c)];
        }
    }
}
delete[] pixels;
return new Image(pixels2, width, height);
}

GLuint loadTextureFromImage(Image* image) {
GLuint textureId;
glGenTextures(2, &textureId); //Make room for our texture
//glBindTexture(GL_TEXTURE_2D, textureId);

//Map the image to the texture
glTexImage2D(GL_TEXTURE_2D, 
    0,
    GL_RGB,
    image->width, image->height,
    0,
    GL_RGB,
    GL_UNSIGNED_BYTE,
    image->pixels);
return textureId;
}



void initRendering() {
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glShadeModel(GL_SMOOTH);
glEnable(GL_COLOR_MATERIAL);
glDisable(GL_CULL_FACE);
glEnable(GL_TEXTURE_2D);


Image* img = loadBMP("earth.bmp");
_textureId[1] = loadTextureFromImage(img);
delete img;

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

sphere = gluNewQuadric();
gluQuadricDrawStyle(sphere, GLU_FILL);
gluQuadricTexture(sphere, GL_TRUE);
gluQuadricNormals(sphere, GLU_SMOOTH);

Image* image = loadBMP("sky.bmp");
_textureId[2] = loadTextureFromImage(image);
delete image;

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

sphere2 = gluNewQuadric();
gluQuadricDrawStyle(sphere2, GLU_FILL);
gluQuadricTexture(sphere2, GL_TRUE);
gluQuadricNormals(sphere2, GLU_SMOOTH);
}

void handleResize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (float)w / (float)h, 1.0, 200.0);
}

void drawScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glBindTexture(GL_TEXTURE_2D, _textureId[1]);

glTranslatef(0.0f, 0.0f, -20.0f);
glRotatef(_angle, 0, 1, 0);

gluSphere(sphere, 5.0, 20, 20);


glBindTexture(GL_TEXTURE_2D, _textureId[2]);

glTranslatef(0.0f, 0.0f, -30.0f);
glRotatef(_angle, 0, 1, 0);

gluSphere(sphere, 5.0, 20, 20);


glutSwapBuffers();
}

//Called every 25 milliseconds
void update(int value) {
_angle += 1.5f;
if (_angle > 360) {
    _angle -= 360;
}

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

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

glutCreateWindow("Sphery sky");
initRendering();

glutDisplayFunc(drawScene);
glutReshapeFunc(handleResize);
glutTimerFunc(25, update, 0);

glutMainLoop();
return 0;
}
4

1 回答 1

1

glGenTextures 不绑定纹理。您必须在使用 glTexImage2D 之前绑定纹理。另请注意,您的 glGenTextures 调用确实分配了 2 个纹理名称,但您只为一个名称提供空间。loadTextureFromImage 的语义表明 glGenTextures 的第一个参数应该是 1。而且你不检查错误。

于 2012-11-29T14:20:09.793 回答