簡體   English   中英

在OpenGL 3.3上使用Texture2D

[英]Using texture2D on OpenGL 3.3

因此,我一直在用OpenGL 3.3(FreeGLUT + GLEW)完成一個舊的大學項目,但遇到了一些問題。

就在開始時,我運行程序,並且在編譯BumpMap Fragment Shader時遇到錯誤:

#version 330 core    
#define lightCount 10

in vec4 vertPos;
in vec4 eyeModel;

in vec3 normalInterp;

in vec4 ambient;
in vec4 color;
in vec4 spec;
in vec2 texuv;

in vec4 lightPosition[lightCount];

struct LightSource {

        vec4 Position;
        vec4 Direction;

        vec4 Color;

        float CutOff;

        float AmbientIntensity;
        float DiffuseIntensity;
        float SpecularIntensity;

        float ConstantAttenuation;
        float LinearAttenuation;
        float ExponentialAttenuation;

        int lightType;
};

layout(std140) uniform LightSources {

        LightSource lightSource[10];
};

uniform sampler2D diffuse_tex;
uniform sampler2D normal_tex;

out vec4 out_Color;

void main() {
        out_Color = vec4(0);

        for(int i=0; i<lightCount; i++) {

                if(lightSource[i].lightType == 0)
                        continue;

                vec3 NormalMap = texture2D(normal_tex, texuv).rgb;
                vec3 normal = normalize(NormalMap * 2.0 - 1.0); //normalize(normalInterp);

                vec4 LightDirection = vertPos - lightSource[i].Position;
                float Distance = length(LightDirection);
                LightDirection = normalize(LightDirection);

                vec4 ambientColor = ambient * lightSource[i].Color * lightSource[i].AmbientIntensity;
                vec4 diffuseColor  =  vec4(0, 0, 0, 0);
                vec4 dColor = texture2D(diffuse_tex, texuv);
                vec4 specularColor = vec4(0, 0, 0, 0);

                float DiffuseFactor = dot(normal, vec3(-LightDirection));

                if (DiffuseFactor > 0) {

                        diffuseColor = dColor * lightSource[i].Color * lightSource[i].DiffuseIntensity * DiffuseFactor;

                        vec3 VertexToEye = normalize(vec3(eyeModel - vertPos));
                        vec3 LightReflect = normalize(reflect(vec3(LightDirection), normal));

                        float SpecularFactor = dot(VertexToEye, LightReflect);

                        SpecularFactor = pow(SpecularFactor, 255);
                        if(SpecularFactor > 0.0){
                        //SpecularFactor = pow( max(SpecularFactor,0.0), 255);
                                specularColor = spec * lightSource[i].Color * lightSource[i].SpecularIntensity * SpecularFactor;
                        }
                }

                out_Color += ambientColor + diffuseColor + specularColor;
        }
}

錯誤:0:55:“功能”:在正向兼容上下文Texture2D中已刪除
錯誤:0:55:'texture2D':找不到匹配的重載函數(使用隱式轉換)

於是我起來看了看這個問題,盡管我認為這件事很奇怪,我在一個項目上得到這個問題,我就知道一直處於工作狀態,我切換texture2D呼吁建立texture呼叫現在着色器編譯,但我得到一個不同的錯誤,其中為場景中的第一個對象創建了緩沖區對象:

//Consts defined here for readability
#define VERTICES 0
#define COLORS 1
#define NORMALS 2
#define TEXUVS 3
#define AMBIENTS 4
#define TANGENTS 5
#define SPECULARS 6
#define SPECULARS_CONSTANTS 7
#define NOISE_SCALE 8

void BufferObject::createBufferObject() {

    glGenVertexArrays(1, &_vertexArrayObjectID);
    glBindVertexArray(_vertexArrayObjectID);

    glGenBuffers(1, &_vertexBufferObjectID);

    glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferObjectID);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)*_vertexCount, _vertices, GL_STATIC_DRAW);

    glEnableVertexAttribArray(VERTICES);
    glVertexAttribPointer(VERTICES, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);

    glEnableVertexAttribArray(COLORS);
    glVertexAttribPointer(COLORS, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)sizeof(_vertices[0].XYZW));

    glEnableVertexAttribArray(NORMALS);
    glVertexAttribPointer(NORMALS, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(sizeof(_vertices[0].XYZW)+sizeof(_vertices[0].RGBA)));

    glEnableVertexAttribArray(TEXUVS);
    glVertexAttribPointer(TEXUVS, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(sizeof(_vertices[0].XYZW)+sizeof(_vertices[0].RGBA)+sizeof(_vertices[0].NORMAL)));

    glEnableVertexAttribArray(AMBIENTS);
    glVertexAttribPointer(AMBIENTS, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(sizeof(_vertices[0].XYZW)+sizeof(_vertices[0].RGBA)+sizeof(_vertices[0].NORMAL)+sizeof(_vertices[0].TEXUV)));

    glEnableVertexAttribArray(TANGENTS);
    glVertexAttribPointer(TANGENTS, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(sizeof(_vertices[0].XYZW)+sizeof(_vertices[0].RGBA)+sizeof(_vertices[0].NORMAL)+sizeof(_vertices[0].TEXUV)+sizeof(_vertices[0].AMBIENT)));

    glEnableVertexAttribArray(SPECULARS);
    glVertexAttribPointer(SPECULARS, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(sizeof(_vertices[0].XYZW)+sizeof(_vertices[0].RGBA)+sizeof(_vertices[0].NORMAL)+sizeof(_vertices[0].TEXUV)+sizeof(_vertices[0].AMBIENT)+sizeof(_vertices[0].TANGENT)));

    glEnableVertexAttribArray(SPECULARS_CONSTANTS);
    glVertexAttribPointer(SPECULARS_CONSTANTS, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(sizeof(_vertices[0].XYZW)+sizeof(_vertices[0].RGBA)+sizeof(_vertices[0].NORMAL)+sizeof(_vertices[0].TEXUV)+sizeof(_vertices[0].AMBIENT)+sizeof(_vertices[0].TANGENT)+sizeof(_vertices[0].SPECULAR)));

    glBindVertexArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_UNIFORM_BUFFER, 0);

    glDisableVertexAttribArray(VERTICES);
    glDisableVertexAttribArray(COLORS);
    glDisableVertexAttribArray(NORMALS);
    glDisableVertexAttribArray(TEXUVS);
    glDisableVertexAttribArray(AMBIENTS);
    glDisableVertexAttribArray(TANGENTS);
    glDisableVertexAttribArray(SPECULARS);
    glDisableVertexAttribArray(SPECULARS_CONSTANTS);

    Utility::checkOpenGLError("ERROR: Buffer Object creation failed.");
}

OpenGL錯誤[無效操作] = 1282

這就是我得到的所有信息。 我已經移動了checkOpenGLError ,並發現glDisableVertexAttribArray(VERTICES)行給出了錯誤。 經過更多的挖掘之后,我發現您不應該將glBindVertexArray(0)設置glBindVertexArray(0)至少在glDisableVertexAttribArray之前glBindVertexArray(0) ,根據我記得,我們將這些標志設置為0,這樣我們就不會意外地影響到我們沒有想)

此時,錯誤移至我們繪制場景對象之一的位置。 在這一點上,我碰壁了一點,不要去下一步了。 我想我的問題是,在運行項目時是否存在需要設置的配置,或者僅在較新的圖形卡上運行該配置是否可以解釋不同的行為。 最后一點,這是在Widnows中的Visual Studio 10(或15,還原所有更改且未重新定位解決方案時切換為10)的窗口上運行的,程序配置如下:

//GLUT Init
glutInit(&argc, argv);

glutInitContextVersion(3, 3);
glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
glutInitContextProfile(GLUT_CORE_PROFILE);

glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,GLUT_ACTION_GLUTMAINLOOP_RETURNS);

glutInitWindowSize(windowWidth, windowHeight);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);

windowHandle = glutCreateWindow(CAPTION);

//GLEW Init
glewExperimental = GL_TRUE;

GLenum result = glewInit(); 

//GLUT Init
std::cerr << "CONTEXT: OpenGL v" << glGetString(GL_VERSION) << std::endl;

glClearColor(0.1f, 0.1f, 0.1f, 1.0f);

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glDepthMask(GL_TRUE);
glDepthRange(0.0,1.0);
glClearDepth(1.0);

glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);

上面的上下文是:

上下文:OpenGL v3.3.0-內部版本22.20.16.4749

讓我知道是否需要任何其他信息,我不想添加任何不必要的混亂情況,並且該項目太大,無法將其全部粘貼到這里...

在您的着色器中,您使用的是glsl版本330內核,這意味着不建議使用texture2D() ,而應使用texture()

至於您的無效操作錯誤,問題在於您使用glBindVertexArray(0);解除了glBindVertexArray(0);綁定glBindVertexArray(0); 然后稱為glDisableVertexAttribArray(VERTICES); 在當前綁定的vao上運行。 您應該移動glBindVertexArray(0); 在這些電話下。

首先讓我參考規范OpenGL 4.6 API核心配置文件規范; 10.3.1頂點數組對象 第347頁

頂點數組對象的名稱空間是無符號整數, 其中GL保留零
...
通過使用命令綁定GenVertexArray返回的名稱來創建頂點數組對象

 void BindVertexArray( uint array ); 

array是頂點數組對象名稱。 所得的頂點數組對象是一個新的狀態向量,包括所有狀態,並具有表23.3和23.4中列出的相同初始值。
BindVertexArray也可以用於綁定現有的頂點數組對象。 如果綁定成功,則不會更改綁定的頂點數組對象的狀態,並且任何先前的綁定都會中斷。

表23.3,頂點數組對象狀態
VERTEX_ATTRIB_ARRAY_ENABLEDVERTEX_ATTRIB_ARRAY_SIZEVERTEX_ATTRIB_ARRAY_STRIDEVERTEX_ATTRIB_ARRAY_TYPEVERTEX_ATTRIB_ARRAY_NORMALIZEDVERTEX_ATTRIB_ARRAY_INTEGERVERTEX_ATTRIB_ARRAY_LONGVERTEX_ATTRIB_ARRAY_DIVISORVERTEX_ATTRIB_ARRAY_POINTER

表23.4,頂點數組對象狀態
ELEMENT_ARRAY_BUFFER_BINDINGVERTEX_ATTRIB_ARRAY_BUFFER_BINDINGVERTEX_ATTRIB_BINDINGVERTEX_ATTRIB_RELATIVE_OFFSETVERTEX_BINDING_OFFSETVERTEX_BINDING_STRIDEVERTEX_BINDING_DIVISORVERTEX_BINDING_BUFFER

這意味着“ 頂點陣列對象”將收集繪制對象所需的所有信息。 在頂點數組對象中存儲有關頂點屬性的位置和格式的信息。 此外,頂點數組對象“知道”屬性是啟用還是禁用。

如果你這樣做

glBindVertexArray(0);

glDisableVertexAttribArray( .... );

當您使用核心配置文件OpenGL上下文時 ,這會導致INVALID_OPERATION錯誤,因為頂點數組對象0不是有效的頂點數組對象。 如果使用兼容性配置文件上下文,則不會導致錯誤,因為頂點數組對象0是默認的頂點數組對象,並且是有效的。

如果你這樣做

glBindVertexArray(_vertexArrayObjectID);

glEnableVertexAttribArray( ..... );
glVertexAttribPointer( ..... );

glDisableVertexAttribArray( ..... );

glBindVertexArray(0);

那么抽獎電話將失敗。 您已努力定義通用頂點屬性數據的所有數組並正確啟用它們,但是在此之后立即再次禁用它們。 因此,在頂點數組對象中存儲了所有屬性的“禁用”狀態。

定義頂點數組對象的正確過程是:

  • 生成頂點緩沖區,並創建和初始化緩沖區對象的數據存儲(此步驟也可以在創建並綁定頂點數組對象之后完成):
glGenBuffers(1, &_vertexBufferObjectID);

glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferObjectID);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)*_vertexCount, _vertices, GL_STATIC_DRAW);
  • 生成並綁定頂點數組對象:
glGenVertexArrays(1, &_vertexArrayObjectID);
glBindVertexArray(_vertexArrayObjectID);
  • 定義並啟用通用頂點屬性數據的數組(這必須在綁定頂點數組對象之后完成):
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferObjectID);
glEnableVertexAttribArray(VERTICES);
glVertexAttribPointer(VERTICES, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);

....

glBindBuffer(GL_ARRAY_BUFFER, 0);
  • 如果要使用元素緩沖區( GL_ELEMENT_ARRAY_BUFFER ),則必須立即指定它,因為元素緩沖區對象(的引用)的名稱存儲在頂點數組對象中,並且當元素緩沖區對象被綁定。
glGenBuffers(1, &ibo);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, ..... );
  • 最后,您可以執行glBindVertexArray(0) 但是沒有理由這樣做。 在指定新網格之前,綁定一個新的頂點陣列對象就足夠了,或者在繪制網格之前綁定一個適當的頂點數組對象就足夠了。

此外,只要您不想更改頂點數組對象的規范,就不需要glDisableVertexAttribArray 狀態“啟用”存儲在頂點數組對象中並保持在那里。 如果綁定一個新的頂點數組對象,則該對象及其所有狀態都將變為當前狀態。

現在繪制很簡單:

 glBindVertexArray(_vertexArrayObjectID);
 glDrawArrays( .... );

同樣,在繪制調用之后(尤其是在核心模式下),不需要glBindVertexArray(0) )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM