opengl 2.1 和纹理

问题描述 投票:0回答:1

我正在尝试使用 opengl 2.1 和 glsl 120 显示纹理(是的,它是一个锅),但我不确定如何做到这一点,我所能得到的只是一个黑色四边形,我一直在关注这个教程:纹理立方体OpenGl - 纹理,我所理解的是我需要:

  1. 指定附加到每个顶点的纹理坐标(在我的例子中是 6 个顶点,一个没有索引的立方体)

  2. 加载纹理并将其绑定到纹理单元中(默认为0)

  3. 调用glDrawArrays

  4. 在着色器内部我需要:

  5. 接收顶点着色器中属性中的纹理坐标,并通过可变变量将其传递给片段着色器

  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
所以我尝试“转换”代码,还有这个教程:简单纹理 - LightHouse 解释了
gl_MultiTexCoord0
属性和
gl_TexCoord
数组是内置的,但这几乎与我正在做的事情相同。我想知道是否做得好,如果没有,我想知道如何使用 opengl 2.1 和 glsl 120 在屏幕上显示简单的 2d 纹理

c++ opengl
1个回答
0
投票

您是否有特殊原因将 opengl 2.1 与 glsl 版本 1.2 一起使用?如果不坚持使用 openGl 3.0,因为恕我直言,它更容易理解。 我猜你有两个大问题:

首先获得一个黑色四边形:如果它的大小占据了您的孔应用程序,那么它的背景颜色。这意味着它根本不绘制任何东西。 我认为(通过测试这个)OpenGL有一个默认程序,即使你已经在gpu上设置了一个顶点数组/缓冲区对象,它也会激活。它应该在你的窗口中渲染为一个白色的四边形......所以这可能是你的第一个问题。我不知道 opengl 2.1 是否有顶点缓冲区数组,但 opengl 3.0 有,你应该充分利用它!

第二:你在渲染阶段不使用你的着色器程序; 在绘制四边形之前调用此函数:

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

如果您希望我解释如何使用 OpegGL 3.0 ++ 绘制您的四边形,请告诉我:) ...这与您在代码中已经编写的内容相去不远。

© www.soinside.com 2019 - 2024. All rights reserved.