Pracowałem z OpenGL przez kilka miesięcy, ucząc się wszystkiego od nowa. Teraz mam do renderowania pozycji, modele współrzędnych teksturyProblem z skórowaniem GPU za pomocą GLSL
Próbuję pracować z animowanymi modelami, które zrobię proces skórki animacji na karcie graficznej.
Przy okazji, jeśli ktoś chce mi pomóc 1 na 1, daj mi znać, nie miałbym nic przeciwko jeszcze bardziej bezpośredniemu podejściu.
Oto moja Format wierzchołek
struct VERTEX_ANIMATED
{
float3 position;
float3 normal;
float2 texCoord;
float weights[4];
unsigned boneIndices[4];
};
to jak mogę dodać moje Verts do uchwytu bufora GPU (dowolny zmienne niezainicjalizowane w tych funkcjach znajdują się w ".h")
bool CVertexBuffer::IncreaseVerts(const unsigned int uiNumVerts)
{
//create our increase by value
unsigned uiIncrement = (uiNumVerts/BUFFER_INCREASE_SIZE) * BUFFER_INCREASE_SIZE + BUFFER_INCREASE_SIZE;
m_uiNumVerts += uiIncrement;
//bind to our buffer
void* buffer1;
if (GLEW_ARB_vertex_shader)
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_uiVertBufferHandle);
//make sure our buffer exists
buffer1 = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_READ_WRITE);
}
else
{
glBindBuffer(GL_ARRAY_BUFFER, m_uiVertBufferHandle);
//make sure our buffer exists
buffer1 = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
}
if(buffer1)
{
//collection of all our data
void* buffer2 = new char[ (m_uiNumVerts)*sizeof(VertexFormat) ];
memset(buffer2, 0, (m_uiNumVerts)*sizeof(VertexFormat));
memcpy(buffer2, buffer1, (m_uiNumVerts - uiIncrement)*sizeof(VertexFormat) );
//create a new buffer
//unsigned uiNewHandle;
if (GLEW_ARB_vertex_shader)
{
//allocate our new storage space, and store our data in there
glBufferDataARB(GL_ARRAY_BUFFER_ARB, (m_uiNumVerts*sizeof(VertexFormat)), buffer2, GL_DYNAMIC_READ);
//lock our buffer
//void* buffer2 = glMapBuffer(GL_ARRAY_BUFFER_ARB, GL_READ_WRITE);
//unlock our buffer2
//if(glUnmapBufferARB(GL_ARRAY_BUFFER_ARB) == GL_FALSE)
// return false;
//}
//reset what we are bound to
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
}
else
{
//allocate our new storage space, and store our data in there
glBufferDataARB(GL_ARRAY_BUFFER_ARB, (m_uiNumVerts*sizeof(VertexFormat)), buffer2, GL_DYNAMIC_READ);
//reset what we are bound to
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
}
//delete our buffer
free(buffer2);
//Unmap our currently mapped buffer
glUnmapBuffer(GL_ARRAY_BUFFER);
return true;
}
unsigned int CVertexBuffer::AddVerts(const VERTEX_ANIMATED* pVerts, unsigned int iNumVerts)
{
//Save the location to copy to
unsigned int uiVertLocation = m_uiVertsUsed;
m_uiVertsUsed += iNumVerts;
if(m_uiVertsUsed > m_uiNumVerts)
{
IncreaseVerts(m_uiVertsUsed - m_uiNumVerts);
}
if(GLEW_ARB_vertex_program)
{
//bind the buffer we're gonna mess with
glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_uiVertBufferHandle);
//get the pointer position where we can add verts
void* pPositionBuffer = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_READ_WRITE );
//now copy into our memory spot
//which we need to move to the right position
memcpy(((char*)pPositionBuffer) + (uiVertLocation*sizeof(VertexFormat)), pVerts, iNumVerts*sizeof(VertexFormat));
//now stop mapping
glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
}
else
{
//bind the buffer we're gonna mess with
glBindBuffer(GL_ARRAY_BUFFER, m_uiVertBufferHandle);
//get the pointer position where we can add verts
void* pPositionBuffer = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
//now copy into our memory spot
//which we need to move to the right position
memcpy(((char*)pPositionBuffer) + (uiVertLocation*sizeof(VertexFormat)), pVerts, iNumVerts*sizeof(VertexFormat));
//now stop mapping
glUnmapBuffer(GL_ARRAY_BUFFER);
}
return uiVertLocation;
}
Zakładam, że mój błąd wynika z tego, jak inicjuję moje dane lub jak przekazuję moje dane do modułu cieniującego.
Oto prosty wezwanie do mojego stworzenia programu shaderów trwa w nazwie pliku vertex shader i nazwa pliku fragment shader następnie zmienna dla głównych zmiennych, które chcą być określone takie jak „Pozycja, normalne, texCoords”
CreateProgram("animTriangle.vp",
"animTriangle.fp",
5,
VERTEX_ATTRIB, "vVertexPos",
NORMAL_ATTRIB, "vVertexNormal",
TEXTURE_COORD_ATTRIB0, "vTexCoord",
COLOR_ATTRIB, "vBlendWeights",
COLOR2_ATTRIB, "vBoneIndices");
w bok to funkcja robię analizowania parametrów po utworzeniu i skompilowane programowi Shader
//make sure to use our program to setup our handles
glUseProgram(m_uiProgramHandle);
//start from this parameter
va_start(parseList, szFragmentShaderName);
//read in number of variables if any
uiNum = va_arg(parseList, unsigned);
//for loop through our attribute pairs
int enumType = 0;
for(unsigned x = 0; x < uiNum; ++x)
{
//specify our attribute locations
enumType = va_arg(parseList, int);
char* name = va_arg(parseList, char*);
glBindAttribLocation(m_uiProgramHandle, enumType, name);
}
//end our list parsing
va_end(parseList);
oto moja lista zmiennych na początku mojego vertex shader
in vec3 vVertexPos; // position
in vec3 vVertexNormal; // normal
in vec2 vTexCoord; // texture coordinate....
in vec4 vBlendWeights; // the weights pull of the related bone
in ivec4 vBoneIndices; // the indicators of which bones we are influenced by
tutaj jest mój wierzchołek krok
//set which vertices we will be using
glBindBuffer(GL_ARRAY_BUFFER, m_uiVertBufferHandle);
//enable these vertex attributes
glEnableVertexAttribArray(VERTEX_ATTRIB);
glEnableVertexAttribArray(NORMAL_ATTRIB);
glEnableVertexAttribArray(TEXTURE_COORD_ATTRIB0);
glEnableVertexAttribArray(COLOR_ATTRIB);
glEnableVertexAttribArray(COLOR2_ATTRIB);
//specify our vertex attribute
glVertexAttribPointer(VERTEX_ATTRIB, 3, GL_FLOAT, GL_FALSE, sizeof(VERTEX_ANIMATED), BUFFER_OFFSET(0));
//specify our normal attribute
glVertexAttribPointer(NORMAL_ATTRIB, 3, GL_FLOAT, GL_FALSE, sizeof(VERTEX_ANIMATED), BUFFER_OFFSET(12));
//specify our texture attribute
glVertexAttribPointer(TEXTURE_COORD_ATTRIB0, 2, GL_FLOAT, GL_FALSE, sizeof(VERTEX_ANIMATED), BUFFER_OFFSET(24));
//specify our bone weight attribute location
glVertexAttribPointer(COLOR_ATTRIB, 4, GL_FLOAT, GL_FALSE, sizeof(VERTEX_ANIMATED), BUFFER_OFFSET(32));
//specify our bone indice attribute location
glVertexAttribPointer(COLOR2_ATTRIB, 4, GL_INT, GL_FALSE, sizeof(VERTEX_ANIMATED), BUFFER_OFFSET(48));
teraz mogę załadować modele statyczne dobrze. Kiedy ładuję moje animowane modele, dostaję się jak połowa modelu lub połowa modelu z brakującymi częściami na tej połowie. Pracowałem wcześniej z DirectX i tylko natknąłem się na ten problem, kiedy gpu prawidłowo odczytało moje bufory.
Jeśli chcieliby Państwo uzyskać więcej informacji, daj mi znać. Byłem w tym dziwnym problemie przez prawie 2 tygodnie i bardzo chciałbym nauczyć się mojego problemu.
Jak przekazujesz matryce kostne do modułu cieniującego? –
w module cieniującym wygląda to tak: / /uniform mat4 mAnimPose [40]; / w .cpp ten sposób przekazać go / glUniformMatrix4fv (glGetUniformLocation (pCurShader-> GetShaderProgramHandle() "mAnimPose") pCurBones.size() GL_FALSE (pływak *) (i pCurBones [0])); / ale obecnie w module cieniującym nie używam ich tylko po to, aby przetestować resztę modelu, więc w zasadzie ustawię mnożniki, aby były mnożone tylko przez matrycę rzutowania widoku modelu, którą to macierz działa, ponieważ jest tą, której używam w moim modelu statycznym shader –
Przepraszam, nie jestem dobra z tą składową kodu komentarza X_X –