2017-02-13 9 views
0

Я пытаюсь показать текстуру (да, это банк) с opengl 2.1 и glsl 120, но я не уверен, как это сделать, все, что я могу получить, это черный квад, Я после этого руководства: A Textured Cube, OpenGl - Textures и то, что я понял, что мне нужно:opengl 2.1 и текстуры

  1. Укажите координаты текстуры, чтобы прикрепить к каждой вершине (в моем случае 6 вершин, куб без индексации)
  2. Загрузить текстуру и связать его в блоке текстуры (по умолчанию 0)
  3. glDrawArrays вызовов

  4. Внутри шейдеров мне нужно:

  5. Получите текстурные COORDS в атрибуте в вершинном шейдере и передать его в пиксельный шейдер через меняющегося переменной
  6. В пиксельный шейдер использовать объект сэмплера образца пиксель в позиции, заданной переменной переменной, из текстуры.

Все ли верно?

Вот как я создать текстуру VBO и загрузить текстуру:

void Application::onStart(){ 
unsigned int format; 
SDL_Surface* img; 

float quadCoords[] = { 
     -0.5f, -0.5f, 0.0f, 
     0.5f, -0.5f, 0.0f, 
     0.5f, 0.5f, 0.0f, 
     0.5f, 0.5f, 0.0f, 
     -0.5f, 0.5f, 0.0f, 
     -0.5f, -0.5f, 0.0f}; 

const float texCoords[] = { 
     0.0f, 0.0f, 
     1.0f, 0.0f, 
     1.0f, 1.0f, 
     1.0f, 1.0f, 
     0.0f, 1.0f, 
     0.0f, 0.0f}; 

//shader loading omitted ... 
sprogram.bind(); // call glUseProgram(programId) 
//set the sampler value to 0 -> use texture unit 0 
sprogram.loadValue(sprogram.getUniformLocation(SAMPLER), 0); 

//quad 
glGenBuffers(1, &quadBuffer); 
glBindBuffer(GL_ARRAY_BUFFER, quadBuffer); 
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*18, quadCoords, GL_STATIC_DRAW); 
//texture 
glGenBuffers(1, &textureBuffer); 
glBindBuffer(GL_ARRAY_BUFFER, textureBuffer); 
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*12, texCoords, GL_STATIC_DRAW); 

//load texture 
img = IMG_Load("resources/images/crate.jpg"); 

if(img == nullptr) 
    throw std::runtime_error(SDL_GetError()); 

glGenTextures(1, &this->texture); 
glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_2D, this->texture); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img->w, img->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, img->pixels); 

SDL_FreeSurface(img); 
} 

рендеринга фазы:

glClear(GL_COLOR_BUFFER_BIT); 

glEnableVertexAttribArray(COORDS); 
glBindBuffer(GL_ARRAY_BUFFER, quadBuffer); 
glVertexAttribPointer(COORDS, 3, GL_FLOAT, GL_FALSE, 0, nullptr); 

glEnableVertexAttribArray(TEX_COORDS); 
glBindBuffer(GL_ARRAY_BUFFER, textureBuffer); 
glVertexAttribPointer(TEX_COORDS, 2, GL_FLOAT, GL_FALSE, 0, nullptr); 

//draw the vertices 
glDrawArrays(GL_TRIANGLES, 0, 6); 

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

#version 120 

attribute vec3 coord; 
attribute vec2 texCoord; 

varying vec2 UV; 

void main(){  
    gl_Position = vec4(coord.x, coord.y, coord.z, 1.0); 
    UV = texCoord; 
} 

пиксельный шейдер:

#version 120 

uniform sampler2D tex; 
varying vec2 UV; 

void main(){ 
    gl_FragColor.rgb = texture2D(tex, UV).rgb; 
    gl_FragColor.a = 1.0; 
} 

Я знаю, что учебники использовать out вместо varying так я пытался «преобразовать» код, также есть этот учебник: Simple Texture - LightHouse что объяснить gl_MultiTexCoord0 атрибут и gl_TexCoord массив которым строятся, но это почти то же самое я делаю. Я хочу знать, если все будет хорошо, а если нет, я хотел бы узнать, как показать простую текстуру 2d на экране с opengl 2.1 и glsl 120

+2

Где вы привязываете текстуру к сэмплеру? – immibis

+0

Редактировать в [mcve]. – genpfault

+0

@immibis, перед привязкой моей текстуры я вызываю 'glActiveTexture (GL_TEXTURE0)', который является сэмплером по умолчанию в шейдерах –

ответ

1

У вас есть конкретная причина использовать opengl 2.1 с версией glsl 1.2? Если не придерживаться openGl 3.0, потому что его легче понять imho. У меня есть две большие проблемы:

Прежде всего, получить черный квадратик: если его размер занимает ваше отверстие, то его цвет фона. Это означает, что он ничего не рисует. Я думаю (при тестировании этого) OpenGL имеет программу по умолчанию, которая будет активирована, и даже если вы уже установили объект массива вершин/буфер на gpu.It должен отображать как белый квадратик в вашем окне ... Так что это может быть Ур 1 проблема. Я не знаю, имеет ли opengl 2.1 буферные массивы вершин, но opengl 3.0 имеет, и вы должны определенно использовать это!

Во-вторых: вы не используете свою шейдерную программу в фазе рендеринга; Вызывайте эту функцию перед нанесением вашего четверной:

glUseProgram(myProgram); // The myProgram variable is your compiled shader program

Если случайно вы хотели бы, чтобы я объяснил, как сделать ваш квадроцикл с помощью OpegGL 3,0 ++, дайте мне знать :) ...Это недалеко от того, что вы уже писали в своем коде.

+0

Да, у меня есть причина использовать ogl 2.1 и glsl 1.2, мой компьютер очень старый (с 2010 года), и я действительно не могу купить новый прямо сейчас, квадрат рисуется правильно, он не занимает весь экран, я также тестировал треугольник. Я очень сожалею об этом, но я забыл показать, где я связываю свою программу gl, которая находится в разделе «// ... shader loading», который я обошел из-за моих классов оболочки gl, теперь я его изменю. –

+0

Вот какой полезный веб-сайт, на котором показаны все функции, доступные в ogl по версии: http://docs.gl/gl2/glUseProgram –

+0

Если ваш квад рисует на экране, тогда ваши текстурные UV-фильтры могут не попасть в шейдер. Существует и другой способ: vbo = {v1.x, v1.y, v1.z, uv1.x, uv1.y, v2.x, v2.y, v2.z, uv2.x, uv2.y,/* и т. д. * /} в основном вершины и uv данные упаковываются в одно и то же vbo и при вызове glVertexAttribPointer (COORDS, 3, GL_FLOAT, GL_FALSE, 0, nullptr); изменение 0 (шаг) до 3 * sizeof (GLfloat) glVertexAttribPointer (TEX_COORDS, 2, GL_FLOAT, GL_FALSE, 0, nullptr); и здесь от 0 до 2 * sizeof (GLfloat) // stride и nullptr to (GLvoid *) (3 * sizeof (GLfloat)) // (смещение) – Robert

 Смежные вопросы

  • Нет связанных вопросов^_^