我正在尝试从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
}
答案 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,不需要将它们分开。
我不确定,如果你需要做所有简单的基础知识 图纸。您可能想阅读这些文章: