从文本分段错误的OpenGL高度图

时间:2015-03-21 03:39:09

标签: c++ opengl graphics 3d

我正在尝试从25个浮点值创建一个高度图,如下所示:

#define HEIGHT_VERTS 5
#define VALS_PER_VERT_HEIGHT 5

float heightmapVerts[ HEIGHT_VERTS*VALS_PER_VERT_HEIGHT ] = {
            //5    
            -0.9, -0.6, -0.4, -0.6, -0.9,
            -0.2, 0.1, 0.3, 0.1, -0.3,
            0, 0.4, 0.8, 0.4, 0,
            -0.2, 0.1, 0.3, 0.1, -0.3,
            0.5, -0.6, -0.4, -0.6, -0.9,    
    };

我在调用时遇到分段错误:

    glDrawArrays(GL_TRIANGLES, 0, HEIGHT_VERTS);

我被建议这是因为glVertexAttribPointer()的size参数必须是1,2,3或4.我用5传递:

glVertexAttribPointer(vertLocHeight, VALS_PER_VERT_HEIGHT, GL_FLOAT, GL_FALSE, 0, 0);

但我得到另一个错误,说如果这些值较小,我有太多顶点(例如:#define VALS_PER_VERT_HEIGHT 3)

error: too many initializers for ‘float [15]’ 

我已将其余代码附加到某些上下文中,我对OpenGL非常陌生,所以如果代码混乱,我会道歉。

#include <stdio.h>
// GLEW loads OpenGL extensions. Required for all OpenGL programs.
#include <GL/glew.h>
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
// Utility code to load and compile GLSL shader programs
#include "shader.hpp"
#include <iostream>
#include <fstream>
#include <vector>
#include "glm/glm.hpp"

#define WINDOW_WIDTH    400
#define WINDOW_HEIGHT   400

#define VALS_PER_VERT_HEIGHT 5//5
#define VALS_PER_COLOUR_HEIGHT 4
#define HEIGHT_VERTS 5 //height map vertices per line

using namespace std;

// Handle to our VAO generated in setShaderData method
//heightmap


unsigned int vertexVaoHandleHeight;

// Handle to our shader program
unsigned int programID;

/**
 * Sets the shader uniforms and vertex data
 * This happens ONCE only, before any frames are rendered
 * @param id, Shader program object to use
 * @returns 0 for success, error otherwise
 */
int setShaderData(const unsigned int &id) 
{   
    float heightmapVerts[ HEIGHT_VERTS*VALS_PER_VERT_HEIGHT ] = {
            //5    
            -0.9, -0.6, -0.4, -0.6, -0.9,
            -0.2, 0.1, 0.3, 0.1, -0.3,
            0, 0.4, 0.8, 0.4, 0,
            -0.2, 0.1, 0.3, 0.1, -0.3,
            0.5, -0.6, -0.4, -0.6, -0.9,    
    };



    // Colours for each vertex; red, green, blue and alpha
    // This data is indexed the same order as the vertex data, but reads 4 values
    // Alpha will not be used directly in this example program
        float heightColours[ HEIGHT_VERTS*VALS_PER_COLOUR_HEIGHT ] = {
            0.8f, 0.7f, 0.5f, 1.0f,
            0.3f, 0.7f, 0.1f, 1.0f,
            0.8f, 0.2f, 0.5f, 1.0f,        
    };  

    // heightmap stuff ##################################################   
    // Generate storage on the GPU for our triangle and make it current.
    // A VAO is a set of data buffers on the GPU
    glGenVertexArrays(1, &vertexVaoHandleHeight);
    glBindVertexArray(vertexVaoHandleHeight);       

    // Generate new buffers in our VAO
    // A single data buffer store for generic, per-vertex attributes
    unsigned int bufferHeight[2];
    glGenBuffers(2, bufferHeight);
    // Allocate GPU memory for our vertices and copy them over
    glBindBuffer(GL_ARRAY_BUFFER, bufferHeight[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(float)*HEIGHT_VERTS*VALS_PER_VERT_HEIGHT, heightmapVerts, GL_STATIC_DRAW);
    // Do the same for our vertex colours
    glBindBuffer(GL_ARRAY_BUFFER, bufferHeight[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(float)*HEIGHT_VERTS*VALS_PER_COLOUR_HEIGHT, heightColours, GL_STATIC_DRAW);    

    // Now we tell OpenGL how to interpret the data we just gave it
    // Tell OpenGL what shader variable it corresponds to
    // Tell OpenGL how it's formatted (floating point, 3 values per vertex)
    int vertLocHeight = glGetAttribLocation(id, "a_vertex");
    glBindBuffer(GL_ARRAY_BUFFER, bufferHeight[0]);
    glEnableVertexAttribArray(vertLocHeight);
    glVertexAttribPointer(vertLocHeight, VALS_PER_VERT_HEIGHT, GL_FLOAT, GL_FALSE, 0, 0);

    // Do the same for the vertex colours
    int colourLocHeight = glGetAttribLocation(id, "a_colour");
    glBindBuffer(GL_ARRAY_BUFFER, bufferHeight[1]);
    glEnableVertexAttribArray(colourLocHeight);
    glVertexAttribPointer(colourLocHeight, VALS_PER_COLOUR_HEIGHT, GL_FLOAT, GL_FALSE, 0, 0);
    // heightmap stuff ##################################################

    // An argument of zero un-binds all VAO's and stops us
    // from accidentally changing the VAO state
    glBindVertexArray(0);
    // The same is true for buffers, so we un-bind it too
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    return 0;   // return success
}
/**
 * Renders a frame of the state and shaders we have set up to the window
 * Executed each time a frame is to be drawn.
 */
void render() 
{
    // Clear the previous pixels we have drawn to the colour buffer (display buffer)
    // Called each frame so we don't draw over the top of everything previous
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glUseProgram(programID);

    // HEIGHT MAP STUFF ###################################
    // Make the VAO with our vertex data buffer current
    glBindVertexArray(vertexVaoHandleHeight);
    // Send command to GPU to draw the data in the current VAO as triangles
    //CRASHES HERE
    glDrawArrays(GL_TRIANGLES, 0, HEIGHT_VERTS);

    glBindVertexArray(0);   // Un-bind the VAO

    // HEIGHT MAP STUFF ###################################

    glutSwapBuffers();  // Swap the back buffer with the front buffer, showing what has been rendered

    glFlush();  // Guarantees previous commands have been completed before continuing
}

1 个答案:

答案 0 :(得分:0)

你搞砸了。

1)使用glVertexAttribPointer(),您可以设置顶点属性 - 这些属性几乎总是某种向量。对于顶点位置,如果需要在2D中绘制场景,则传递size = 2(因为每个顶点具有x和y坐标),对于3D - 传递3(x,y,z)。

2)我认为你对高度图的解释也是错误的。您只使用高度值填充数组(在3D空间中,这些是Y坐标)。但X和Z在哪里?你需要渲染顶点,所以你需要传递所有的x,y和z坐标,这样OpenGL才能知道应该渲染每个点的位置。

您的程序崩溃了,因为您发送的数据不够,OpenGL尝试从内存中读取,但这并不属于您。

我假设你想要一个5x5网格的高度图?以这种方式初始化数据:

float heightmapVerts[25] =
{
  //leave this as it is right now
};

vec3 vertices[5][5];

for(int z_num = 0; z_num < 5; ++z_num)
{
  for(int x_num = 0; x_num < 5; ++x_num)
  {
    vertices[z_num][x_num].x = x_num * 0.5f;
    vertices[z_num][x_num].z = z_num * 0.5f;
    vertices[z_num][x_num].y = heightmapVerts[z_num * 5 + x_num];
  }
}

然后你可以打电话:

glVertexAttribPointer(vertLocHeight, 3, GL_FLOAT, GL_FALSE, 0, 0);

<强>更新

  

vec3代表三维向量。我把它写成伪代码   说明了概念,但为了简单起见,你可能想要   使用这个伟大的图书馆:OpenGL Mathematics

更新2:

  

还有一件事:颜色数据也设置不正确。你可能想要   颜色为RGB值,因此每个顶点需要额外的3个浮点数   代表它的颜色。此外,应放置位置和颜色   单个VBO,不需要将它们分开。

     

我不确定,如果你需要做所有简单的基础知识   图纸。您可能想阅读这些文章:

     

OpenGL Wiki

     

This nice tutorial

     

Lighthouse 3D