Я пытаюсь нарисовать текстурированный куб с не чередующимися / отдельными буферами для каждой позиции / текстурных координат / нормальных буферов.
поскольку я использую opengles-2, я не использую VAO.
код выполняется без ошибок, но вывод пуст. Я попробовал несколько вариантов умножения матриц, но все еще безуспешно.
вся помощь приветствуется.
Я ограничил рисование одной инициализацией и вызовом отрисовки, так как хочу отладить одну итерацию цикла отрисовки.
///////////////////////////////BUFFERS///////////////////////////////
private:
std::vector<GLfloat> positions = {
// Front face
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
// Back face
-1.0, -1.0, -1.0,
-1.0, 1.0, -1.0,
1.0, 1.0, -1.0,
1.0, -1.0, -1.0,
// Top face
-1.0, 1.0, -1.0,
-1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, -1.0,
// Bottom face
-1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
1.0, -1.0, 1.0,
-1.0, -1.0, 1.0,
// Right face
1.0, -1.0, -1.0,
1.0, 1.0, -1.0,
1.0, 1.0, 1.0,
1.0, -1.0, 1.0,
// Left face
-1.0, -1.0, -1.0,
-1.0, -1.0, 1.0,
-1.0, 1.0, 1.0,
-1.0, 1.0, -1.0,
};
std::vector<GLfloat> vertexNormals = {
// Front
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
// Back
0.0, 0.0, -1.0,
0.0, 0.0, -1.0,
0.0, 0.0, -1.0,
0.0, 0.0, -1.0,
// Top
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
// Bottom
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
// Right
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
// Left
-1.0, 0.0, 0.0,
-1.0, 0.0, 0.0,
-1.0, 0.0, 0.0,
-1.0, 0.0, 0.0,
};
std::vector<GLfloat> textureCoordinates = {
// Front
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
// Back
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
// Top
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
// Bottom
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
// Right
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
// Left
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
};
std::vector<GLuint> vertexIndices = {
0, 1, 2, 0, 2, 3, // front
4, 5, 6, 4, 6, 7, // back
8, 9, 10, 8, 10, 11, // top
12, 13, 14, 12, 14, 15, // bottom
16, 17, 18, 16, 18, 19, // right
20, 21, 22, 20, 22, 23, // left
};
GLuint vbo[4];
static enum BUFFERS {
VERTEX_BUFFER,
TEXCOORD_BUFFER,
NORMAL_BUFFER,
INDEX_BUFFER
};
private:
//GLuint vao;
GLuint vbo[4];
static enum BUFFERS {
VERTEX_BUFFER,
TEXCOORD_BUFFER,
NORMAL_BUFFER,
INDEX_BUFFER
};
public:
void load_geometry(){
LOGD("in %s",__func__);
vbo[VERTEX_BUFFER] = NULL;
vbo[TEXCOORD_BUFFER] = NULL;
vbo[NORMAL_BUFFER] = NULL;
vbo[INDEX_BUFFER] = NULL;
glGenBuffers(1, &vbo[VERTEX_BUFFER]);
glBindBuffer(GL_ARRAY_BUFFER, vbo[VERTEX_BUFFER]);
glBufferData(GL_ARRAY_BUFFER, positions.size() * sizeof(GLfloat), positions.data(), GL_STATIC_DRAW);
glGenBuffers(1, &vbo[TEXCOORD_BUFFER]);
glBindBuffer(GL_ARRAY_BUFFER, vbo[TEXCOORD_BUFFER]);
glBufferData(GL_ARRAY_BUFFER, textureCoordinates.size() * sizeof(GLfloat), textureCoordinates.data(), GL_STATIC_DRAW);
glGenBuffers(1, &vbo[NORMAL_BUFFER]);
glBindBuffer(GL_ARRAY_BUFFER, vbo[NORMAL_BUFFER]);
glBufferData(GL_ARRAY_BUFFER, vertexNormals.size() * sizeof(GLfloat), vertexNormals.data(), GL_STATIC_DRAW);
glGenBuffers(1, &vbo[INDEX_BUFFER]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[INDEX_BUFFER]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, vertexIndices.size() * sizeof(GLuint), vertexIndices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
///////////////////////////////PROGRAM///////////////////////////////
private:
GLuint program;
public:
void load_shader(){
LOGD("in %s",__func__);
const char* vertex_shader = "attribute vec4 aVertexPosition;\n"
" attribute vec3 aVertexNormal;\n"
" attribute vec2 aTextureCoord;\n"
" uniform mat4 uNormalMatrix;\n"
" uniform mat4 uModelViewMatrix;\n"
" uniform mat4 uProjectionMatrix;\n"
" varying highp vec2 vTextureCoord;\n"
" varying highp vec3 vLighting;\n"
" void main(void) {\n"
" gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;\n"
" vTextureCoord = aTextureCoord;\n"
" // Apply lighting effect\n"
" highp vec3 ambientLight = vec3(0.3, 0.3, 0.3);\n"
" highp vec3 directionalLightColor = vec3(1, 1, 1);\n"
" highp vec3 directionalVector = normalize(vec3(0.85, 0.8, 0.75));\n"
" highp vec4 transformedNormal = uNormalMatrix * vec4(aVertexNormal, 1.0);\n"
" highp float directional = max(dot(transformedNormal.xyz, directionalVector), 0.0);\n"
" vLighting = ambientLight + (directionalLightColor * directional);\n"
" }";
const char* fragment_shader = " varying highp vec2 vTextureCoord;\n"
" varying highp vec3 vLighting;\n"
" uniform sampler2D uSampler;\n"
" void main(void) {\n"
" highp vec4 texelColor = texture2D(uSampler, vTextureCoord);\n"
" gl_FragColor = vec4(texelColor.rgb * vLighting, texelColor.a);\n"
" }";
GLuint gl_vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(gl_vs, 1, &vertex_shader, NULL);
glCompileShader(gl_vs);
GLint status = 0;
glGetShaderiv(gl_vs, GL_COMPILE_STATUS, &status);
if (status == 0) {
LOGE("*** Vertex shader compilation failed.");
ABORT_GAME;
}
LOGD("Vertex shader compilation succeeded.");
GLuint gl_fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(gl_fs, 1, &fragment_shader, NULL);
glCompileShader(gl_fs);
glGetShaderiv(gl_fs, GL_COMPILE_STATUS, &status);
if (status == 0) {
LOGE("*** Fragment shader compilation failed, %d", status);
ABORT_GAME;
}
LOGD("Fragment shader compilation succeeded.");
program = glCreateProgram();
glAttachShader(program, gl_vs);
glAttachShader(program, gl_fs);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &status);
if (status == 0) {
LOGE("*** Shader program link failed, %d", status);
ABORT_GAME;
}
LOGD("Program linking succeeded.");
}
///////////////////////////////TEXTURE///////////////////////////////
private:
GLuint tbo;
public:
void load_texture(cv::Mat frame){
if(frame.empty()){
frame = cv::Mat(4,4,CV_MAKETYPE(CV_8U,4),cv::Scalar::all(255));
}
GLenum format = frame.channels()==4 ? GL_RGBA : GL_RGB;
glGenTextures(1, &tbo);
glBindTexture(GL_TEXTURE_2D, tbo);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
cv::cvtColor(frame,frame, cv::COLOR_RGB2BGR);
glTexImage2D(GL_TEXTURE_2D, 0, format, frame.cols,frame.rows, 0, format, GL_UNSIGNED_BYTE, frame.ptr());
glBindTexture(GL_TEXTURE_2D, 0);
}
///////////////////////////////RENDER///////////////////////////////
public:
void render(GLuint PROGRAM){
LOGD("Ruby_vault in %s %d",__func__,__LINE__);
glm::mat4 projection_matrix = glm::perspective((float)(45.0f * M_PI / 180), 2,0f, 0.1f,200.0f);
glm::mat4 view_matrix = glm::mat4(1.0f);
glm::vec3 Eye = glm::vec3(0.0f,0.0f,-50.0f);
glm::vec3 Center = glm::vec3(0.0f,0.0f,0.0f);
glm::vec3 Up = glm::vec3(0.0f,1.0f,0.0f);
view_matrix = glm::lookAt(Eye, Center, Up);
glm::mat4 model_matrix = glm::mat4(1.0f);
model_matrix = glm::translate(model_matrix, glm::vec3(0.0f, 0.0f, 0.0f));
model_matrix = glm::scale(model_matrix, glm::vec3(1.0f, 1.0f, 1.0f));
model_matrix = view_matrix * model_matrix;
glm::mat4 normal_matrix = glm::mat4(1.0f);
normal_matrix = glm::inverseTranspose(model_matrix*view_matrix);
glBindBuffer(GL_ARRAY_BUFFER, vbo[VERTEX_BUFFER]);
GLint attribute_1 = glGetAttribLocation(PROGRAM,"aVertexPosition");
GLint attribute_2 = glGetAttribLocation(PROGRAM,"aTextureCoord");
GLint attribute_3 = glGetAttribLocation(PROGRAM,"aVertexNormal");
glVertexAttribPointer(attribute_1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray (attribute_1);
glBindBuffer(GL_ARRAY_BUFFER, vbo[TEXCOORD_BUFFER]);
glVertexAttribPointer(attribute_2, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray (attribute_2);
glBindBuffer(GL_ARRAY_BUFFER, vbo[NORMAL_BUFFER]);
glVertexAttribPointer(attribute_3, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray (attribute_3);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[INDEX_BUFFER]);
glUseProgram(PROGRAM);
GLint uniform_1 = glGetUniformLocation(PROGRAM, "uProjectionMatrix");
GLint uniform_2 = glGetUniformLocation(PROGRAM, "uModelViewMatrix");
GLint uniform_3 = glGetUniformLocation(PROGRAM, "uNormalMatrix");
GLint uniform_4 = glGetUniformLocation(PROGRAM, "uSampler");
glUniformMatrix4fv(uniform_1, 1, GL_FALSE, glm::value_ptr(projection_matrix));
glUniformMatrix4fv(uniform_2, 1, GL_FALSE, glm::value_ptr(model_matrix));
glUniformMatrix4fv(uniform_3, 1, GL_FALSE, glm::value_ptr(normal_matrix));
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, tbo);
glUniform1i(uniform_4,1);
//glDrawElements(GL_TRIANGLES, mesh->mNumFaces * 3 , GL_UNSIGNED_INT, NULL);
glDrawElements(GL_TRIANGLES, vertexIndices.size() , GL_UNSIGNED_INT, NULL);
}
//////////////////////////////INITIALIZATION/+DRAW CALL///////////////////////////////
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
Element element = new Element();
element->load_geometry();
element->load_shader();
element->load_texture(cv::imread("/storage/emulated/0/Ruby.jpg"));
element->render(element->get_program());
что не так с кодом? Что я должен сделать, чтобы использовать отдельные буферы?
edit: вызывается один раз перед инициализацией и первым вызовом.
////////////////////////////////////////////////////////////////////////
GLuint * m_RenderToTextureFBO = new GLuint[1];
GLuint * textureIds = new GLuint[1];
GLuint m_CubeFBOTextureId;
int width_4k = 3840;
int height_4k = 2160;
void PlayScene::frame_buffer() {
/** Create the texture, setup its properties for the FBO */
glGenTextures(1, textureIds);
m_CubeFBOTextureId = textureIds[0];
/** Bind the texture for FBO and Setup its properties */
glBindTexture(GL_TEXTURE_2D, m_CubeFBOTextureId);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
cv::Mat frame(height_4k,width_4k,CV_MAKETYPE(CV_8U,4),cv::Scalar::all(255));
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_4k, height_4k, 0, GL_RGBA, GL_UNSIGNED_BYTE, frame.data);
glGenFramebuffers(1, m_RenderToTextureFBO);
/** Bind our frame buffer */
glBindFramebuffer(GL_FRAMEBUFFER, m_RenderToTextureFBO[0]);
/** Attach texture to the frame buffer */
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_CubeFBOTextureId, 0);
/** Check FBO is complete and OK */
int iResult = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(iResult != GL_FRAMEBUFFER_COMPLETE)
{
LOGE("Framebuffer incomplete");
}
/** Un-bind frame buffer */
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
и до розыгрыша ..
glViewport(0,0,width_4k,height_4k);
/** set the Texture unit 0 active and bind the texture to it */
glActiveTexture(GL_TEXTURE0);
/** Enable frame buffer to start rendering into it */
glBindFramebuffer(GL_FRAMEBUFFER, m_RenderToTextureFBO[0]);
/** Create an Orange back ground */
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);