我一直在尝试将6个图像加载到立方体的每个面上,我试图找到一种方法来做,并发现使用 SOIL 我可以加载纹理图像。目前我想加载图像数组(6),并使用它来将每个立方体边的纹理设置为其中一个纹理。
到目前为止,这是我的代码,它加载了一个立方体,如果你注释LoadGLTextures()函数,它会在没有纹理的情况下继续旋转:
#include <windows.h> // for MS Windows
#include <GL/glut.h> // GLUT, include glu.h and gl.h
#include "SOIL.h""
#include <fstream>
#include <stdlib.h>
#include <stdio.h>
#include <Imagehlp.h>
#include <image_DXT.h>
using namespace std;
/* Global variables */
char title[] = "3D Shapes";
float _angle = 0.0;
GLuint texture[6];
/* Initialize OpenGL Graphics */
void initGL() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color to black and opaque
glClearDepth(1.0f); // Set background depth to farthest
glEnable(GL_DEPTH_TEST); // Enable depth testing for z-culling
glDepthFunc(GL_LEQUAL); // Set the type of depth-test
glShadeModel(GL_SMOOTH); // Enable smooth shading
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Nice perspective corrections
GLuint tex;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
float color[] = { 1.0f, 0.0f, 0.0f, 1.0f };
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color);
}
void LoadGLTextures() {
// Load Texture
Image *image[6]; //PROBLEM HERE
int i;
for (i = 0; i<6; i++){
// allocate space for texture
image[i] = (Image *)malloc(sizeof(Image));
if (image[i] == NULL) {
printf("Error allocating space for image");
exit(0);
}
}
if ((!ImageLoad("1.png", image[0])) || (!ImageLoad("2.png", image[1])) || (!ImageLoad("3.png", image[2])) || (!ImageLoad("4.png", image[3])) || (!ImageLoad("5.png", image[4])) || (!ImageLoad("6.png", image[5]))) {
exit(1);
}
for (i = 0; i<6; i++){
// Create Texture
glGenTextures(1, &texture[i]);
glBindTexture(GL_TEXTURE_2D, texture[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // scale linearly when image bigger than texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // scale linearly when image smalled than texture
glTexImage2D(GL_TEXTURE_2D, 0, 3, image[i]->sizeX, image[i]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, image[i]->data);
}
};
/* Handler for window-repaint event. Called back when the window first appears and
whenever the window needs to be re-painted. */
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers
glMatrixMode(GL_MODELVIEW); // To operate on model-view matrix
// Render a color-cube consisting of 6 quads with different colors
glLoadIdentity(); // Reset the model-view matrix
glTranslatef(1.5f, 0.0f, -7.0f); // Move right and into the screen
//Rotates, making sure it rotates around the center of the cube
glTranslatef(0.5, 1.0, 0.0);
glRotatef(_angle, 1.0, 1.0, 1.0);
glTranslatef(-0.5, -1.0, 0.0);
glBegin(GL_QUADS); // Begin drawing the color cube with 6 quads
// Top face (y = 1.0f)
// Define vertices in counter-clockwise (CCW) order with normal pointing out
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
// Bottom face (y = -1.0f)
glColor3f(1.0f, 0.5f, 0.0f); // Orange
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
// Front face (z = 1.0f)
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
// Back face (z = -1.0f)
glColor3f(1.0f, 1.0f, 0.0f); // Yellow
glVertex3f(1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
// Left face (x = -1.0f)
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face (x = 1.0f)
glColor3f(1.0f, 0.0f, 1.0f); // Magenta
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
// Black/white checkerboard
float pixels[] = {
0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f
};
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_FLOAT, pixels);
glEnd(); // End of drawing color-cube
//// Render a pyramid consists of 4 triangles
//glLoadIdentity(); // Reset the model-view matrix
//glTranslatef(-1.5f, 0.0f, -6.0f); // Move left and into the screen
//glBegin(GL_TRIANGLES); // Begin drawing the pyramid with 4 triangles
//// Front
//glColor3f(1.0f, 0.0f, 0.0f); // Red
//glVertex3f(0.0f, 1.0f, 0.0f);
//glColor3f(0.0f, 1.0f, 0.0f); // Green
//glVertex3f(-1.0f, -1.0f, 1.0f);
//glColor3f(0.0f, 0.0f, 1.0f); // Blue
//glVertex3f(1.0f, -1.0f, 1.0f);
//// Right
//glColor3f(1.0f, 0.0f, 0.0f); // Red
//glVertex3f(0.0f, 1.0f, 0.0f);
//glColor3f(0.0f, 0.0f, 1.0f); // Blue
//glVertex3f(1.0f, -1.0f, 1.0f);
//glColor3f(0.0f, 1.0f, 0.0f); // Green
//glVertex3f(1.0f, -1.0f, -1.0f);
//// Back
//glColor3f(1.0f, 0.0f, 0.0f); // Red
//glVertex3f(0.0f, 1.0f, 0.0f);
//glColor3f(0.0f, 1.0f, 0.0f); // Green
//glVertex3f(1.0f, -1.0f, -1.0f);
//glColor3f(0.0f, 0.0f, 1.0f); // Blue
//glVertex3f(-1.0f, -1.0f, -1.0f);
//// Left
//glColor3f(1.0f, 0.0f, 0.0f); // Red
//glVertex3f(0.0f, 1.0f, 0.0f);
//glColor3f(0.0f, 0.0f, 1.0f); // Blue
//glVertex3f(-1.0f, -1.0f, -1.0f);
//glColor3f(0.0f, 1.0f, 0.0f); // Green
//glVertex3f(-1.0f, -1.0f, 1.0f);
//glEnd(); // Done drawing the pyramid
glutSwapBuffers(); // Swap the front and back frame buffers (double buffering)
}
/* Handler for window re-size event. Called back when the window first appears and
whenever the window is re-sized with its new width and height */
void reshape(GLsizei width, GLsizei height) { // GLsizei for non-negative integer
// Compute aspect ratio of the new window
if (height == 0) height = 1; // To prevent divide by 0
GLfloat aspect = (GLfloat)width / (GLfloat)height;
// Set the viewport to cover the new window
glViewport(0, 0, width, height);
// Set the aspect ratio of the clipping volume to match the viewport
glMatrixMode(GL_PROJECTION); // To operate on the Projection matrix
glLoadIdentity(); // Reset
// Enable perspective projection with fovy, aspect, zNear and zFar
gluPerspective(45.0f, aspect, 0.1f, 100.0f);
}
void update(int value) { //function for increasing the angle variable smoothly, keeps it <=360
_angle += 1.0f;
if (_angle > 360) {
_angle -= 360;
}
glutPostRedisplay();
glutTimerFunc(25, update, 0);
}
/* Main function: GLUT runs as a console application starting at main() */
int main(int argc, char** argv) {
glutInit(&argc, argv); // Initialize GLUT
glutInitDisplayMode(GLUT_DOUBLE); // Enable double buffered mode
glutInitWindowSize(640, 480); // Set the window's initial width & height
glutInitWindowPosition(50, 50); // Position the window's initial top-left corner
glutCreateWindow(title); // Create window with the given title
glutDisplayFunc(display); // Register callback handler for window re-paint event
glutReshapeFunc(reshape); // Register callback handler for window re-size event
initGL(); // Our own OpenGL initialization
glutTimerFunc(25, update, 0); //Add a timer
glutMainLoop(); // Enter the infinite event-processing loop
return 0;
}