简体   繁体   English

文本分割错误导致的OpenGL高度图

[英]OpenGL Height Map from text segmentation fault

I am trying to create a heightmap from 25 float values like so: 我正在尝试从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,    
    };

I am getting a segmentation fault when calling: 调用时出现分段错误:

    glDrawArrays(GL_TRIANGLES, 0, HEIGHT_VERTS);

I have been suggested that it's because the size argument of glVertexAttribPointer() must be 1, 2, 3, or 4. I pass 5 with: 有人建议我这样做是因为glVertexAttribPointer()的size参数必须为1、2、3或4。我通过5传递了:

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

but I get another error saying that I have too many vertices if these values are smaller (eg: #define VALS_PER_VERT_HEIGHT 3) 但是我又收到一个错误消息,如果这些值较小,则顶点过多(例如:#define VALS_PER_VERT_HEIGHT 3)

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

I have attached the rest of my code for some context, I am very very new to OpenGL so I apologize if the code is messy. 我已经将我的其余代码附加到了某些上下文中,因为我对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
}

You are messing things up. 你搞砸了。

1) With glVertexAttribPointer() , you setup vertex attributes - those are almost always vectors of some kind. 1)使用glVertexAttribPointer() ,可以设置顶点属性-几乎总是某种矢量。 For vertex position, if you need to draw scene in 2D, pass size = 2 (because each vertex has x and y coordinates), for 3D - pass 3 (x, y, z). 对于顶点位置,如果需要以2D绘制场景,则传递尺寸= 2(因为每个顶点都有x和y坐标),对于3D-传递3(x,y,z)。

2) I think your interpretation of heightmap is also quite incorrect. 2)我认为您对heightmap的解释也很不正确。 You filled array only with height values (in 3D space, those are Y coordinates). 您仅用高度值填充了数组(在3D空间中,这些是Y坐标)。 But where are X and Z? 但是X和Z在哪里? You need to render vertices , so you need to pass all x, y and z coords, so OpenGL can know where each point should be rendered. 您需要渲染顶点 ,因此需要传递所有x,y和z坐标,以便OpenGL可以知道应在何处渲染每个点。

Your program crashes, because you send not enough data and OpenGL tries to read from memory, that doesn't belong to you. 您的程序崩溃,因为您发送的数据不足,并且OpenGL尝试从内存中读取不属于您的数据。

I assume, that you want a heightmap, which is a 5x5 grid? 我假设您想要一个5x5的高度图? Init data this way: 以这种方式初始化数据:

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];
  }
}

Then you can call: 然后,您可以致电:

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

Update: 更新:

vec3 stands for 3-dimensional vector. vec3代表3维向量。 I wrote it as pseudocode to illustrate conception, but for the sake of simplicity, you may want to use this great library: OpenGL Mathematics . 我将其编写为伪代码来说明概念,但是为了简单起见,您可能需要使用这个强大的库: OpenGL Mathematics

Update 2: 更新2:

One more thing: color data is also set improperly. 还有一件事:颜色数据设置也不正确。 You probably want color to be an RGB value, so every vertex needs additional 3 floats to represent its color. 您可能希望颜色为RGB值,因此每个顶点需要额外的3个浮点数来表示其颜色。 Also, position and color should be place in single VBO, there is no need for separating them. 另外,位置和颜色应放在单个VBO中,无需将它们分开。

I am not sure, if you got all basics required to do any simple drawings. 我不确定,如果您具备完成任何简单图纸所需的所有基本知识。 You may want to read these articles: 您可能需要阅读以下文章:

OpenGL Wiki OpenGL维基

This nice tutorial 这个不错的教程

Lighthouse 3D 灯塔3D

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM