Friday 15 April 2011

c++ - OpenGL Simple Cube not Appearing, Using Uniform Blocks -



c++ - OpenGL Simple Cube not Appearing, Using Uniform Blocks -

i trying draw simple cube homework assignment class reason isn't showing up.

i using uniform blocks , modern opengl. sure not doing correctly.

my finish code below. below illustration depends on glew + glfw + glm.

what found interesting lite , material uniform blocks index uniform block mvp matrix don't index.

any ideas?

here c++ code:

#include <iostream> #include <string> #include <sstream> #include <vector> #include <algorithm> #ifndef opengl_includes_ #define opengl_includes_ #include "gl\glew.h" #ifndef glfw_includes_ #define glfw_includes_ #if defined(_win32) #include <windows.h> #define glfw_expose_native_win32 #define glfw_expose_native_wgl #elif defined(__linux__) #include <x11/x.h> #include <x11/extensions/xrandr.h> #define glfw_expose_native_x11 #define glfw_expose_native_glx #endif #include "glfw\glfw3.h" #include "glfw\glfw3native.h" #endif #endif #ifndef glm_includes_ #define glm_includes_ #include <glm/glm.hpp> #include <glm/gtx/rotate_vector.hpp> #include <glm/gtc/matrix_transform.hpp> #include <glm/gtx/transform.hpp> #include <glm/gtc/type_ptr.hpp> #include <glm/gtc/quaternion.hpp> #include <glm/gtx/quaternion.hpp> #endif glfwwindow* mainwindow; #ifdef _win32 hwnd mainwindowwin32handle; #endif glint windowwidth = 1024; glint windowheight = 768; glulong sizedivizor = 1; glboolean riftavailable = false; glboolean useapplicationwindowframe = false; gluint mainopenglshaderprogramid; gluint matricesuniformblockid; gluint matricesuniformbufferid; gluint lightsuniformblockid; gluint lightsuniformbufferid; gluint materialsuniformblockid; gluint materialsuniformbufferid; glm::mat4 viewmatrix; glm::mat4 viewmodelmatrix; glm::mat4 projectionmatrix; glm::mat4 mvpmatrix; glm::mat3 normalmatrix; class standardcube; std::vector<standardcube> cubes; class standardcube { private: glfloat* vertices; glfloat* normals; gluint* indices; gluint vao; glm::mat4 modelmatrix; public: void loadintoopengl() { vertices = new glfloat[72] { 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f }; normals = new glfloat[72] { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f }; indices = new gluint[36] {0, 1, 2, 2, 3, 0, 4, 5, 6, 6, 7, 4, 8, 9, 10, 10, 11, 8, 12, 13, 14, 14, 15, 12, 16, 17, 18, 18, 19, 16, 20, 21, 22, 22, 23, 20 }; glgenvertexarrays(1, &vao); glbindvertexarray(vao); gluint meshbufferid; glgenbuffers(1, &meshbufferid); glbindbuffer(gl_array_buffer, meshbufferid); gluint totalbufferdata = (sizeof(glfloat) * 72) + (sizeof(glfloat) * 72); glbufferdata(gl_array_buffer, totalbufferdata, null, gl_static_draw); glbuffersubdata(gl_array_buffer, null, sizeof(glfloat) * 72, vertices); glvertexattribpointer(0, 3, gl_float, gl_false, 0, 0); glenablevertexattribarray(0); glbuffersubdata(gl_array_buffer, sizeof(glfloat) * 72, sizeof(glfloat) * 72, normals); glvertexattribpointer(1, 3, gl_float, gl_false, 0, (glvoid*)(sizeof(glfloat) * 72)); glenablevertexattribarray(1); gluint indexbufferid; glgenbuffers(1, &indexbufferid); glbindbuffer(gl_element_array_buffer, indexbufferid); glbufferdata(gl_element_array_buffer, sizeof(glint) * 36, indices, gl_static_draw); glbindvertexarray(null); modelmatrix = glm::mat4(1.0f); } void drawme() { mvpmatrix = projectionmatrix * viewmatrix * modelmatrix; viewmodelmatrix = viewmatrix * modelmatrix; normalmatrix = glm::transpose(glm::inverse(glm::mat3(mvpmatrix))); glbindbuffer(gl_uniform_buffer, matricesuniformbufferid); glbuffersubdata(gl_uniform_buffer, null, sizeof(glm::mat4), glm::value_ptr(mvpmatrix)); glbuffersubdata(gl_uniform_buffer, sizeof(glm::mat4), sizeof(glm::mat4), glm::value_ptr(viewmodelmatrix)); glbuffersubdata(gl_uniform_buffer, sizeof(glm::mat4) + sizeof(glm::mat4), sizeof(glm::mat3), glm::value_ptr(normalmatrix)); glbindbuffer(gl_uniform_buffer, null); glbindvertexarray(vao); gldrawelementsinstanced(gl_triangles, 36, gl_unsigned_int, null, 1); glbindvertexarray(null); } }; static void glfwkeycallback(glfwwindow* p_window, glint p_key, glint p_scancode, glint p_action, glint p_mods) { if (p_key == glfw_key_escape && p_action == glfw_press) { glfwsetwindowshouldclose(p_window, gl_true); } if (p_key == glfw_key_o && p_action == glfw_press) { glclearcolor(0.2f, 0.1f, 0.3f, 1.0f); } if (p_key == glfw_key_i && p_action == glfw_press) { glclearcolor(1.0f, 0.5f, 0.5f, 1.0f); } } static void glfwwindowresizecallback(glfwwindow* p_window, glint width, glint height) { //currentglfwapplication->windowresizecallback(p_window, width, height); } static void glfwmousemovementcallback(glfwwindow* p_window, gldouble mousex, gldouble mousey) { //currentglfwapplication->mousemovementcallback(p_window, mousex, mousey); } static void glfwframebuffersizecallback(glfwwindow* window, glint width, glint height) { glviewport(0, 0, width, height); } int initializeglfwglew() { mainwindow = null; if (!glfwinit()) { fprintf(stderr, "glfw failed initialize."); glfwterminate(); homecoming exit_failure; } glfwwindowhint(glfw_opengl_profile, glfw_opengl_any_profile); if (useapplicationwindowframe) { mainwindow = glfwcreatewindow(windowwidth, windowheight, "basic oculus rift example", null, null); } else { if (!riftavailable) { mainwindow = glfwcreatewindow(windowwidth, windowheight, "basic oculus rift example", null, null); } else { glint monitorcount; glfwmonitor** glfw_monitors = glfwgetmonitors(&monitorcount); glfwmonitor* monitortouse; switch (monitorcount) { case 0: printf("no monitors found, exiting.\n"); homecoming exit_failure; break; case 1: printf("two monitors expected, found one, using primary...\n"); monitortouse = glfwgetprimarymonitor(); break; case 2: printf("two monitors found, using sec monitor\n"); monitortouse = glfw_monitors[1]; break; default: printf("more 2 monitors found, using sec monitor\n"); monitortouse = glfw_monitors[1]; } mainwindow = glfwcreatewindow(windowwidth, windowheight, "basic oculus rift example", monitortouse, null); } } if (!mainwindow) { fprintf(stderr, "could not determine opengl version; exiting."); glfwterminate(); homecoming exit_failure; } glfwmakecontextcurrent(mainwindow); glewexperimental = gl_true; glenum err = glewinit(); if (glew_ok != err) { /* problem: glewinit failed, wrong. */ fprintf(stderr, "error: %s\n", glewgeterrorstring(err)); homecoming exit_failure; } glfwsetinputmode(mainwindow, glfw_sticky_keys, gl_true); glfwsetkeycallback(mainwindow, glfwkeycallback); glfwsetwindowsizecallback(mainwindow, glfwwindowresizecallback); glfwsetcursorposcallback(mainwindow, glfwmousemovementcallback); glfwsetframebuffersizecallback(mainwindow, glfwframebuffersizecallback); glfwswapbuffers(mainwindow); glfwpollevents(); homecoming exit_success; } int prepareopengl() { glenable(gl_depth_test); gldepthfunc(gl_less); glpolygonmode(gl_front_and_back, gl_fill); glenable(gl_texture_2d); glenable(gl_blend); glenable(gl_cull_face); glblendfunc(gl_src_alpha, gl_one_minus_src_alpha); glenable(gl_multisample); homecoming exit_success; } int loadshaders() { // create shaders gluint vertexshaderid = glcreateshader(gl_vertex_shader); gluint fragmentshaderid = glcreateshader(gl_fragment_shader); // compile vertex shader printf("compiling vertext shader.\n\n"); char const * vertexsource = "#version 330 \n\n\ layout(std140) uniform matrixinformation {\n\ mat4 m_pvm;\n\ mat4 m_viewmodel;\n\ mat3 m_normal;\n\ };\n\ layout(std140) uniform lights {\n\ vec3 l_dir; \n\ };\n\ in vec4 position;\n\ in vec3 normal;\n\ \n\ \n\ out data{\n\ vec3 normal;\n\ vec4 eye;\n\ } dataout;\n\ \n\ void main() {\n\ \n\ dataout.normal = normalize(m_normal * normal);\n\ dataout.eye = -(m_viewmodel * position);\n\ \n\ gl_position = m_pvm * position;\n\ }\n\ \n"; glshadersource(vertexshaderid, 1, &vertexsource, null); glcompileshader(vertexshaderid); // check vertex shader glint result = gl_false; int infologlength; glgetshaderiv(vertexshaderid, gl_compile_status, &result); glgetshaderiv(vertexshaderid, gl_info_log_length, &infologlength); if (infologlength > 0){ std::vector<char> vertexshadererrormessage(infologlength + 1); glgetshaderinfolog(vertexshaderid, infologlength, null, &vertexshadererrormessage[0]); std::string errormessage = std::string(&vertexshadererrormessage[0]); printf("%s\n", &vertexshadererrormessage[0]); } printf("compiling fragment shader.\n\n"); char const * fragmentsource = "#version 330\n\ layout(std140) uniform materials {\n\ vec4 diffuse;\n\ vec4 ambient;\n\ vec4 specular;\n\ vec4 emissive;\n\ float shininess;\n\ int texcount;\n\ };\ \n\ layout(std140) uniform lights {\n\ vec3 l_dir; \n\ };\ \n\ in data{\n\ vec3 normal;\n\ vec4 eye;\n\ } datain;\n\ \n\ out vec4 colorout;\ \n\ void main() {\n\ \n\ vec4 spec = vec4(0.0);\n\ \n\ vec3 n = normalize(datain.normal);\n\ vec3 e = normalize(vec3(datain.eye));\n\ \n\ float intensity = max(dot(n, l_dir), 0.0);\n\ \n\ if (intensity > 0.0) {\n\ vec3 h = normalize(l_dir + e);\n\ \n\ float intspec = max(dot(h, n), 0.0);\n\ spec = specular * pow(intspec, shininess);\n\ }\n\ \n\ colorout = max(intensity * diffuse + spec, ambient);\n\ }"; glshadersource(fragmentshaderid, 1, &fragmentsource, null); glcompileshader(fragmentshaderid); // check fragment shader glgetshaderiv(fragmentshaderid, gl_compile_status, &result); glgetshaderiv(fragmentshaderid, gl_info_log_length, &infologlength); if (infologlength > 0){ std::vector<char> fragmentshadererrormessage(infologlength + 1); glgetshaderinfolog(fragmentshaderid, infologlength, null, &fragmentshadererrormessage[0]); std::string errormessage = std::string(&fragmentshadererrormessage[0]); printf("%s\n", &fragmentshadererrormessage[0]); } // link programme printf("linking shader program.\n\n"); gluint programid = glcreateprogram(); glattachshader(programid, vertexshaderid); glattachshader(programid, fragmentshaderid); gllinkprogram(programid); // check programme glgetprogramiv(programid, gl_link_status, &result); glgetprogramiv(programid, gl_info_log_length, &infologlength); if (infologlength > 0){ std::vector<char> programerrormessage(infologlength + 1); glgetprograminfolog(programid, infologlength, null, &programerrormessage[0]); std::string errormessage = std::string(&programerrormessage[0]); printf("%s\n", &programerrormessage[0]); } gldeleteshader(vertexshaderid); gldeleteshader(fragmentshaderid); mainopenglshaderprogramid = programid; homecoming exit_success; } int prepareshaderuniforms() { gluseprogram(mainopenglshaderprogramid); lightsuniformblockid = glgetuniformblockindex(mainopenglshaderprogramid, "lights"); gluniformblockbinding(mainopenglshaderprogramid, lightsuniformblockid, 2); glgenbuffers(1, &lightsuniformbufferid); glbindbuffer(gl_uniform_buffer, lightsuniformbufferid); glbindbufferbase(gl_uniform_buffer, 2, lightsuniformbufferid); glfloat lightdirection[3] = { 1.0f, 1.0f, 0.0f }; glbufferdata(gl_uniform_buffer, sizeof(lightdirection), &lightdirection, gl_dynamic_draw); glbindbuffer(gl_uniform_buffer, null); matricesuniformblockid = glgetuniformblockindex(mainopenglshaderprogramid, "matrixinformation"); gluniformblockbinding(mainopenglshaderprogramid, matricesuniformblockid, 1); glgenbuffers(1, &matricesuniformbufferid); glbindbuffer(gl_uniform_buffer, matricesuniformbufferid); glbindbufferbase(gl_uniform_buffer, 1, matricesuniformbufferid); glsizeiptr totalbuffersize = sizeof(glm::mat4) + sizeof(glm::mat4); totalbuffersize += sizeof(glm::mat3); glbufferdata(gl_array_buffer, totalbuffersize, null, gl_dynamic_draw); glbindbuffer(gl_uniform_buffer, null); materialsuniformblockid = glgetuniformblockindex(mainopenglshaderprogramid, "materials"); gluniformblockbinding(mainopenglshaderprogramid, materialsuniformblockid, 3); glgenbuffers(1, &materialsuniformbufferid); glbindbuffer(gl_uniform_buffer, materialsuniformbufferid); glbindbufferbase(gl_uniform_buffer, 3, materialsuniformbufferid); glfloat material[18]; //diffuse material[0] = 0.5f; material[1] = 0.0f; material[2] = 0.0f; material[3] = 1.0f; //ambient material[4] = 0.2f; material[5] = 0.2f; material[6] = 0.2f; material[7] = 1.0f; //specular material[8] = 0.0f; material[9] = 0.0f; material[10] = 0.0f; material[11] = 1.0f; //emissive material[12] = 0.0f; material[13] = 0.0f; material[14] = 0.0f; material[15] = 1.0f; //shininess material[16] = 2.0f; //texture count material[17] = 0.0f; glbufferdata(gl_uniform_buffer, sizeof(material), &material, gl_dynamic_draw); glbindbuffer(gl_uniform_buffer, null); homecoming exit_success; } int loadcubes() { standardcube newcube; newcube.loadintoopengl(); cubes.push_back(newcube); homecoming exit_success; } int preparematricies() { glfloat aspectratio = (glfloat)(windowwidth) / (glfloat)(windowheight); projectionmatrix = glm::perspective(45.0f, aspectratio, 1.0f, 1000.0f); viewmatrix = glm::lookat( glm::vec3(4.0f, 3.0f, 3.0f), // photographic camera @ (4,3,3), in world space - photographic camera within world. glm::vec3(0.0f, 0.0f, 0.0f), // , looks @ origin - point photographic camera looking @ within world. glm::vec3(0.0f, 1.0f, 0.0f)// head up(set 0,1,0) - direction of camera. ); glviewport(0, 0, windowwidth, windowheight); homecoming exit_success; } int main(int argc, char** argv) { if (initializeglfwglew() == exit_failure) { exit(exit_failure); } if (prepareopengl() == exit_failure) { exit(exit_failure); } if (loadshaders() == exit_failure) { exit(exit_failure); } if (prepareshaderuniforms() == exit_failure) { exit(exit_failure); } if (loadcubes() == exit_failure) { exit(exit_failure); } if (preparematricies() == exit_failure) { exit(exit_failure); } while (!glfwwindowshouldclose(mainwindow)) { glclear(gl_color_buffer_bit | gl_depth_buffer_bit); (auto & c : cubes) { c.drawme(); } glfwswapbuffers(mainwindow); glfwpollevents(); } exit(exit_success); }

here vertex shader:

#version 330 layout(std140) uniform matrixinformation { mat4 m_pvm; mat4 m_viewmodel; mat3 m_normal; }; layout(std140) uniform lights { vec3 l_dir; }; in vec4 position; in vec3 normal; out data{ vec3 normal; vec4 eye; } dataout; void main() { dataout.normal = normalize(m_normal * normal); dataout.eye = -(m_viewmodel * position); gl_position = m_pvm * position; }

and here fragment shader:

#version 330 layout(std140) uniform materials { vec4 diffuse; vec4 ambient; vec4 specular; vec4 emissive; float shininess; int texcount; }; layout(std140) uniform lights { vec3 l_dir; }; in data{ vec3 normal; vec4 eye; } datain; out vec4 colorout; void main() { vec4 spec = vec4(0.0); vec3 n = normalize(datain.normal); vec3 e = normalize(vec3(datain.eye)); float intensity = max(dot(n, l_dir), 0.0); if (intensity > 0.0) { vec3 h = normalize(l_dir + e); float intspec = max(dot(h, n), 0.0); spec = specular * pow(intspec, shininess); } colorout = max(intensity * diffuse + spec, ambient); }

so issue part:

//binding uniform buffer glbindbuffer(gl_uniform_buffer, matricesuniformbufferid); glbindbufferbase(gl_uniform_buffer, 1, matricesuniformbufferid); glsizeiptr totalbuffersize = sizeof(glm::mat4) + sizeof(glm::mat4); totalbuffersize += sizeof(glm::mat3); //uploading unbound array buffer glbufferdata(gl_array_buffer, totalbuffersize, null, gl_dynamic_draw); glbindbuffer(gl_uniform_buffer, null);

so need alter

glbufferdata(gl_array_buffer, totalbuffersize, null, gl_dynamic_draw);

to

glbufferdata(gl_uniform_buffer, totalbuffersize, null, gl_dynamic_draw);

additionally uploading null doesn't work on opengl driver (although should), had

std::array<unsigned char,sizeof(glm::mat4)*2+sizeof(glm::mat3)> buff; glbufferdata(gl_uniform_buffer, totalbuffersize, buff.data(), gl_dynamic_draw);

as how find out: old-school method litter code glgeterror calls go off in debug mode. more modern method create debug context , print break on callback find out whereabouts error (then can create glgeterror calls in area exact function phone call if don't know then, since modern opengl drivers threaded , callback may triggered 1 or 2 function calls later).

c++ opengl glsl

No comments:

Post a Comment