-lopengl32 -lglu32 -lglut32 -lpng

#include <iostream>
#include <GL/glut.h>
#include <png.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

using namespace std;

// 摄像机视角控制
float camX = 0.0f, camY = 8.0f, camZ = 20.0f;
float rotX = 0.0f, rotY = 0.0f;
int lastMouseX, lastMouseY;
bool mouseDown = false;

// 纹理ID
GLuint tex_grass_on, tex_grass_side, tex_dirt, tex_stone;

// 平台尺寸(方块数量)
#define PLAT_SIZE 10
// 平台总层数
#define LAYERS 6

// ------------------------------
// PNG图片加载函数(C++98兼容)
// ------------------------------
GLuint loadPNG(const char* filename) {
    FILE* fp = fopen(filename, "rb");
    if (!fp) {
        cout << "找不到贴图: " << filename << endl;
        return 0;
    }

    unsigned char sig[8];
    fread(sig, 1, 8, fp);
    if (!png_check_sig(sig, 8)) {
        fclose(fp);
        return 0;
    }

    png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    png_infop info_ptr = png_create_info_struct(png_ptr);
    setjmp(png_jmpbuf(png_ptr));

    png_init_io(png_ptr, fp);
    png_set_sig_bytes(png_ptr, 8);
    png_read_info(png_ptr, info_ptr);

    int width = png_get_image_width(png_ptr, info_ptr);
    int height = png_get_image_height(png_ptr, info_ptr);
    int channels = png_get_channels(png_ptr, info_ptr);

    png_bytep* row_pointers = new png_bytep[height];
    unsigned char* data = new unsigned char[width * height * channels];
    for (int i = 0; i < height; i++) {
        row_pointers[height - 1 - i] = data + i * width * channels;
    }

    png_read_image(png_ptr, row_pointers);

    GLuint tex;
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    if (channels == 3) {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
    } else {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
    }

    delete[] row_pointers;
    delete[] data;
    fclose(fp);
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);

    return tex;
}

// ------------------------------
// 渲染单个立方体(带6面纹理)
// ------------------------------
void drawCube(float x, float y, float z, GLuint top, GLuint side, GLuint bottom) {
    glPushMatrix();
    glTranslatef(x, y, z);

    // 上面
    glBindTexture(GL_TEXTURE_2D, top);
    glBegin(GL_QUADS);
    glTexCoord2f(0,0); glVertex3f(-1,1,-1);
    glTexCoord2f(1,0); glVertex3f(1,1,-1);
    glTexCoord2f(1,1); glVertex3f(1,1,1);
    glTexCoord2f(0,1); glVertex3f(-1,1,1);
    glEnd();

    // 下面
    glBindTexture(GL_TEXTURE_2D, bottom);
    glBegin(GL_QUADS);
    glTexCoord2f(0,0); glVertex3f(-1,-1,-1);
    glTexCoord2f(1,0); glVertex3f(1,-1,-1);
    glTexCoord2f(1,1); glVertex3f(1,-1,1);
    glTexCoord2f(0,1); glVertex3f(-1,-1,1);
    glEnd();

    // 四周
    glBindTexture(GL_TEXTURE_2D, side);
    // 前
    glBegin(GL_QUADS);
    glTexCoord2f(0,0); glVertex3f(-1,-1,1);
    glTexCoord2f(1,0); glVertex3f(1,-1,1);
    glTexCoord2f(1,1); glVertex3f(1,1,1);
    glTexCoord2f(0,1); glVertex3f(-1,1,1);
    glEnd();
    // 后
    glBegin(GL_QUADS);
    glTexCoord2f(0,0); glVertex3f(-1,-1,-1);
    glTexCoord2f(1,0); glVertex3f(1,-1,-1);
    glTexCoord2f(1,1); glVertex3f(1,1,-1);
    glTexCoord2f(0,1); glVertex3f(-1,1,-1);
    glEnd();
    // 左
    glBegin(GL_QUADS);
    glTexCoord2f(0,0); glVertex3f(-1,-1,-1);
    glTexCoord2f(1,0); glVertex3f(-1,-1,1);
    glTexCoord2f(1,1); glVertex3f(-1,1,1);
    glTexCoord2f(0,1); glVertex3f(-1,1,-1);
    glEnd();
    // 右
    glBegin(GL_QUADS);
    glTexCoord2f(0,0); glVertex3f(1,-1,-1);
    glTexCoord2f(1,0); glVertex3f(1,-1,1);
    glTexCoord2f(1,1); glVertex3f(1,1,1);
    glTexCoord2f(0,1); glVertex3f(1,1,-1);
    glEnd();

    glPopMatrix();
}

// ------------------------------
// 生成6层平台
// ------------------------------
void drawWorld() {
    for (int layer = 1; layer <= LAYERS; ++layer) {
        GLuint t, s, b;

        if (layer == 6) { // 顶层:草方块
            t = tex_grass_on;
            s = tex_grass_side;
            b = tex_dirt;
        }
        else if (layer == 5 || layer == 4) { // 泥土
            t = s = b = tex_dirt;
        }
        else { // 石头(1、2、3层)
            t = s = b = tex_stone;
        }

        float y = layer * 2.0f - 6.0f;

        for (int x = -PLAT_SIZE; x < PLAT_SIZE; ++x) {
            for (int z = -PLAT_SIZE; z < PLAT_SIZE; ++z) {
                drawCube(x*2, y, z*2, t, s, b);
            }
        }
    }
}

// ------------------------------
// OpenGL主渲染
// ------------------------------
void display() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    // 3D视角
    glRotatef(rotX, 1,0,0);
    glRotatef(rotY, 0,1,0);
    glTranslatef(-camX, -camY, -camZ);

    drawWorld();

    glutSwapBuffers();
}

// ------------------------------
// 鼠标控制视角
// ------------------------------
void mouse(int button, int state, int x, int y) {
    if (button == GLUT_LEFT_BUTTON) {
        mouseDown = (state == GLUT_DOWN);
        lastMouseX = x;
        lastMouseY = y;
    }
}

void motion(int x, int y) {
    if (mouseDown) {
        rotY += (x - lastMouseX) * 0.3f;
        rotX += (y - lastMouseY) * 0.3f;
        lastMouseX = x;
        lastMouseY = y;
        glutPostRedisplay();
    }
}

// ------------------------------
// 键盘移动
// ------------------------------
void keyboard(int key, int x, int y) {
    float speed = 1.0f;
    if (key == GLUT_KEY_UP) camZ -= speed;
    if (key == GLUT_KEY_DOWN) camZ += speed;
    if (key == GLUT_KEY_LEFT) camX -= speed;
    if (key == GLUT_KEY_RIGHT) camX += speed;
    glutPostRedisplay();
}

// ------------------------------
// 初始化
// ------------------------------
void init() {
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glClearColor(0.5f, 0.7f, 1.0f, 1.0f);

    // 加载贴图(同exe文件夹)
    tex_grass_on = loadPNG("grass_block_on.png");
    tex_grass_side = loadPNG("grass_block_side.png");
    tex_dirt = loadPNG("dirt.png");
    tex_stone = loadPNG("stone.png");

    // 透视投影
    glMatrixMode(GL_PROJECTION);
    gluPerspective(60, 1.0, 0.1, 100);
    glMatrixMode(GL_MODELVIEW);
}

// ------------------------------
// 主函数
// ------------------------------
int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(800, 600);
    glutCreateWindow("Minecraft 3D Platform - C++98 OpenGL");

    init();

    glutDisplayFunc(display);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutSpecialFunc(keyboard);
    glutMainLoop();

    return 0;
}