OpenGL immediate mode: gluSphere replacement

Updated interface_draw.c to use the new sphere batch.
This commit is contained in:
Clément Foucault 2017-02-08 00:38:07 +01:00 committed by Julian Eisel
parent 5b10a6bb8e
commit dfadb45254
4 changed files with 109 additions and 72 deletions

View File

@ -1282,63 +1282,6 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti
immUnbindProgram();
}
#define SPHERE_LAT_RES 24
#define SPHERE_LON_RES 32
static float sphere_coords[SPHERE_LON_RES][SPHERE_LAT_RES][3] = {{{2.0f}}};
static void ui_draw_lat_lon_vert(unsigned int pos, unsigned int nor, float radius, int lat, int lon)
{
const float x = sphere_coords[lon][lat][0];
const float y = sphere_coords[lon][lat][1];
const float z = sphere_coords[lon][lat][2];
immAttrib3f(nor, x, y, z);
immVertex3f(pos, x * radius, y * radius, z * radius);
}
static void ui_draw_unitvec_sphere(unsigned int pos, unsigned int nor, float radius)
{
const float lon_inc = 2 * M_PI / SPHERE_LON_RES;
const float lat_inc = M_PI / SPHERE_LAT_RES;
float lon, lat;
/* TODO put that in a batch */
/* Init coords only once */
if (sphere_coords[0][0][0] == 2.0f) {
lon = 0.0f;
for(int i = 0; i < SPHERE_LON_RES; i++, lon += lon_inc) {
lat = 0.0f;
for(int j = 0; j < SPHERE_LAT_RES; j++, lat += lat_inc) {
sphere_coords[i][j][0] = sinf(lat) * cosf(lon);
sphere_coords[i][j][1] = cosf(lat);
sphere_coords[i][j][2] = sinf(lat) * sinf(lon);
}
}
}
immBegin(GL_TRIANGLES, (SPHERE_LAT_RES-1) * SPHERE_LON_RES * 6);
for(int i = 0; i < SPHERE_LON_RES; i++) {
for(int j = 0; j < SPHERE_LAT_RES; j++) {
if (j != SPHERE_LAT_RES - 1) { /* Pole */
ui_draw_lat_lon_vert(pos, nor, radius, j, i);
ui_draw_lat_lon_vert(pos, nor, radius, j+1, i);
ui_draw_lat_lon_vert(pos, nor, radius, j+1, i+1);
}
if (j != 0) { /* Pole */
ui_draw_lat_lon_vert(pos, nor, radius, j, i);
ui_draw_lat_lon_vert(pos, nor, radius, j+1, i+1);
ui_draw_lat_lon_vert(pos, nor, radius, j, i+1);
}
}
}
immEnd();
}
#undef SPHERE_LAT_RES
#undef SPHERE_LON_RES
void ui_draw_but_UNITVEC(uiBut *but, uiWidgetColors *wcol, const rcti *rect)
{
/* sphere color */
@ -1357,40 +1300,36 @@ void ui_draw_but_UNITVEC(uiBut *but, uiWidgetColors *wcol, const rcti *rect)
ui_but_v3_get(but, light);
light[2] = -light[2];
VertexFormat *format = immVertexFormat();
unsigned int pos = add_attrib(format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
unsigned int nor = add_attrib(format, "nor", GL_FLOAT, 3, KEEP_FLOAT);
immBindBuiltinProgram(GPU_SHADER_SIMPLE_LIGHTING);
immUniformColor3fv(diffuse);
immUniform3fv("light", light);
/* transform to button */
gpuMatrixBegin3D_legacy();
gpuPushMatrix();
if (BLI_rcti_size_x(rect) < BLI_rcti_size_y(rect))
size = BLI_rcti_size_x(rect) / 200.f;
size = BLI_rcti_size_x(rect) / 2.f;
else
size = BLI_rcti_size_y(rect) / 200.f;
size = BLI_rcti_size_y(rect) / 2.f;
gpuTranslate3f(rect->xmin + 0.5f * BLI_rcti_size_x(rect), rect->ymin + 0.5f * BLI_rcti_size_y(rect), 0.0f);
gpuScale3f(size, size, MIN2(size, 1.0f));
gpuScale3f(size, size, size);
ui_draw_unitvec_sphere(pos, nor, 100.0);
immUnbindProgram();
Batch *sphere = Batch_get_sphere(2);
Batch_set_builtin_program(sphere, GPU_SHADER_SIMPLE_LIGHTING);
Batch_Uniform4f(sphere, "color", diffuse[0], diffuse[1], diffuse[2], 1.f);
Batch_Uniform3fv(sphere, "light", light);
Batch_draw(sphere);
/* restore */
glDisable(GL_CULL_FACE);
/* AA circle */
format = immVertexFormat();
pos = add_attrib(format, "pos", GL_FLOAT, 2, KEEP_FLOAT);
VertexFormat *format = immVertexFormat();
unsigned int pos = add_attrib(format, "pos", GL_FLOAT, 2, KEEP_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor3ubv((unsigned char *)wcol->inner);
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
imm_draw_lined_circle(pos, 0.0f, 0.0f, 100.0f, 32);
imm_draw_lined_circle(pos, 0.0f, 0.0f, 1.0f, 32);
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);

View File

@ -35,3 +35,9 @@
/* Extend Batch_set_program to use Blenders library of built-in shader programs. */
void Batch_set_builtin_program(Batch*, GPUBuiltinShader);
/* Replacement for gluSphere */
Batch *Batch_get_sphere(int lod);
void gpu_batch_init(void);
void gpu_batch_exit(void);

View File

@ -25,6 +25,9 @@
* ***** END GPL LICENSE BLOCK *****
*/
#include "BLI_utildefines.h"
#include "BLI_math.h"
#include "GPU_batch.h"
#include "gpu_shader_private.h"
@ -33,3 +36,87 @@ void Batch_set_builtin_program(Batch* batch, GPUBuiltinShader shader_id)
GPUShader *shader = GPU_shader_get_builtin_shader(shader_id);
Batch_set_program(batch, shader->program);
}
static Batch *sphere_high = NULL;
static Batch *sphere_med = NULL;
static Batch *sphere_low = NULL;
static VertexBuffer *vbo;
static VertexFormat format = {0};
static unsigned int pos_id, nor_id;
static unsigned int vert;
static void batch_sphere_lat_lon_vert(float lat, float lon)
{
float pos[3];
pos[0] = sinf(lat) * cosf(lon);
pos[1] = cosf(lat);
pos[2] = sinf(lat) * sinf(lon);
setAttrib(vbo, nor_id, vert, pos);
setAttrib(vbo, pos_id, vert++, pos);
}
/* Replacement for gluSphere */
static Batch *batch_sphere(int lat_res, int lon_res)
{
const float lon_inc = 2 * M_PI / lon_res;
const float lat_inc = M_PI / lat_res;
float lon, lat;
if (format.attrib_ct == 0) {
pos_id = add_attrib(&format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
nor_id = add_attrib(&format, "nor", GL_FLOAT, 3, KEEP_FLOAT);
}
vbo = VertexBuffer_create_with_format(&format);
VertexBuffer_allocate_data(vbo, (lat_res-1) * lon_res * 6);
vert = 0;
lon = 0.0f;
for(int i = 0; i < lon_res; i++, lon += lon_inc) {
lat = 0.0f;
for(int j = 0; j < lat_res; j++, lat += lat_inc) {
if (j != lat_res - 1) { /* Pole */
batch_sphere_lat_lon_vert(lat, lon);
batch_sphere_lat_lon_vert(lat+lat_inc, lon);
batch_sphere_lat_lon_vert(lat+lat_inc, lon+lon_inc);
}
if (j != 0) { /* Pole */
batch_sphere_lat_lon_vert(lat, lon);
batch_sphere_lat_lon_vert(lat+lat_inc, lon+lon_inc);
batch_sphere_lat_lon_vert(lat, lon+lon_inc);
}
}
}
return Batch_create(GL_TRIANGLES, vbo, NULL);
}
Batch *Batch_get_sphere(int lod)
{
BLI_assert(lod >= 0 && lod <= 2);
if (lod == 0)
return sphere_low;
else if (lod == 1)
return sphere_med;
else
return sphere_high;
}
void gpu_batch_init(void)
{
/* Hard coded resolution */
sphere_low = batch_sphere(8, 8);
sphere_med = batch_sphere(16, 10);
sphere_high = batch_sphere(32, 24);
}
void gpu_batch_exit(void)
{
Batch_discard_all(sphere_low);
Batch_discard_all(sphere_med);
Batch_discard_all(sphere_high);
}

View File

@ -32,6 +32,7 @@
#include "BLI_sys_types.h"
#include "GPU_init_exit.h" /* interface */
#include "GPU_immediate.h"
#include "GPU_batch.h"
#include "BKE_global.h"
#include "intern/gpu_codegen.h"
@ -59,6 +60,8 @@ void GPU_init(void)
if (G.debug & G_DEBUG_GPU)
gpu_debug_init();
gpu_batch_init();
immInit();
}
@ -68,6 +71,8 @@ void GPU_exit(void)
{
immDestroy();
gpu_batch_exit();
if (G.debug & G_DEBUG_GPU)
gpu_debug_exit();