Что приводит к сбою кода обработки шейдеров на основе OpenGL 2.0 в :: glBegin ()? - PullRequest
1 голос
/ 05 марта 2012

Сколько стоит:

  • мои графические драйверы (ATI Mobility Radeon 4570) обновлены.
  • Мне удалось получить код обработки шейдеров на основе расширений ARB, работающий надтот же конфиг ранее (хотя прошло некоторое время, прежде чем я вернулся к шейдерам).
  • Я следовал учебным пособиям по Lighthouse3d в своей настройке (... свободно: Настройка шейдеров Lighthouse3d шейдеркод журнала компиляции был извлечен из SO вопроса, извините за недостаток кредита, сейчас я не могу его найти)

В принципе все мои операции OpenGL, похоже, успешно выполняются;шейдеры компилируются и ссылки на программы.Как вы можете видеть ниже, я заканчивал проверкой ошибок OpenGL после каждого из вызовов gl ***.Сами шейдеры тривиальны.

Опять же, конечно, я мог бы упустить что-то смехотворно простое.

#define GLOP(operation) operation; if(!GFX::CheckError(#operation)) exit(1)
// GFX::CheckError() prints an error message, if any.

  GFX::Init(640, 480, 24, 0);
  GLOP(Texture2D::Enable());

  // shader setup
  GLuint  hFrag = GLOP(::glCreateShader(GL_FRAGMENT_SHADER));
  GLuint  hVert = GLOP(::glCreateShader(GL_VERTEX_SHADER));
  GLuint  hProg = GLOP(::glCreateProgram());

  std::ifstream inFile;
  ReadOpen("shader.frag", inFile);
  std::string  str(ReadFile(inFile));
  const char* pSource = str.c_str();
  GLOP(::glShaderSource(hFrag, 1, &pSource, 0));
  GLOP(::glCompileShader(hFrag));

  GLint logLength;
  glGetShaderiv(hFrag, GL_INFO_LOG_LENGTH, &logLength);
  if (logLength > 0) {
      GLchar* log = (GLchar*)malloc(logLength);
      glGetShaderInfoLog(hFrag, logLength, &logLength, log);
      printf("Shader compile log:\n%s\n", log);
      free(log);
  }

  XR::ReadOpen(core.GetPath() + "shader.vert", inFile);
  XRLOG(XR::GetFileSize(inFile) << " bytes in file." << std::endl);
  str = XR::ReadFile(inFile);
  pSource = str.c_str();
  GLOP(::glShaderSource(hVert, 1, &pSource, 0));
  GLOP(::glCompileShader(hVert));

  glGetShaderiv(hVert, GL_INFO_LOG_LENGTH, &logLength);
  if (logLength > 0) {
      GLchar* log = (GLchar*)malloc(logLength);
      glGetShaderInfoLog(hVert, logLength, &logLength, log);
      printf("Shader compile log:\n%s\n", log);
      free(log);
  }

  GLOP(::glAttachShader(hProg, hFrag));
  GLOP(::glAttachShader(hProg, hVert));
  GLOP(::glLinkProgram(hProg));

  glGetProgramiv(hProg, GL_INFO_LOG_LENGTH, &logLength);
  if (logLength > 0) {
      GLchar* log = (GLchar*)malloc(logLength);
      glGetProgramInfoLog(hProg, logLength, &logLength, log);
      printf("Program link log:\n%s\n", log);
      free(log);
  }

  GLOP(::glUseProgram(hProg));

  // get uniform's location
  GLint locTex0 = GLOP(::glGetUniformLocation(hProg, "tex0"));

  /// [loading image, creating texture goes here. works perfectly.]

  while(core.IsRunning())
  {
    GLOP(::glActiveTexture(GL_TEXTURE0));
    GLOP(pTex->Bind());
    GLOP(::glUniform1i(locTex0, GL_TEXTURE0));
    GLOP(::glPushMatrix());
    GLOP(::glTranslatef(GFX::GetFlopWidth() / 2, GFX::GetHeight() / 2, .0f)); // still no errors
    ::glBegin(GL_TRIANGLE_FAN);  // crash
    ::glTexCoord2f(.0f, 1.0f);
    ::glVertex2f(-100.0f, -100.0f);
    ::glTexCoord2f(1.0f, 1.0f);
    ::glVertex2f(100.0f, -100.0f);
    ::glTexCoord2f(1.0f, .0f);
    ::glVertex2f(100.0f, 100.0f);
    ::glTexCoord2f(.0f, .0f);
    ::glVertex2f(-100.0f, 100.0f);
    ::glEnd();
    ::glPopMatrix();
  }

Вершинный шейдер:

void main( void )
{
  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
  gl_TexCoord[0] = gl_MultiTexCoord0;
}

Фрагментный шейдер:

uniform sampler2D tex0;

void  main()
{
  vec2  texCoords = gl_TexCoord[0].st;
  vec3  pixel = texture2D(tex0, texCoords).xyz;
  gl_FragColor = vec4(pixel, 1.0);
}

Выход:

Successfully set video mode 640x480@24
Shader compile log:
Fragment shader was successfully compiled to run on hardware.

Shader compile log:
Vertex shader was successfully compiled to run on hardware.

Program link log:
Vertex shader(s) linked, fragment shader(s) linked.

Ответы [ 2 ]

3 голосов
/ 05 марта 2012

Вылетает ли он на первом кадре?

Я сомневаюсь, что это как-то связано с вашим сбоем, но вы должны знать, что вы вызываете glVertex / glTexcoord в неправильном порядке. glVertex завершает вершину, поэтому в вашем случае первый glVertex не имеет установленной текстовой координаты, а ваша последняя текстовая координата будет применена в следующем цикле.

0 голосов
/ 05 марта 2012

Немедленный режим для отправки таких вершин не поддерживается в профиле ядра, поэтому мне интересно, указали ли вы профиль ядра при настройке контекста OpenGL. Это объясняет, почему он умирает в glBegin.

...