c++ - Strange behavior of glVertexAttrib3f on one machine -
i have weird problem simple opengl application not working on girlfriend's machine. @ first thought of kinds of problems code, break down code not working (not working means: triangle drawn correctly, black, is, without correct color):
#include <stdio.h> #include <stdlib.h> #include <string> #define glew_static #include <gl/glew.h> #include <glfw/glfw3.h> #include <glm/glm.hpp> #include <glm/gtx/transform.hpp> #include "../common/shader.h" const glfloat reticle_vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f }; glm::mat4 mvp; glm::mat4 vp; const char *vertexsource = "#version 150\n" "layout(location = 0) in vec3 position;" "layout(location = 1) in vec3 color;" "out vec3 fragcolor;" "uniform mat4 mvp;" "void main() {" "gl_position = mvp * vec4(position, 1.0);" "fragcolor = color;" "}"; const char *fragmentsource = "#version 150\n" "in vec3 fragcolor;" "out vec4 outcolor;" "void main() {" "outcolor = vec4(fragcolor, 1.0);" "}"; // key callback: exit on escape static void key_callback(glfwwindow *window, int key, int scancode, int action, int mods) { if (key == glfw_key_escape && action == glfw_press) glfwsetwindowshouldclose(window, gl_true); } // initialize , return window glfw glfwwindow *initglwindow(int width, int height, int samples, const char *title, glfwkeyfun keycb) { if (!glfwinit()) { fprintf(stderr, "failed initialize glfw\n"); return null; } glfwwindowhint(glfw_context_version_major, 3); glfwwindowhint(glfw_context_version_minor, 3); glfwwindowhint(glfw_samples, samples); glfwwindowhint(glfw_opengl_profile, glfw_opengl_core_profile); glfwwindow *w = glfwcreatewindow(width, height, title, null, null); if (!w) { glfwterminate(); return null; } glfwmakecontextcurrent(w); glfwsetkeycallback(w, keycb); glewexperimental = true; if (glewinit() != glew_ok) { fprintf(stderr, "failed initialize glew\n"); return null; } return w; } int main() { // initialize opengl window glfwwindow *window = initglwindow(1024, 768, 2, "schnuff", key_callback); // load , use shaders gluint programid = loadshaders(vertexsource, fragmentsource); gluseprogram(programid); // attribute locations gluint posattrib = glgetattriblocation(programid, "position"); printf("posattrib = %d\n", posattrib); gluint colattrib = glgetattriblocation(programid, "color"); printf("colattrib = %d\n", colattrib); //glint normattrib = glgetattriblocation(programid, "normal"); //printf("normattrib = %d\n", normattrib); gluint mvpid = glgetuniformlocation(programid, "mvp"); // vertex array object gluint vao; glgenvertexarrays(1, &vao); glbindvertexarray(vao); // vertex buffer object gluint vbo; glgenbuffers(1, &vbo); glbindbuffer(gl_array_buffer, vbo); glbufferdata(gl_array_buffer, sizeof(reticle_vertices), reticle_vertices, gl_static_draw); glenablevertexattribarray(posattrib); glvertexattribpointer(posattrib, 3, gl_float, gl_false, 0, (void*)0); // hide cursor glfwsetinputmode(window, glfw_cursor, glfw_cursor_hidden); glenable(gl_depth_test); gldepthfunc(gl_less); glenable(gl_cull_face); glclearcolor(0.0f, 0.0f, 0.2f, 1.0f); glm::mat4 m = glm::mat4(1.0f); // main loop { glclear(gl_color_buffer_bit | gl_depth_buffer_bit); gluniformmatrix4fv(mvpid, 1, gl_false, &m[0][0]); glvertexattrib3f(colattrib, 1.0f, 0.0f, 0.0f); gldrawarrays(gl_triangles, 0, 3); glfwswapbuffers(window); glfwpollevents(); } while (!glfwwindowshouldclose(window)); gldeleteprogram(programid); glfwdestroywindow(window); glfwterminate(); return 0; }
as far figure out, problem only occurs because of following: on machine, posattrib = 1, colattrib = 0
, while on mine other way round. tried using
layout(location = 0) in vec3 position; layout(location = 1) in vec3 color;
and works fine! although once exchange these numbers (i have yet test other values , #version 330 core\n
, laptop offline @ moment), stops working again...
i found following unanswered question here on so, seems closely related.
did of encounter similar behavior, or knows how fix whole situation without having use layout(location = x)
? since think in larger project, setting every location hand tedious or unwanted (correct me if i'm wrong there , preferred way it!).
yet test: other values 0 or 1, , #version
stuff, since on machine can't use layout(location = x)
without #version 330 core
(which again strange, because apparently something on machine makes work).
i'm newbie @ opengl , totally confused here! :-)
looks driver bug on amd card.
using vbo color array works:
#include <vector> #include <iostream> #include <gl/glew.h> #include <glfw/glfw3.h> #include <glm/glm.hpp> #include <glm/gtx/transform.hpp> // glsl shader program loader struct program { static gluint load( const char* vert, const char* geom, const char* frag ) { gluint prog = glcreateprogram(); if( vert ) attachshader( prog, gl_vertex_shader, vert ); if( geom ) attachshader( prog, gl_geometry_shader, geom ); if( frag ) attachshader( prog, gl_fragment_shader, frag ); gllinkprogram( prog ); checkstatus( prog ); return prog; } private: static void checkstatus( gluint obj ) { glint status = gl_false, len = 10; if( glisshader(obj) ) glgetshaderiv( obj, gl_compile_status, &status ); if( glisprogram(obj) ) glgetprogramiv( obj, gl_link_status, &status ); if( status == gl_true ) return; if( glisshader(obj) ) glgetshaderiv( obj, gl_info_log_length, &len ); if( glisprogram(obj) ) glgetprogramiv( obj, gl_info_log_length, &len ); std::vector< char > log( len, 'x' ); if( glisshader(obj) ) glgetshaderinfolog( obj, len, null, &log[0] ); if( glisprogram(obj) ) glgetprograminfolog( obj, len, null, &log[0] ); std::cerr << &log[0] << std::endl; exit( -1 ); } static void attachshader( gluint program, glenum type, const char* src ) { gluint shader = glcreateshader( type ); glshadersource( shader, 1, &src, null ); glcompileshader( shader ); checkstatus( shader ); glattachshader( program, shader ); gldeleteshader( shader ); } }; #define glsl(version, shader) "#version " #version "\n" #shader const char* vert = glsl ( 150 core, in vec3 position; in vec3 color; out vec3 fragcolor; uniform mat4 mvp; void main() { fragcolor = color; gl_position = mvp * vec4(position, 1.0); } ); const char* frag = glsl ( 150 core, in vec3 fragcolor; out vec4 outcolor; void main() { outcolor = vec4(1.0); } ); const glfloat reticle_vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f }; const glfloat colors[] = { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }; // key callback: exit on escape static void key_callback(glfwwindow *window, int key, int scancode, int action, int mods) { if (key == glfw_key_escape && action == glfw_press) glfwsetwindowshouldclose(window, gl_true); } // initialize , return window glfw glfwwindow *initglwindow(int width, int height, int samples, const char *title, glfwkeyfun keycb) { if (!glfwinit()) { fprintf(stderr, "failed initialize glfw\n"); return null; } glfwwindowhint(glfw_context_version_major, 3); glfwwindowhint(glfw_context_version_minor, 2); glfwwindowhint(glfw_samples, samples); glfwwindowhint(glfw_opengl_profile, glfw_opengl_core_profile); glfwwindow *w = glfwcreatewindow(width, height, title, null, null); if (!w) { glfwterminate(); return null; } glfwmakecontextcurrent(w); glfwsetkeycallback(w, keycb); glewexperimental = true; if (glewinit() != glew_ok) { fprintf(stderr, "failed initialize glew\n"); return null; } while( glgeterror() != gl_no_error ) {} return w; } int main() { // initialize opengl window glfwwindow *window = initglwindow(1024, 768, 2, "schnuff", key_callback); // hide cursor glfwsetinputmode(window, glfw_cursor, glfw_cursor_hidden); // load , use shaders gluint programid = program::load( vert, null, frag ); gluseprogram(programid); // vertex array object gluint vao; glgenvertexarrays(1, &vao); glbindvertexarray(vao); // vertex buffer object gluint posvbo; glgenbuffers(1, &posvbo); glbindbuffer(gl_array_buffer, posvbo); glbufferdata(gl_array_buffer, sizeof(reticle_vertices), reticle_vertices, gl_static_draw); gluint colorvbo; glgenbuffers(1, &colorvbo); glbindbuffer(gl_array_buffer, colorvbo); glbufferdata(gl_array_buffer, sizeof(colors), colors, gl_static_draw); glenable(gl_depth_test); gldepthfunc(gl_less); glenable(gl_cull_face); // main loop while( !glfwwindowshouldclose(window) ) { glclearcolor(0.0f, 0.0f, 0.2f, 1.0f); glclear(gl_color_buffer_bit | gl_depth_buffer_bit); glm::mat4 m = glm::mat4(1.0f); gluint mvpid = glgetuniformlocation(programid, "mvp"); gluniformmatrix4fv(mvpid, 1, gl_false, &m[0][0]); gluint pospos = glgetattriblocation( programid, "position" ); glenablevertexattribarray( pospos ); glbindbuffer(gl_array_buffer, posvbo); glvertexattribpointer( pospos, 3, gl_float, gl_false, 0, (void*)0 ); gluint colorpos = glgetattriblocation( programid, "color" ); // broken //gldisablevertexattribarray( colorpos ); //glvertexattrib3f( colorpos, 1.0f, 0.0f, 0.0f ); // works glenablevertexattribarray( colorpos ); glbindbuffer(gl_array_buffer, colorvbo); glvertexattribpointer( colorpos, 3, gl_float, gl_false, 0, (void*)0 ); gldrawarrays(gl_triangles, 0, 3); glfwswapbuffers(window); glfwpollevents(); } gldeleteprogram(programid); glfwdestroywindow(window); glfwterminate(); return 0; }
Comments
Post a Comment