创建缓存
在OpenGL中绘制模型图像,首先要创建并分配缓存区,然后将模型的顶点数据传入到缓存区中。
GLuint vao, vbo[2];
// 设置顶点缓存
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// 顶点缓存数据
glGenBuffers(2, vbo);
// 分配OpenGL缓存空间
long unsigned int size_array = sizeof(GLfloat) * num * 4;
// 顶点数据1
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER, size_array, NULL, GL_STATIC_DRAW);
// 顶点数据2
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glBufferData(GL_ARRAY_BUFFER, size_array, NULL, GL_STATIC_DRAW);
导入缓存数据
// 顶点数据1
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, size_array, Positions);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
// 顶点数据2
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glBufferSubData(GL_ARRAY_BUFFER, 0, size_array, Speeds);
//glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)size_array);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(1);
创建shader程序
ShaderInfo shaders[] = {
{GL_VERTEX_SHADER, vert, 0},
{GL_FRAGMENT_SHADER, frag, 0},
{GL_NONE, NULL, 0}
};
program = LoadShaders(shaders);
glUseProgram(program);
导入shader的uniform变量
// 旋转投影矩阵
view_matrix = vmath::translate(0.0f, 0.0f, 1.9f) * vmath::rotate(0.0f, 0.0f, 0.0f);
//vmath::mat4 projection_matrix = vmath::frustum(-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 10.0f);
// 透视投影矩阵
projection_matrix = vmath::perspective(60.0f, 1.0f, 0.1f, 1000.0f);
glUniformMatrix4fv(glGetUniformLocation(program, "view_matrix"),
1, GL_FALSE, view_matrix);
glUniformMatrix4fv(glGetUniformLocation(program, "projection_matrix"),
1, GL_FALSE, projection_matrix);
互操作
GLfloat *cudaPositions;
GLfloat *cudaSpeeds;
GLuint vbo[2];
cudaGraphicsResource *cudaResource[2];
// 将顶点缓存绑定到到CUDA内存
cudaGraphicsGLRegisterBuffer(&cudaResource[0], vbo[0], cudaGraphicsMapFlagsNone);
cudaGraphicsGLRegisterBuffer(&cudaResource[1], vbo[1], cudaGraphicsMapFlagsNone);
size_t size;
cudaGraphicsMapResources(1, &cudaResource[0], NULL);
cudaGraphicsMapResources(1, &cudaResource[1], NULL);
cudaGraphicsResourceGetMappedPointer( (void**)&cudaPositions, &size, cudaResource[0]);
cudaGraphicsResourceGetMappedPointer( (void**)&cudaSpeeds, &size, cudaResource[1]);
// 解除映射
cudaGraphicsUmapResources(1, &particleObj.cudaResource[0], NULL);
cudaGraphicsUmapResources(1, &particleObj.cudaResource[1], NULL);
创建纹理
// 创建缓存
GLuint tex;
glGenTextures(1, &tex);
// 绑定到纹理单元
glActiveTexture(GL_TEXTURE0 + textureIndex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, imageWidth, imageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageRead);
glGenerateMipmap(GL_TEXTURE_2D);
free(imageRead);
// 设置uniform
glUniform1i(glGetUniformLocation(program, "tex0") + textureIndex, textureIndex);
// 将缓存句柄,存储到统一的列表中
textures[textureIndex++] = tex;
着色器纹理
#version 400
in mat2 point_rotate;
uniform sampler2D tex0;
uniform sampler2D tex1;
out vec4 fColor;
void main(void){
vec4 color = texture(tex0,
point_rotate * (gl_PointCoord - vec2(0.5)) + vec2(0.5));
vec4 color2 = texture(tex1,
point_rotate * (gl_PointCoord - vec2(0.5)) + vec2(0.5));
if(dot(color.rgb, vec3(1.0)) > 2.0){
//if(color.r > 0.9 && color.g > 0.9 && color.b > 0.9){
color = vec4(0.0, 0.0, 0.0, 1.0);
}
fColor = color;
}
绘制图形
// 传输着色器uniform数据
initShaderUniform();
static const float black[] = {0.0f, 0.0f, 0.0f, 0.0f};
//glClearBufferv(GL_COLOR, 0, black);
glBindVertexArray(vao);
if(isClear == 1){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo[0]);
//glDepthMask(true);
glEnable(GL_DEPTH_TEST); // 启用深度测试
glEnable(GL_PROGRAM_POINT_SIZE);
glEnable( GL_POINT_SPRITE_ARB );
glDepthFunc(GL_LEQUAL); // 深度测试类型
//glDrawElements(GL_TRIANGLES, 216932*3, GL_UNSIGNED_INT, NULL);
glDrawArrays(GL_POINTS, 0, num);