【问题标题】:c++ OpenGL terrain generationc++ OpenGL地形生成
【发布时间】:2015-07-29 18:45:52
【问题描述】:

我试图从顶点网格制作地形,但我有一个错误,只是找不到它。我坚持了 3 个小时。我使用 c++ 和 opengl。我计划使用混合贴图进行纹理和高度稍后映射。无论如何,这是代码:

它应该是这样的:http://postimg.org/image/9431kcvy7/

它的外观如下: http://postimg.org/image/xxsoesqkp/

如您所见,三角形由 1 个单位的矩形隔开,看起来所有底部点与坐标为 (0,0,0) 的点形成一个三角形

我知道这个问题似乎很容易解决,但我已经尝试了 3 个小时。请帮助:)

地图.h

#ifndef MAP_H
#define MAP_H

#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <SFML/OpenGL.hpp>
#include <SFML/Graphics.hpp>
#include <windows.h>
using namespace std;

struct coordinate{
    float x,y,z;
};

struct face{
    int v[3];
    int n[3];
};

struct uv{
    float x;
    float y;
};


class Map
{
    private:
        int mapX,mapY;
        vector<coordinate> vertex;
        vector<uv>textureCoordinates;
        vector<coordinate>normals;
        vector< vector<face> > faces;
        string fileNameString;
        sf::Image image[5];
        sf::Color faceColor,blendPixel,p0,p1,p2;
        sf::Image texture;
        sf::Uint8 pixels[256*256*4];
        unsigned int imageID[3],textureID;
    public:
        void load(const char *fileName);
        void draw();
};

#endif // MAP_H

还有 Map.cpp

#include "Map.h"

#define blendMap 3
#define heightMap 4

void Map::load(const char *fileName)
{
    int i,j;
    fileNameString=fileName;
    vector<face> F;
    coordinate v;
    face f;

    image[0].loadFromFile(fileNameString+"/0.png");
    image[1].loadFromFile(fileNameString+"/1.png");
    image[2].loadFromFile(fileNameString+"/2.png");
    image[blendMap].loadFromFile(fileNameString+"/blendMap.png");
    image[heightMap].loadFromFile(fileNameString+"/heightMap.png");

    mapX=image[blendMap].getSize().x;
    mapY=image[blendMap].getSize().y;

    for(i=-mapY/2;i<mapY/2;i++)
        for(j=-mapX/2;j<mapX/2;j++)
        {
            v.x=j*0.5;
            v.z=i*0.5;
            vertex.push_back(v);
        }
    for(i=0;i<mapY-1;i++)
    {
        for(j=0;j<2*(mapX-1);j++)
            F.push_back(f);
        faces.push_back(F);
    }

    for(i=0;i<mapY-1;i++)
        for(j=0;j<(mapX-1)*2;j+=2)
        {
            faces[i][j].v[0]=i*mapX+j;
            faces[i][j].v[1]=i*mapX+j+1;
            faces[i][j].v[2]=(i+1)*mapX+j;

            faces[i][j+1].v[0]=i*mapX+j+1;
            faces[i][j+1].v[1]=(i+1)*mapX+j+1;
            faces[i][j+1].v[2]=(i+1)*mapX+j;
        }

    for(i=0;i<mapX*mapY;i++)
        {
            color=image[heightMap].getPixel(i/mapX,i%mapX);
            vertex[i].y=0;//(float)color.r/25.5-10;
        }
}

void Map::draw()
{
    unsigned int i,j;

    for(i=0;i<mapY-1;i++)
        for(j=0;j<(mapX-1)*2;j+=2)
        {
            glBindTexture(GL_TEXTURE_2D,imageID[0]);
            glBegin(GL_TRIANGLES);
                glTexCoord2f (0,0);
                glVertex3f(vertex[faces[i][j].v[0]].x , vertex[faces[i][j].v[0]].y , vertex[faces[i][j].v[0]].z);
                glTexCoord2f (1,0);
                glVertex3f(vertex[faces[i][j].v[1]].x , vertex[faces[i][j].v[1]].y , vertex[faces[i][j].v[1]].z);
                glTexCoord2f (0,1);
                glVertex3f(vertex[faces[i][j].v[2]].x , vertex[faces[i][j].v[2]].y , vertex[faces[i][j].v[2]].z);

                glTexCoord2f (0,0);
                glVertex3f(vertex[faces[i][j+1].v[0]].x , vertex[faces[i][j+1].v[0]].y , vertex[faces[i][j+1].v[0]].z);
                glTexCoord2f (1,0);
                glVertex3f(vertex[faces[i][j+1].v[1]].x , vertex[faces[i][j+1].v[1]].y , vertex[faces[i][j+1].v[1]].z);
                glTexCoord2f (0,1);
                glVertex3f(vertex[faces[i][j+1].v[2]].x , vertex[faces[i][j+1].v[2]].y , vertex[faces[i][j+1].v[2]].z);
            glEnd();
        }
}

【问题讨论】:

  • 其实 3 小时对于调试 OpenGL 代码来说并不算多。我花了几天时间处理某些情况(比如实例化“错误”)。但是我首先看到的是您使用了已弃用的 OpenGL 函数!它们自 2007 年以来已被弃用!
  • 你能告诉我你在说哪些功能吗?我只是一个初学者,所以任何建议都有帮助
  • glBeginglTexCoord2fglVertex3f 均已弃用,请改用 VAO 和着色器。

标签: c++ opengl terrain


【解决方案1】:

一些事情:

for(i=-mapY/2;i<mapY/2;i++)

无论如何,这很危险,可能不是循环的意图。你想循环mapY 次。但是,如果mapY 是奇数,您将只循环mapY - 1 次。例如。如果mapY = 3,那么-mapY / 2 = -1; mapY / 2 = 1。因此,您将循环使用值 -10。这是第一个问题,导致缓冲区中的顶点太少(这可能是主要问题)。而是在坐标级别上进行移动:

for(i = 0; i < mapY; i++)
    for(j = 0; j < mapX; j++)
    {
        v.x = j * 0.5 - mapY / 2.0;
        v.z = i * 0.5 - mapX / 2.0;
        vertex.push_back(v);
    }

您使用vector&lt;vector&lt;...&gt;&gt; 表示面部是否有原因?正如你已经注意到的,它会给你各种关于索引的问题。只需使用vector&lt;Face&gt; 并将你所有的脸都放在那里。通常,您创建此结构一次,然后再也不碰它。所以二维索引可能不是必需的。如果你想保持二维索引,这个循环有错误的界限:

for(j=0;j<(mapX-1)*2;j+=2)

这个上限是一个包容性的界限。因此,使用

for(j = 0; j <= (mapX - 1) * 2; j += 2)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多