Üdv,
Megint csak OpenGL-lel szenvedek. Első lépésként egy Bézier görbét kellett megrajzolnom és őszintén szólva már ez sem volt éppen problémamentes, pedig nem egy nagy feladat.
glLineWidth(PATH_LINE_WIDTH);
glMap1d(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, PATH_CONTROL_POINTS, (double *) &(path->control_points[0]));
glEnable(GL_MAP1_VERTEX_3);
glMapGrid1d(50, 0, 1);
glEvalMesh1(GL_LINE, 0, 50);
Na most itt a glEvalMesh1() ugyebár azt csinálja, hogy felosztja a görbét 50 részre, kiszámolja a koordinátákat, majd a pontokat vonallal összeköti. Tehát görbém már van. Csakhogy ezen valaminek gurulnia is kellene, tehát az egyes szegmensek koordinátái alapján fizikai számításokat is kell végeznem. Tehát valahogy le kellene kérdeznem ezeket a koordinátákat, csak fogalmam sincs hogyan. Rákerestem, Stackoverflow-on is rákérdeztem, de egyelőre semmi megoldás. Szóval ha erre jár valami OpenGL guru akkor útba igazíthatna.
Előre is köszönök minden segítséget!
- 2892 megtekintés
Hozzászólások
Lehet, hogy ezt így meg lehet oldani, de tipikusan nem ez a jó megoldás a gyakorlatban. Megvan az algoritmusa hogyan kell kiszámolni egy bézier görbe adott pontját. Ezt szépen leimplementálod, ezután a kirajzoláshoz nem is kell mást tenni, mint kiszámolni n pontban a görbe koordinátáit és vonallal összekötni. Az animációhoz pontosan ugyanezt az algoritmust használod, csak itt az idő határozza meg melyik pont érdekel. (Jellemzően van az algoritmusnak egy t paramétere.)
- A hozzászóláshoz be kell jelentkezni
Kösz a választ. Nos a preferált út az lett volna hogy dolgozzon a grafikus könyvtár helyettem, ha ez lehetséges. De most már egyértelmű hogy jobban jártam volna ha inkább implementálom a dolgot, csak már rohadt sok időt rááldoztam hogy ezen a vonalon elindulva valahogy elérjem amit akarok és ezért gondoltam rákérdezek itt is hátha mégis van valami mód. Feltételeztem hogy ha már a könyvtár ki tudja rajzolni a cuccot akkor arra is módot ad hogy dolgozzak vele. Azt csak később tudtam hogy ezen függvények státusza már deprecated.
- A hozzászóláshoz be kell jelentkezni
A lehető legjobb megoldás az, ha az opengl-t tényleg csak a kártya vezérlésére használod. Ráadásként az általad használt megoldások már rég nem optimálisak, a legtöbbjük ami nem szoftveres implementáció az a hardware-ből is ki lett írtva. Ebben az esetben én CPU oldalon számolnám ki a görbét.
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
Értem, kösz a tippet. :)
- A hozzászóláshoz be kell jelentkezni
glMapGrid, glEvalMesh deprecated, ujabb OpenGL-ben már benne sincs. Ennek ellenére GPU-n el lehet végezni ezeket a számításokat, csak neked kell megírni hogy mit számoljon.
Arra is van lehetőség h OpenGL-ben elvégzett számítás eredményét kiolvassuk, TransformFeedback a keresendő kifejezés. A példában a data[5] tomböt feltöltjuk a GPU memoriájába, azon lefut a vertexShaderSrc program, majd az eredményeket a feedback[5] tömbbe visszaolvassuk, és kiiratjuk.
#define GLSL(src) "#version 330 core\n" #src
void testTransformFeedback()
{
const GLchar* vertexShaderSrc = GLSL(
in float inValue;
out float outValue;
void main()
{
outValue = sqrt(inValue);
}
);
GLuint shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(shader, 1, &vertexShaderSrc, nullptr);
glCompileShader(shader);
GLuint program = glCreateProgram();
glAttachShader(program, shader);
// Transform feedback's output definitions, must be done before linking the program
const GLchar* feedbackVaryings[] = { "outValue" };
glTransformFeedbackVaryings(program, 1, feedbackVaryings, GL_INTERLEAVED_ATTRIBS);
glLinkProgram(program);
glUseProgram(program);
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// VBO: input data
GLfloat data[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
// Set VBO as input for variable in shader source
GLint inputAttrib = glGetAttribLocation(program, "inValue");
glEnableVertexAttribArray(inputAttrib);
glVertexAttribPointer(inputAttrib, 1, GL_FLOAT, GL_FALSE, 0, 0);
// VBO: output data
GLuint tbo;
glGenBuffers(1, &tbo);
glBindBuffer(GL_ARRAY_BUFFER, tbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(data), nullptr, GL_STATIC_READ);
// Set VBO as output for variable in shader source
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tbo);
// Do the computation
glEnable(GL_RASTERIZER_DISCARD);
glBeginTransformFeedback(GL_POINTS);
glDrawArrays(GL_POINTS, 0, 5);
glEndTransformFeedback();
glFlush();
// Download result
GLfloat feedback[5];
glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(feedback), feedback);
LOGI << boost::format("Transform feedback result: %f %f %f %f %f") % feedback[0] % feedback[1] % feedback[2] % feedback[3] % feedback[4];
}
- A hozzászóláshoz be kell jelentkezni
Új OpenGL API-ban deprecated, de attól függően hogy hozta létre a context-et, használható vagy sem. Egyébként sikerült egy 2 éves topicot előhozni :)
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
Ha másod- vagy harmadrendű a görbe, akkor ne szenvedj azzal, hogy CPU-ból számolod ki a görbe pontjait és kötöd össze egyenesekkel, ez nagyon primitív megoldás, túl sok CPU-t használ. Hagyd, hogy a GPU rajzolja ki a görbét egy okos fragment shaderrel. Lásd: Loop-Blinn raszterizáció. http://http.developer.nvidia.com/GPUGems3/gpugems3_ch25.html illetve az eredeti cikk: http://research.microsoft.com/en-us/um/people/cloop/LoopBlinn05.pdf
Itt a kontrolpontokon kívül mindent a GPU számol.
- A hozzászóláshoz be kell jelentkezni