我创建了一个最小的设置,用一个片段着色器来设置颜色,所以甚至没有一个参数。顶点着色器传入一个矩阵,并转换点。我们可以看到球体,但只是它的一部分。
我不想把整个代码都贴出来,我尽可能地把代码写得最少,但是包括着色器加载代码在内,大约有300行。我只会把核心部分贴出来,如果有人想要更多的话,我会把所有的都贴出来。
下面是演示代码,包括一个精简的Sphere类和glmain。
# include <GL/glew.h>
# include "common/common.hh"
# include <glm/glm.hpp>
# include <glm/ext.hpp>
# include <numbers>
# include <iostream>
# include <iomanip>
# include <cstdint>
# include <string>
using namespace std;
using namespace glm;
using namespace std::numbers;
class Sphere {
private:
uint32_t progid; // handle to the shader code
uint32_t vao; // array object container for vbo and indices
uint32_t vbo; // handle to the point data on the graphics card
uint32_t lbo; // handle to buffer of indices for lines for wireframe sphere
uint32_t latRes, lonRes;
uint32_t resolution;
public:
/**
* @brief Construct a sphere
*
* @param r radius of the sphere
* @param latRes resolution of the grid in latitude
* @param lonRes resolution of the grid in latitude
*/
Sphere(double r, uint32_t latRes, uint32_t lonRes);
~Sphere() { cleanup(); }
void render(mat4& trans);
void cleanup();
};
Sphere::Sphere(double r, uint32_t latRes, uint32_t lonRes) : latRes(latRes), lonRes(lonRes),
resolution((2*latRes-2)*lonRes + 2) {
progid = loadShaders( "05_3d.vert", "02simple.frag" );
double dlon = 2.0*numbers::pi / lonRes, dlat = numbers::pi / latRes;
double z;
double lat = -numbers::pi/2 + dlat; // latitude in radians
double rcircle;
float vert[resolution*3]; // x,y,z
uint32_t c = 0;
for (uint32_t j = 0; j < 2*latRes-2; j++, lat += dlat) {
//what is the radius of hte circle at that height?
rcircle = r* cos(lat); // size of the circle at this latitude
z = r * sin(lat); // height of each circle
double t = 0;
for (uint32_t i = 0; i < lonRes; i++, t += dlon) {
vert[c++] = rcircle * cos(t), vert[c++] = rcircle * sin(t);
vert[c++] = z;
}
cout << endl;
}
// south pole
vert[c++] = 0;
vert[c++] = 0;
vert[c++] = -r;
// north pole
vert[c++] = 0;
vert[c++] = 0;
vert[c++] = r;
cout << "resolution: " << resolution << endl;
cout << "predicted num vert components: " << resolution*3 << endl;
cout << "actual num vert components: " << c << endl;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, resolution, vert, GL_STATIC_DRAW);
glBindVertexArray(0);
}
void Sphere::render(mat4& trans) {
glUseProgram(progid); // Use the shader
uint32_t matrixID = glGetUniformLocation(progid, "trans");
glUniformMatrix4fv(matrixID, 1, GL_FALSE, &trans[0][0]);
glBindVertexArray(vao);
glVertexAttribPointer(
0, // first parameter to shader, numbered 0
3, // 3 floating point numbers (x,y,z)
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // this is the entire set of data, move on
(void*)0 // array buffer offset
);
glEnableVertexAttribArray(0); // pass x,y to shader
glEnable(GL_PROGRAM_POINT_SIZE);
//points don't work, why not? And how to set the size of the points?
glPointSize(5);
glDrawArrays(GL_POINT, 0, resolution);
// line strips work, but incomplete (see screen shot)
glDrawArrays(GL_LINE_STRIP, 0, resolution);
glDisableVertexAttribArray(0);
}
void Sphere::cleanup() {
glDeleteBuffers(1, &vbo); // remove vbo memory from graphics card
glDeleteVertexArrays(1, &vao); // remove vao from graphics card
glDeleteProgram(progid);
}
using namespace std;
void glmain() {
win = createWindow(800, 800, "Sphere demo");
glClearColor(0.0f, 0.0f, 0.4f, 0.0f); // Dark blue background
Sphere sphere(1.0, 30, 15);
mat4 trans= lookAt(vec3(0,0,0), vec3(10,5,10), vec3(0,1,0));
do {
glClear( GL_COLOR_BUFFER_BIT ); // Clear the screen
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
//glDepthFunc(GL_LESS);
sphere.render(trans);
glfwSwapBuffers(win); // double buffer
glfwPollEvents();
} while( glfwGetKey(win, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
glfwWindowShouldClose(win) == 0 );
}
点完全没有显示,所以这个调用被注解掉了。我们画了一个线条带。这有点作用。为什么它被截断了?为什么它至少没有完成球体的图层?
着色器如下所示:
# version 330 core
// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 v;
uniform mat4 trans;
void main(){
gl_PointSize = 5;
gl_Position = trans * vec4(v,1.0);
gl_Position.w = 1.0;
}
片段着色器:
# version 330 core
out vec4 color;
void main()
{
color = vec4(1,1,1,1);
}
1条答案
按热度按时间r6l8ljro1#
glBufferData
的 size 参数指定缓冲区对象的新数据存储的大小(以字节为单位):glBufferData(GL_ARRAY_BUFFER, resolution, vert, GL_STATIC_DRAW);
个