triangle demo works on ubuntu13.04,doesn't work on ubuntu 12.04 - opengl-es-2.0

I get a triangle demo from internet. It works on my ubuntu13.04 virtual machine,but it doesn't work on my ubuntu12.04 virtual machine.All of my two vritual machines installed libgles2-mesa-dev(apt-get).The only diffrenet is:the ubuntu12.04 glesv2 is based on mesa-8.0 and the ubuntu13.04 glesv2 is based on mesa-9.
My code:
#include <GLES2/gl2.h>
#include <EGL/egl.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <unistd.h>
#include <X11/Xlib.h>
#define VERTEX_ARRAY 0
EGLDisplay eglDisplay = 0;
EGLConfig eglConfig = 0;
EGLSurface eglSurface = 0;
EGLContext eglContext = 0;
EGLNativeWindowType eglWindow = 0;
bool TestEGLError()
{
EGLint iErr = eglGetError();
if (iErr != EGL_SUCCESS)
{
return false;
}
return true;
}
bool CreateEGLContext()
{
eglDisplay = eglGetDisplay((EGLNativeDisplayType) EGL_DEFAULT_DISPLAY);
EGLint iMajorVersion, iMinorVersion;
if (!eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion))
{
return false;
}
const EGLint pi32ConfigAttribs[] =
{
EGL_LEVEL, 0,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NATIVE_RENDERABLE, EGL_FALSE,
EGL_DEPTH_SIZE, EGL_DONT_CARE,
EGL_NONE
};
EGLint config16bpp[] = {
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_DEPTH_SIZE, 16,
EGL_STENCIL_SIZE, 0,
EGL_NONE
};
int iConfigs;
if (!eglChooseConfig(eglDisplay,config16bpp, &eglConfig, 1, &iConfigs) || (iConfigs != 1))
{
return false;
}
eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, eglWindow, NULL);
if(eglSurface == EGL_NO_SURFACE)
{
eglGetError(); // Clear error
eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, NULL, NULL);
}
if (!TestEGLError())
{
return false;
}
eglBindAPI(EGL_OPENGL_ES_API);
EGLint ai32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, ai32ContextAttribs);
if (!TestEGLError())
{
return false;
}
eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
if (!TestEGLError())
{
return false;
}
return true;
}
bool Render()
{
bool bRet = false;
float pfIdentity[] =
{
1.0f,0.0f,0.0f,0.0f,
0.0f,1.0f,0.0f,0.0f,
0.0f,0.0f,1.0f,0.0f,
0.0f,0.0f,0.0f,1.0f
};
char szFragShaderSrc[] = {"\
void main (void)\
{\
gl_FragColor = vec4(1.0, 1.0, 0.66 ,1.0);\
}"};
char szVertShaderSrc[] = {"\
attribute highp vec4 myVertex;\
uniform mediump mat4 myPMVMatrix;\
void main(void)\
{\
gl_Position = myPMVMatrix * myVertex;\
}"};
char * pszFragShader = (char *)szFragShaderSrc;
char * pszVertShader = (char *)szVertShaderSrc;
GLuint uiFragShader = 0;
GLuint uiVertShader = 0;
GLuint uiProgramObject = 0;
GLint bShaderCompiled;
GLint bLinked;
GLuint ui32Vbo = 0;
GLfloat afVertices[] = { -0.4f,-0.4f,0.0f, // Position
0.4f ,-0.4f,0.0f,
0.0f ,0.4f ,0.0f};
int i32InfoLogLength, i32CharsWritten;
char* pszInfoLog = NULL;
int i32Location = 0;
unsigned int uiSize = 0;
uiFragShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(uiFragShader, 1, (const char**)&pszFragShader, NULL);
glCompileShader(uiFragShader);
glGetShaderiv(uiFragShader, GL_COMPILE_STATUS, &bShaderCompiled);
if (!bShaderCompiled)
{
glGetShaderiv(uiFragShader, GL_INFO_LOG_LENGTH, &i32InfoLogLength);
pszInfoLog = new char[i32InfoLogLength];
glGetShaderInfoLog(uiFragShader, i32InfoLogLength, &i32CharsWritten, pszInfoLog);
delete[] pszInfoLog;
goto cleanup;
}
uiVertShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(uiVertShader, 1, (const char**)&pszVertShader, NULL);
glCompileShader(uiVertShader);
glGetShaderiv(uiVertShader, GL_COMPILE_STATUS, &bShaderCompiled);
if (!bShaderCompiled)
{
glGetShaderiv(uiVertShader, GL_INFO_LOG_LENGTH, &i32InfoLogLength);
pszInfoLog = new char[i32InfoLogLength];
glGetShaderInfoLog(uiVertShader, i32InfoLogLength, &i32CharsWritten, pszInfoLog);
delete[] pszInfoLog;
goto cleanup;
}
uiProgramObject = glCreateProgram();
glAttachShader(uiProgramObject, uiFragShader);
glAttachShader(uiProgramObject, uiVertShader);
glBindAttribLocation(uiProgramObject, VERTEX_ARRAY, "myVertex");
glLinkProgram(uiProgramObject);
glGetProgramiv(uiProgramObject, GL_LINK_STATUS, &bLinked);
if (!bLinked)
{
glGetProgramiv(uiProgramObject, GL_INFO_LOG_LENGTH, &i32InfoLogLength);
pszInfoLog = new char[i32InfoLogLength];
glGetProgramInfoLog(uiProgramObject, i32InfoLogLength, &i32CharsWritten, pszInfoLog);
delete[] pszInfoLog;
goto cleanup;
}
glUseProgram(uiProgramObject);
glClearColor(0.6f, 0.8f, 1.0f, 1.0f);
glGenBuffers(1, &ui32Vbo);
glBindBuffer(GL_ARRAY_BUFFER, ui32Vbo);
uiSize = 3 * (sizeof(GLfloat) * 3); // Calc afVertices size (3 vertices * stride (3 GLfloats per vertex))
glBufferData(GL_ARRAY_BUFFER, uiSize, afVertices, GL_STATIC_DRAW);
{
glClear(GL_COLOR_BUFFER_BIT);
i32Location = glGetUniformLocation(uiProgramObject, "myPMVMatrix");
glUniformMatrix4fv( i32Location, 1, GL_FALSE, pfIdentity);
glEnableVertexAttribArray(VERTEX_ARRAY);
glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 3);
eglSwapBuffers(eglDisplay, eglSurface);
}
bRet = true;
cleanup:
if (uiProgramObject)
glDeleteProgram(uiProgramObject);
if (uiFragShader)
glDeleteShader(uiFragShader);
if (uiVertShader)
glDeleteShader(uiVertShader);
// Delete the VBO as it is no longer needed
if (ui32Vbo)
glDeleteBuffers(1, &ui32Vbo);
return bRet;
}
int main(int argc ,char* argv[])
{
unsigned int uiHeight = 800;
unsigned int uiWidth = 480;
int screen;
Display *x_display;
Window root_window;
x_display = XOpenDisplay ( NULL ); // open the standard display (the primary screen)
if ( x_display == NULL ) {
printf ("cannot connect to X server");
return false;
}
screen = DefaultScreen(x_display);
root_window = RootWindow(x_display,screen);
static int Hnd = XCreateSimpleWindow(x_display, root_window,0,0,800,480,0,0,0);
eglWindow = (EGLNativeWindowType)Hnd;
if (!eglWindow)
{
printf("Failed to create X window.\n");
return false;
}
XUndefineCursor(x_display, eglWindow);
XMapRaised(x_display, eglWindow);
XFlush(x_display);
CreateEGLContext();
while(1)
{
Render();
usleep(100000);
}
return 0;
}

Related

ASSERT failure in QList::operator[]: "index out of range"

I want to put the data of all the pixels of my image into a two-dimensional "uchar" vector, so that I can then manipulate this data, but the error does not allow me to do this.Error: ASSERT failure in QList::operator[]: "index out of range", file C:\Qt\6.2.1\msvc2019_64\include\QtCore/qlist.h, line 403
header
#include <QPixmap>
#include <QVector>
class LoadedImage
{
public:
LoadedImage(QString path);
QImage getCopyOfLoadedPILImage();
void loadImage();
void loadImageData();
QVector<uchar*> imageData ;
int getWidth();
int getHeight();
private:
QString path_;
QImage *loadedImage;
double width, height;
bool loadedImageIsOpen;
};
#endif // LOADEDIMAGE_H
cpp
#include "loadedimage.h"
LoadedImage::LoadedImage(QString path) : path_(path)
{
loadedImageIsOpen = false;
}
QImage LoadedImage::getCopyOfLoadedPILImage(){
return loadedImage->copy();
}
int LoadedImage::getHeight(){
return height;
}
int LoadedImage::getWidth(){
return width;
}
void LoadedImage::loadImage(){
loadedImage = new QImage(path_);
loadedImageIsOpen = true;
width = loadedImage->size().width();
height = loadedImage->size().height();
}
void LoadedImage::loadImageData(){
if(loadedImageIsOpen == false)
loadImage();
// unsigned char * rawData = loadedImage->bits();
int rawDataCount = 0;
int slice = 0;
for(int y = 0; y < height - 1; y++){
for(int x = 0; x < width - 1; x++){
if(slice < 3){
imageData[x][y] = loadedImage->pixel(rawDataCount, slice);
}
rawDataCount++;
slice++;
}
}
}

VK_ERROR_SURFACE_LOST_KHR while executing vkGetPhysicalDeviceSurfaceCapabilitiesKHR()

I met some problem while learning Vulkan. I followed Vulkan Coockbook but I failed on executing vkGetPhysicalDeviceSurfaceCapabilitiesKHR(), it returned VK_ERROR_SURFACE_LOST_KHR. I have no idea what the wrong is with my code.
CyApplication::CyApplication(void) {
#ifdef _WIN32
VulkanLibrary = LoadLibrary(L"vulkan-1.dll");
#elif defined __linux
VulkanLibrary = dlopen("libvulkan.so.1", RTLD_NOW);
#endif
if (VulkanLibrary == nullptr) {
throw std::runtime_error("");
}
#ifdef _WIN32
vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)GetProcAddress(VulkanLibrary, "vkGetInstanceProcAddr");
#elif defined __linux
vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)dlsym(VulkanLibrary, "vkGetInstanceProcAddr");
#endif
// Load global functions
vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)vkGetInstanceProcAddr(nullptr, "vkEnumerateInstanceExtensionProperties");
vkEnumerateInstanceLayerProperties = (PFN_vkEnumerateInstanceLayerProperties)vkGetInstanceProcAddr(nullptr, "vkEnumerateInstanceLayerProperties");
vkCreateInstance = (PFN_vkCreateInstance)vkGetInstanceProcAddr(nullptr, "vkCreateInstance");
// Create instance
desiredInstanceExtensions.emplace_back(VK_KHR_SURFACE_EXTENSION_NAME);
desiredInstanceExtensions.emplace_back(
#ifdef VK_USE_PLATFORM_WIN32_KHR
VK_KHR_WIN32_SURFACE_EXTENSION_NAME
#elif defined VK_USE_PLATFORM_XLIB_KHR
VK_KHR_XLIB_SURFACE_EXTENSION_NAME
#elif defined VK_USE_PLATFORM_XCB_KHR
VK_KHR_XCB_SURFACE_EXTENSION_NAME
#endif
);
applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
applicationInfo.pNext = nullptr;
applicationInfo.pApplicationName = "Cygine";
applicationInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
applicationInfo.pEngineName = "Cygine";
applicationInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
applicationInfo.apiVersion = VK_MAKE_VERSION(1, 0, 0);
instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
instanceCreateInfo.pNext = nullptr;
instanceCreateInfo.flags = 0;
instanceCreateInfo.pApplicationInfo = &applicationInfo;
instanceCreateInfo.enabledLayerCount = 0;
instanceCreateInfo.ppEnabledLayerNames = nullptr;
instanceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(desiredInstanceExtensions.size());
instanceCreateInfo.ppEnabledExtensionNames = desiredInstanceExtensions.data();
if (vkCreateInstance(&instanceCreateInfo, nullptr, &instance)) {
throw std::runtime_error("Failed to create the Vulkan instance.");
}
loadInstanceLevelFunctions();
// Create presentation surface
#ifdef VK_USE_PLATFORM_WIN32_KHR
wndParams.HInstance = GetModuleHandle(nullptr);
WNDCLASSEX window_class = {
sizeof(WNDCLASSEX), // UINT cbSize
// Win 3.x
CS_HREDRAW | CS_VREDRAW, // UINT style
WindowProcedure, // WNDPROC lpfnWndProc
0, // int cbClsExtra
0, // int cbWndExtra
wndParams.HInstance, // HINSTANCE hInstance
nullptr, // HICON hIcon
LoadCursor(nullptr, IDC_ARROW), // HCURSOR hCursor
(HBRUSH)(COLOR_WINDOW + 1), // HBRUSH hbrBackground
nullptr, // LPCSTR lpszMenuName
L"CygineWindow", // LPCSTR lpszClassName
// Win 4.0
nullptr // HICON hIconSm
};
if (!RegisterClassEx(&window_class)) {
throw std::runtime_error("WSL");
}
wndParams.Hwnd = CreateWindow(L"CyApplicationWindow",
L"CyApplication",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
(HWND)nullptr,
(HMENU)nullptr,
wndParams.HInstance,
(LPVOID)nullptr);
if (wndParams.Hwnd = nullptr) {
throw std::runtime_error("");
}
surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
surfaceCreateInfo.pNext = nullptr;
surfaceCreateInfo.flags = 0;
surfaceCreateInfo.hinstance = wndParams.HInstance;
surfaceCreateInfo.hwnd = wndParams.Hwnd;
ShowWindow(wndParams.Hwnd, SW_SHOW);
VkResult result = vkCreateWin32SurfaceKHR(instance, &surfaceCreateInfo, nullptr, &surface);
if (result != VK_SUCCESS) {
exit(EXIT_FAILURE);
}
#elif defined VK_USE_PLATFORM_XLIB_KHR
wndParams.dpy = XOpenDisplay();
wndParams.window = XCreateWindow(nullptr);
surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
surfaceCreateInfo.pNext = nullptr;
surfaceCreateInfo.flags = 0;
surfaceCreateInfo.hinstance = wndParams.dpy;
surfaceCreateInfo.hwnd = wndParams.window;
VkResult result = vkCreateXlibSurfaceKHR(instance, &surfaceCreateInfo, nullptr, &surface);
if (result != VK_SUCCESS || surface == VK_NULL_HANDLE) {
exit(EXIT_FAILURE);
}
#elif defined VK_USE_PLATFORM_XCB_KHR
wndParams.connect = xcb_connect();
wndParams.window = xcb_generate_id(nullptr);
surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
surfaceCreateInfo.pNext = nullptr;
surfaceCreateInfo.flags = 0;
surfaceCreateInfo.hinstance = wndParams.dpy;
surfaceCreateInfo.hwnd = wndParams.window;
VkResult result = vkCreateXcbSurfaceKHR(instance, &surfaceCreateInfo, nullptr, &surface);
if (result != VK_SUCCESS || surface == VK_NULL_HANDLE) {
exit(EXIT_FAILURE);
}
#endif
// Select physical device
desiredPhysicalDeviceExtensions.emplace_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
getAvailablePhysicalDevices();
do {
fmt::print("Select a physical device that Cygine will run on: ");
std::cin >> selectedPhysicalDeviceID;
} while (selectedPhysicalDeviceID >= availablePhysicalDevicesCount);
physicalDevice = availablePhysicalDevices[selectedPhysicalDeviceID];
getAvailablePhysicalDeviceExtensions(physicalDevice);
// Create logical device
getPhysicalDeviceQueueFamilyProperties(availablePhysicalDevices[selectedPhysicalDeviceID]);
selectQueueFamily(VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT);
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfo.pNext = nullptr;
queueCreateInfo.flags = 0;
queueCreateInfo.queueFamilyIndex = queueFamilyIndex;
queueCreateInfo.queueCount = 1;
float queuePriority = 1.0f;
queueCreateInfo.pQueuePriorities = &queuePriority;
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
deviceCreateInfo.pNext = nullptr;
deviceCreateInfo.flags = 0;
deviceCreateInfo.queueCreateInfoCount = /*static_cast<uint32_t>(queueCreateInfos.size())*/ 1;
deviceCreateInfo.pQueueCreateInfos = /*queueCreateInfos.data()*/ &queueCreateInfo;
deviceCreateInfo.enabledLayerCount = 0;
deviceCreateInfo.ppEnabledLayerNames = nullptr;
deviceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(desiredPhysicalDeviceExtensions.size());
deviceCreateInfo.ppEnabledExtensionNames = desiredPhysicalDeviceExtensions.data();
deviceCreateInfo.pEnabledFeatures = &desiredDeviceFeatures;
if (vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &device) != VK_SUCCESS) {
throw std::runtime_error("failed to create logical device!");
}
loadDeviceLevelFunctions();
// Create presentation surface
/*
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
GLFWwindow* window = glfwCreateWindow(640, 480, "Window Title", NULL, NULL);
if (glfwCreateWindowSurface(instance, window, nullptr, &surface))
throw std::runtime_error("failed to create");
*/
getSurfaceCapabilities();
fmt::print("Min Image Count: {}\n", surfaceCapabilities.minImageCount);
}
} // CygineApplicationAbstractions
Above is a part of my code. Have to say cooking Vulkan is really trivial ๐Ÿ˜ญ... Does any one have an idea? Hope you can solve my problem. Thanks!
if (wndParams.Hwnd = nullptr) {
You assign nullptr to Hwnd, so the surface is invalid when you query it.

C/C++ Socket UDP Client Data Sending -> Keep sending only one peer

i faced a problem with Multi-UDP Socket.
Now I have a PC(192.168.58.200), and 3 MPU(STM32F4)(192.168.85.100~102).
and I Conncected RS232 With MPU.
When MPU got a messasge, it returns just 'X', and print out same thing with RS232, so i can distinguish when PC can not send message and when MPU can get a message but PC can not recieve the message.
below is my code, Especially "UdpClient[c].Write( TempStr, strlen(TempStr));" doesnt work.
when it send mesage, only one MPU can get a message, and keep reciving 30~40 sec, some times changed other MPU.
1:1 is fine, but problem is more 2 Peer. please share your experiences.
// udpclient.cpp
#include <stdio.h>
#include "UDPCLIENT.h"
#include "UDPServer.h"
struct sPeer
{
char IP[64];
int Port;
};
#define CUR_MPU 3
#define MAX_MPU 16
sPeer Peer[MAX_MPU];
unsigned long _stdcall ReadThread(void *Param)
{
UDPSERVERSOCKET UDPSocket;
int ID = (int)Param;
printf("Server ID %d\n", ID);
UDPSocket.Open(Peer[ID].Port);
while (1)
{
char ReadBuffer[1024];
char Addr[32];
UDPSocket.Read(Addr, ReadBuffer, 1024);
printf("%s>%s\n", Addr, ReadBuffer);
}
UDPSocket.Close();
return 0;
}
int main()
{
sprintf(Peer[0].IP, "192.168.58.100"); Peer[0].Port = 7726;
sprintf(Peer[1].IP, "192.168.58.101"); Peer[1].Port = 7727;
sprintf(Peer[2].IP, "192.168.58.102"); Peer[2].Port = 7728;
///////////////////////์“ฐ๋ ˆ๋“œ๋ฅผ ์—ฐ๋‹ค./////////////////
for (int c = 0; c < CUR_MPU; c++)
{
DWORD ID;
HANDLE thread01 = CreateThread( NULL,//๋ณด์•ˆ ์†์„ฑ
0,//์Šคํƒ์˜ ํฌ๊ธฐ
ReadThread,//ํ•จ์ˆ˜
(void *)c,//์ธ์ž
0,//์ƒ์„ฑํ”Œ๋Ÿฌ๊ทธ
&ID);// ์•„์ด๋””
}
UDPCLIENTSOCKET UdpClient[CUR_MPU];
for (int c = 0; c < CUR_MPU; c++)
{
UdpClient[c].Open(Peer[c].IP, Peer[c].Port);
}
while (1)
{
char TempStr[1024];
printf("๋ณด๋‚ผ ๋ฉ”์‹œ์ง€ ---");
scanf("%s", TempStr);
for (int c = 0; c < CUR_MPU; c++)
{
UdpClient[c].Write( TempStr, strlen(TempStr));
}
}
for (int c = 0; c < CUR_MPU; c++)
UdpClient[c].Close();
return 0;
}
Cleint.cpp
#include "UDPCLIENT.h"
int UDPCLIENTSOCKET::Open(char *Address , int Port)
{
unsigned int addr;
int nRtn = WSAStartup(MAKEWORD(1, 1), &wsaData);
if (nRtn != 0) {
perror("WSAStartup ์˜ค๋ฅ˜\n");
return -1;
}
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0) {
perror("์†Œ์ผ“ ์˜ค๋ฅ˜\n");
WSACleanup();
return -2;
}
lpHostEnt = gethostbyname(Address);
if (lpHostEnt == NULL) {
addr = inet_addr(Address);
lpHostEnt = gethostbyaddr((char *)&addr, 4, AF_INET);
if (lpHostEnt == NULL) {
perror("์„œ๋ฒ„๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.\n");
_getch();
return -3;
}
}
memset(&addrin, 0, sizeof(addrin));
memcpy(&(addrin.sin_addr),
lpHostEnt->h_addr_list[0],
lpHostEnt->h_length);
addrin.sin_port = htons(Port);
addrin.sin_family = AF_INET;
//addrin.sin_addr.s_addr =
// *((unsigned long *)lpHostEnt->h_addr);
return 1;
}
void UDPCLIENTSOCKET::Close()
{
closesocket(s);
WSACleanup();
}
int UDPCLIENTSOCKET::Write(char *Address, int Port, char *Buffer, int Size)
{
unsigned int addr;
lpHostEnt = gethostbyname(Address);
if (lpHostEnt == NULL) {
addr = inet_addr(Address);
lpHostEnt = gethostbyaddr((char *)&addr, 4, AF_INET);
if (lpHostEnt == NULL) {
perror("์„œ๋ฒ„๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.\n");
_getch();
return -3;
}
}
memset(&addrin, 0, sizeof(addrin));
memcpy(&(addrin.sin_addr),
lpHostEnt->h_addr_list[0],
lpHostEnt->h_length);
addrin.sin_port = htons(Port);
addrin.sin_family = AF_INET;
int nRtn = sendto(s, Buffer, Size, 0,
(LPSOCKADDR)&addrin, sizeof(addrin));
return nRtn;
}
int UDPCLIENTSOCKET::Write(char *Buffer, int Size)
{
int nRtn = sendto(s, Buffer, Size, 0,
(LPSOCKADDR)&addrin, sizeof(addrin));
return nRtn;
}
Server.cpp
#include "UDPServer.h"
int UDPSERVERSOCKET::Open(u_short uport)
{
int nRtn;
if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) {
perror("WSAStartup Error\n");
return -1;
}
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0) {
perror("socket ์˜ค๋ฅ˜\n");
WSACleanup();
return -2;
}
memset(&addrin, 0, sizeof(addrin));
addrin.sin_port = htons(uport);
addrin.sin_family = AF_INET;
addrin.sin_addr.s_addr = htonl(INADDR_ANY);
nRtn = bind(s, (LPSOCKADDR)&addrin, (int)sizeof(addrin));
if (nRtn == SOCKET_ERROR) {
perror("bind ์˜ค๋ฅ˜\n");
closesocket(s);
WSACleanup();
return -3;
}
return 1;
}
int UDPSERVERSOCKET::Read(char *Addr, char *Buffer, int Length)
{
int fromlen = (int)sizeof(from);
int nRtn = recvfrom(s,
Buffer,
Length -1,
0,
(SOCKADDR *)&from,
&fromlen);
if (nRtn == SOCKET_ERROR)
{
Addr[0] = 0;
perror("recvform ์˜ค๋ฅ˜\n");
closesocket(s);
WSACleanup();
return -4;
}
strcpy(Addr, inet_ntoa(from.sin_addr));
Buffer[nRtn] = '\0';
return 1;
}
int UDPSERVERSOCKET::Close()
{
closesocket(s);
WSACleanup();
printf("WSACleanup ์™„๋ฃŒ\n");
return 1;
}
void UDPSERVERSOCKET::ShowErrorMessage(int i)
{
}
void UDPSERVERSOCKET::ReturnClientIP(char *Buffer)
{
}

Why does my structure assignment fail in C language๏ผŸ

Why does my structure assignment fail in C language๏ผŸ
I have a class A: define a structure
typedef struct{
int sockfd;
on_av_frame_cb av_frame_cb;
on_av_frame_cb rtp_cb;
on_error_cb error_cb;
uint8_t *p_buf;
uint8_t *v_buf;
uint8_t *a_buf;
int rtp_flag;
}udp_client_t;
Then I call in class B:
static udp_client_t client;
int jldv_create_client(int src_port,int port ,const char *dst_ip){
udp_client_t *udpClient = &client;
assert(udpClient != NULL);
const char *c_ip = dst_ip;
memset(udpClient, 0, sizeof(udp_client_t));
int ret = create_client(src_port, port, c_ip, &udpClient);
if (ret != 0) {
goto err_output;
}
udpClient->av_frame_cb = (on_av_frame_cb )onVideoFrame;
udpClient->error_cb = on_error;
if (rtp_create(&udpClient) < 0) { ///above problem
goto err_output;
}
printf("rtp_client:%d \n",udpClient->rtp_flag);
return 0;
err_output:
destroy_client(udpClient);
return -1;
}
In the above problem, I used the C class method:
int rtp_create(udp_client_t **data)
{
logi("%s", __func__);
udp_client_t *udpClient = *data;
if(udpClient)
{
udpClient->rtp_flag = 1;
memset(&rtp_cxt, 0, sizeof(rtp_context_t));
int ret = init_server();
if (ret < 0)
{
return -1;
}
rtp_cxt.nalu = alloc_nalu(MAX_FRAME_SIZE);//
if (!rtp_cxt.nalu)
{
loge("alloc nalu failed");
return -2;
}
}
else
{
loge("%s: data is null", __func__);
return -3;
}
printf("udpClient after==>%d \n",udpClient->rtp_flag);
return 0;
}
However, the result of printing is:
udpClient after==>1
rtp_client:0
supplement:
int create_client(int src_port, int dst_port, const char *dst_ip, udp_client_t **client)
{
udp_client_t *udpClient = *client;
assert(udpClient != NULL);
memset(udpClient, 0, sizeof(udp_client_t));
printf("create_client:%p\n",udpClient);
udpClient->port = src_port;
if (pthread_create(&udpClient->recv_tid, NULL, udp_receiver_runnable, (void *) udpClient) != 0)
{
loge("Failed to start new thread");
goto err_output;
}
return 0;
err_output:
memset(udpClient, 0, sizeof(udp_client_t));
return -10;
}
Why is that? Did i use something wrong?

D3D D2D Interop on Windows 7

I'm trying to use DWrite to draw text in my dx11 app but I'm having lot of problems, I shared resources beetween D3D10 Device and D3D11 Device because dx10 is capable to connect D3D with D2D, that's the code of my GraphicsDevice:
// File: GraphicsDevice.h
#pragma once
#ifndef _GRAPHICSDEVICE_H_
#define _GRAPHICSDEVICE_H_
#ifndef _DEFINES_H_
#include "Defines.h"
#endif
#ifndef _COLOR_H_
#include "Color.h"
#endif
#ifndef _UTILITIES_H_
#include "Utilities.h"
#endif
#ifndef _DWRITE_H_
#include "DWrite.h"
#endif
// Forward declaration
namespace BSGameFramework { ref class Game; }
using namespace BSGameFramework;
using namespace System;
namespace BSGameFramework
{
namespace Graphics
{
public ref class GraphicsDevice
{
public:
/// <summary>GraphicsDevice constructor.</summary>
/// <param name="game">The game wich the device has to work.</param>
GraphicsDevice(Game^ game);
virtual ~GraphicsDevice();
/// <summary>Clear the screen.</summary>
/// <param name="color">The color that the screen background will assume after clearing.</param>
void Clear(Color color);
/// <summary>Render on the screen.</summary>
void Render();
/// <summary>Set the full screen state.</summary>
void FullScreen(bool isFullScreen);
property Color BlendFactor
{
Color get()
{
return blendFactor_;
}
void set(Color blendFactor_)
{
blendFactor_ = BlendFactor;
}
}
property D3D_DRIVER_TYPE DriverType
{
D3D_DRIVER_TYPE get()
{
return driverType_;
}
}
property D3D_FEATURE_LEVEL FeatureLevel
{
D3D_FEATURE_LEVEL get()
{
return featureLevel_;
}
}
property ID3D11Device* D3DDevice
{
ID3D11Device* get()
{
return d3dDevice_;
}
}
property ID3D11DeviceContext* D3DContext
{
ID3D11DeviceContext* get()
{
return d3dContext_;
}
}
property ID3D10Device1* D3DDevice10_1
{
ID3D10Device1* get()
{
return d3dDevice10_1_;
}
}
property ID2D1Factory* D2DFactory
{
ID2D1Factory* get()
{
return d2dFactory_;
}
}
property ID2D1RenderTarget* D2DRenderTarget
{
ID2D1RenderTarget* get()
{
return d2dRenderTarget_;
}
}
property ID2D1SolidColorBrush* D2DSolidColorBrush
{
ID2D1SolidColorBrush* get()
{
return d2dSolidColorBrush_;
}
}
property IDWriteFactory* DWriteFactory
{
IDWriteFactory* get()
{
return dWriteFactory_;
}
}
property int WindowWidth
{
int get()
{
return GetWindowWidth();
}
}
property int WindowHeight
{
int get()
{
return GetWindowHeight();
}
}
property HWND Window
{
HWND get()
{
return GetWindow();
}
}
property int SafeTitleArea
{
int get()
{
return safeTitleArea_;
}
void set(int safeTitleArea)
{
safeTitleArea_ = safeTitleArea;
}
}
private:
void CreateD3D11Resources();
void CreateD3D10Resources(ID3D11Texture2D* d3d11Texture);
void CreateD2D1Resources(ID3D10Texture2D* d3d10Texture);
Game^ game_;
Color blendFactor_;
D3D_DRIVER_TYPE driverType_;
D3D_FEATURE_LEVEL featureLevel_;
int safeTitleArea_;
int GetWindowWidth();
int GetWindowHeight();
HWND GetWindow();
// Direct3D 11
ID3D11Device* d3dDevice_;
ID3D11DeviceContext* d3dContext_;
// Direct3D 10
ID3D10Device1* d3dDevice10_1_;
// Direct2D
ID2D1Factory* d2dFactory_;
ID2D1RenderTarget* d2dRenderTarget_;
ID2D1SolidColorBrush* d2dSolidColorBrush_;
// DirectWrite
IDWriteFactory* dWriteFactory_;
IDXGISwapChain* swapChain_;
ID3D11RenderTargetView* backBufferTarget_;
};
}
}
#endif
// FILE: GraphicsDevice.cpp
#include "GraphicsDevice.h"
#include "Game.h"
#include "GraphicsDeviceNativeWrapper.h"
using namespace BSGameFramework::Graphics;
using namespace BSGameFramework;
inline GraphicsDevice::GraphicsDevice(Game^ game) : driverType_( D3D_DRIVER_TYPE_NULL ), featureLevel_( D3D_FEATURE_LEVEL_11_0 ),
d3dDevice_( 0 ), d3dContext_( 0 ), swapChain_( 0 ), backBufferTarget_( 0 )
{
game_ = game;
BlendFactor = Color::White;
CreateD3D11Resources();
}
inline GraphicsDevice::~GraphicsDevice()
{
if (backBufferTarget_)
{
backBufferTarget_->Release();
}
if (swapChain_)
{
swapChain_->Release();
}
if (d3dContext_)
{
d3dContext_->Release();
}
if (d3dDevice_)
{
d3dDevice_->Release();
}
backBufferTarget_ = 0;
swapChain_ = 0;
d3dContext_ = 0;
d3dDevice_ = 0;
}
inline void GraphicsDevice::Clear(Color color)
{
if (d3dContext_ == 0)
{
return;
}
float clearColor[4];
Vec4 convertedColor = Utilities::ColorToVec4(color);
clearColor[0] = convertedColor.values[0];
clearColor[1] = convertedColor.values[1];
clearColor[2] = convertedColor.values[2];
clearColor[3] = convertedColor.values[3];
d3dContext_->ClearRenderTargetView(backBufferTarget_, clearColor);
}
inline void GraphicsDevice::Render()
{
swapChain_->Present(0, 0);
}
inline void GraphicsDevice::FullScreen(bool isFullScreen)
{
swapChain_->SetFullscreenState(isFullScreen, NULL);
}
inline int GraphicsDevice::GetWindowWidth()
{
return game_->WindowWidth;
}
inline int GraphicsDevice::GetWindowHeight()
{
return game_->WindowHeight;
}
inline HWND GraphicsDevice::GetWindow()
{
return game_->Window;
}
#pragma region CreateD3D11Resources
inline void GraphicsDevice::CreateD3D11Resources()
{
HRESULT result;
RECT dimensions;
GetClientRect(Window, &dimensions);
unsigned int width = dimensions.right - dimensions.left;
unsigned int height = dimensions.bottom - dimensions.top;
D3D_DRIVER_TYPE driverTypes[] =
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
D3D_DRIVER_TYPE_SOFTWARE
};
unsigned int totalDriverTypes = ARRAYSIZE(driverTypes);
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
D3D_FEATURE_LEVEL_9_2,
D3D_FEATURE_LEVEL_9_1
};
unsigned int totalFeatureLevels = ARRAYSIZE(featureLevels);
DXGI_SWAP_CHAIN_DESC swapChainDesc;
ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
swapChainDesc.BufferCount = 2;
swapChainDesc.BufferDesc.Width = width;
swapChainDesc.BufferDesc.Height = height;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.OutputWindow = game_->Window;
swapChainDesc.Windowed = true;
swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
unsigned int creationFlags = 0;
#ifdef _DEBUG
creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
unsigned int driver = 0;
pin_ptr<IDXGISwapChain*> swapChainPointer;
swapChainPointer = &swapChain_;
pin_ptr<ID3D11Device*> d3dDevicePointer;
d3dDevicePointer = &d3dDevice_;
pin_ptr<D3D_FEATURE_LEVEL> featureLevelPointer;
featureLevelPointer = &featureLevel_;
pin_ptr<ID3D11DeviceContext*> d3dContextPointer;
d3dContextPointer = &d3dContext_;
for (driver = 0; driver < totalDriverTypes; ++driver)
{
result = D3D11CreateDeviceAndSwapChain(0, driverTypes[driver], 0, creationFlags, featureLevels, totalFeatureLevels,
D3D11_SDK_VERSION, &swapChainDesc, swapChainPointer,
d3dDevicePointer, featureLevelPointer, d3dContextPointer);
if (SUCCEEDED(result))
{
driverType_ = driverTypes[driver];
break;
}
}
if (FAILED(result))
{
DXTRACE_MSG("Failed to create the Direct3D device!");
return;
}
ID3D11Texture2D* backBufferTexture;
result = swapChain_->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferTexture);
if (FAILED(result))
{
DXTRACE_MSG("Failed to get the swap chain back buffer!");
return;
}
pin_ptr<ID3D11RenderTargetView*> backBufferTargetPointer;
backBufferTargetPointer = &backBufferTarget_;
result = d3dDevice_->CreateRenderTargetView(backBufferTexture, 0, backBufferTargetPointer);
if (FAILED(result))
{
DXTRACE_MSG("Failed to create the render target view!");
return;
}
d3dContext_->OMSetRenderTargets(1, backBufferTargetPointer, 0);
D3D11_VIEWPORT viewport;
viewport.Width = static_cast<float>(width);
viewport.Height = static_cast<float>(height);
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
viewport.TopLeftX = 0.0f;
viewport.TopLeftY = 0.0f;
d3dContext_->RSSetViewports(1, &viewport);
CreateD3D10Resources(backBufferTexture);
}
#pragma endregion
#pragma region CreateD3D10Resources
inline void GraphicsDevice::CreateD3D10Resources(ID3D11Texture2D* d3d11Texture)
{
//Load D3D10.DLL
HMODULE d3d10_1 = LoadLibrary("D3D10_1.dll");
// Get adapter of the current D3D11 device. Our D3D10 will run on the same adapter.
IDXGIDevice* dxgiDevice;
IDXGIAdapter* dxgiAdapter;
d3dDevice_->QueryInterface<IDXGIDevice>(&dxgiDevice);
dxgiDevice->GetAdapter(&dxgiAdapter);
SafeRelease<IDXGIDevice>(&dxgiDevice);
//Get address of the function D3D10CreateDevice1 dynamically.
typedef HRESULT (WINAPI* FN_D3D10CreateDevice1)(
IDXGIAdapter *pAdapter, D3D10_DRIVER_TYPE DriverType, HMODULE Software,
UINT Flags, D3D10_FEATURE_LEVEL1 HardwareLevel, UINT SDKVersion, ID3D10Device1 **ppDevice );
FN_D3D10CreateDevice1 fnCreate = (FN_D3D10CreateDevice1)GetProcAddress(d3d10_1, "D3D10CreateDevice1");
//Call D3D10CreateDevice1 dynamically.
pin_ptr<ID3D10Device1*> d3dDevice10_1Ptr = &d3dDevice10_1_;
fnCreate(dxgiAdapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, D3D10_CREATE_DEVICE_BGRA_SUPPORT | D3D10_CREATE_DEVICE_DEBUG, D3D10_FEATURE_LEVEL_10_1, D3D10_1_SDK_VERSION, d3dDevice10_1Ptr);
//Create a D3D10.1 render target texture and share it with our D3D11.
D3D10_TEXTURE2D_DESC tDesc;
tDesc.Width = game_->WindowWidth;
tDesc.Height = game_->WindowHeight;
tDesc.MipLevels = 1;
tDesc.ArraySize = 1;
tDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
tDesc.SampleDesc.Count = 1;
tDesc.SampleDesc.Quality = 0;
tDesc.Usage = D3D10_USAGE_DEFAULT;
//EVEN IF YOU WON'T USE AS SHADER RESOURCE, SET THIS BIND FLAGS:
tDesc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
tDesc.CPUAccessFlags = 0;
tDesc.MiscFlags = D3D10_RESOURCE_MISC_SHARED;
//Create the RT texture on D3D10
ID3D10Texture2D* texture;
d3dDevice10_1_->CreateTexture2D(&tDesc, NULL, &texture);
//Get DXGI Resource and retrieve the sharing handle.
IDXGISurface* dxgiSurface;
IDXGIResource* dxgiResource;
HANDLE shareHandle;
texture->QueryInterface<IDXGISurface>(&dxgiSurface);
dxgiSurface->QueryInterface<IDXGIResource>(&dxgiResource);
dxgiResource->GetSharedHandle(&shareHandle);
SafeRelease(&dxgiResource);
SafeRelease(&dxgiSurface);
//Call D3D 11 to open shared resource.
ID3D11Resource* d3d11Resource;
d3dDevice_->OpenSharedResource(shareHandle, __uuidof(ID3D11Resource), (void**)&d3d11Resource);
d3d11Resource->QueryInterface<ID3D11Texture2D>(&d3d11Texture);
SafeRelease(&d3d11Resource);
if (d3d11Texture)
{
d3d11Texture->Release();
}
CreateD2D1Resources(texture);
}
#pragma endregion
#pragma region CreateD2D1Resources
inline void GraphicsDevice::CreateD2D1Resources(ID3D10Texture2D* d3d10Texture)
{
pin_ptr<ID2D1Factory*> d2dFactoryPtr = &d2dFactory_;
pin_ptr<IDWriteFactory*> dWriteFactoryPtr = &dWriteFactory_;
//pin_ptr<ID2D1HwndRenderTarget*> d2dRenderTargetPtr = &d2dRenderTarget_;
//pin_ptr<ID2D1SolidColorBrush*> D2DSolidColorBrushPtr = &d2dSolidColorBrush_;
GraphicsDeviceNativeWrapper::CreateFactories(Window, d2dFactoryPtr, dWriteFactoryPtr);
//Get DXGI Surface from the created render target.
IDXGISurface1* pRT10;
d3d10Texture->QueryInterface<IDXGISurface1>(&pRT10);
FLOAT dpiX;
FLOAT dpiY;
d2dFactory_->GetDesktopDpi(&dpiX, &dpiY);
// Create a DC render target.
D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(
D2D1_RENDER_TARGET_TYPE_DEFAULT,
D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_IGNORE),
static_cast<float>(dpiX),
static_cast<float>(dpiY)
);
// Create a Direct2D render target.
// Assuming m_pD2DFactory was previously created with:
//D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory), NULL,
// (void**)(&m_pD2DFactory));
pin_ptr<ID2D1RenderTarget*> renderTargetPtr = &d2dRenderTarget_;
d2dFactory_->CreateDxgiSurfaceRenderTarget(pRT10, (const D2D1_RENDER_TARGET_PROPERTIES *)&props, renderTargetPtr);
pin_ptr<ID2D1SolidColorBrush*> solidColorBrushPtr = &d2dSolidColorBrush_;
d2dRenderTarget_->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White), solidColorBrushPtr);
}
#pragma endregion
// File GraphicsDeviceNativeWrapper.h
#pragma once
#ifndef _GRAPHICSDEVICENATIVEWRAPPER_H_
#define _GRAPHICSDEVICENATIVEWRAPPER_H_
#ifndef _DWRITE_H_
#include "DWrite.h"
#endif
#pragma managed(push, false)
namespace BSGameFramework
{
namespace Graphics
{
class GraphicsDeviceNativeWrapper abstract sealed
{
public:
static void CreateFactories(HWND window, ID2D1Factory** d2dFactory, IDWriteFactory** dWriteFactory/*,ID2D1RenderTarget** d2dRenderTarget, ID2D1SolidColorBrush** d2dSolidColorBrush*/)
{
HRESULT result;
result = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,__uuidof(ID2D1Factory), NULL, (void**)d2dFactory);
if (SUCCEEDED(result))
{
result = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown**>(dWriteFactory));
}
RECT rc;
GetClientRect(window, &rc);
D2D1_SIZE_U size = D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top);
}
static void CreateTextFormat(const wchar_t* font, IDWriteFactory* factory, IDWriteTextFormat** format)
{
factory->CreateTextFormat(font, NULL, DWRITE_FONT_WEIGHT_REGULAR, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 72.0f, L"en-us", format);
(*format)->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);
(*format)->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);
}
};
}
}
#pragma managed(pop)
#endif
And this is my SpriteBatch:
// File: SpriteBatch.h
#pragma once
#ifndef _SPRITEBATCH_H_
#define _SPRITEBATCH_H_
#ifndef _DEFINES_H_
#include "Defines.h"
#endif
#ifndef _GRAPHICRESOURCE_H_
#include "GraphicResource.h"
#endif
#ifndef _TEXTURE2D_H_
#include "Texture2D.h"
#endif
#ifndef _GRAPHICSDEVICE_H_
#include "GraphicsDevice.h"
#endif
#ifndef _SPRITESORTMODE_H_
#include "SpriteSortMode.h"
#endif
#ifndef _BLENDSTATE_H_
#include "BlendState.h"
#endif
#ifndef _NATIVESPRITEBATCH_H_
#include "NativeSpritebatch.h"
#endif
#ifndef _SPRITEEFFECT_H_
#include "SpriteEffect.h"
#endif
#ifndef _IDRAWABLECOMPONENT_H_
#include "IDrawableComponent.h"
#endif
#ifndef _SPRITEFONT_H_
#include "SpriteFont.h"
#endif
using namespace BSGameFramework::GameBase;
namespace BSGameFramework
{
namespace Graphics
{
public ref class SpriteBatch : GraphicResource
{
public:
SpriteBatch(GraphicsDevice^ graphicsDevice);
~SpriteBatch();
void Begin();
void Begin(SpriteSortMode sortMode, BlendState^ blendState);
void Draw(IDrawableComponent^ component);
void DrawString(SpriteFont^ font, System::String^ text, Vector2 position);
void End();
private:
bool CompileD3DShader(char* filePath, char* entry, char* shaderModel, ID3DBlob** buffer);
void SortByDepth();
SpriteSortMode sortMode_;
BlendState ^blendState_;
System::Collections::Generic::List<IDrawableComponent^>^ componentList_;
bool beginInvoked_;
ID3D11VertexShader* solidColorVS_;
ID3D11PixelShader* solidColorPS_;
ID3D11InputLayout* inputLayout_;
ID3D11Buffer* vertexBuffer_;
ID3D11BlendState* alphaBlendState_;
NativeSpritebatch* spriteBatch;
};
}
}
#endif
// File: SpriteBatch.cpp
#include "SpriteBatch.h"
#ifndef _SPRITEBATCHBEGINENDEXCEPTION_H_
#include "SpriteBatchBeginEndException.h"
#endif
using namespace BSGameFramework::Graphics;
using namespace BSGameFramework::Exception;
inline SpriteBatch::SpriteBatch(GraphicsDevice^ graphicsDevice) : alphaBlendState_( 0 )
{
graphicDevice_ = graphicsDevice;
sortMode_ = SpriteSortMode::Deferred;
blendState_ = BlendState::AlphaBlend;
// ID3DBlob contiene un puntatore ad un dato di lunghezza qualsiasi, GetBufferPointer restituisce il puntatore e GetBufferSize la grandezza
ID3DBlob* vsBuffer = 0;
// Compila lo shader e salva il risultato nel buffer
bool compileResult = CompileD3DShader("TextureMap.fx", "VS_Main", "vs_4_0", &vsBuffer);
if (compileResult == false)
{
DXTRACE_MSG("Error compiling the vertex shader!");
return;
}
HRESULT d3dResult;
pin_ptr<ID3D11VertexShader*> solidColorVSPointer;
solidColorVSPointer = &solidColorVS_;
// Crea il vertex shader e lo salva in solidColorVS_ di tipo ID3D11VertexShader*
d3dResult = Device->D3DDevice->CreateVertexShader(vsBuffer->GetBufferPointer(), vsBuffer->GetBufferSize(), 0, solidColorVSPointer);
if (FAILED(d3dResult))
{
DXTRACE_MSG("Error creating the vertex shader!");
if (vsBuffer)
{
vsBuffer->Release();
}
return;
}
D3D11_INPUT_ELEMENT_DESC solidColorLayout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
unsigned int totalLayoutElements = ARRAYSIZE(solidColorLayout);
pin_ptr<ID3D11InputLayout*> inputLayoutPointer;
inputLayoutPointer = &inputLayout_;
// Crea l'input layout e lo salva in inputLayout di tipo ID3D11InputLayout*
d3dResult = Device->D3DDevice->CreateInputLayout(solidColorLayout, totalLayoutElements, vsBuffer->GetBufferPointer(), vsBuffer->GetBufferSize(), inputLayoutPointer);
vsBuffer->Release();
if (FAILED(d3dResult))
{
DXTRACE_MSG("Error creating the input layout!");
return;
}
ID3DBlob* psBuffer = 0;
// Compila il pixel shader e salva il risultato in psBuffer
compileResult = CompileD3DShader("TextureMap.fx", "PS_Main", "ps_4_0", &psBuffer);
if (compileResult == false)
{
DXTRACE_MSG("Error compiling pixel shader!");
return;
}
pin_ptr<ID3D11PixelShader*> solidColorPSPointer;
solidColorPSPointer = &solidColorPS_;
// Crea il pixel shader e lo salva in solidColorPS_ di tipo ID3D11PixelShader*
d3dResult = Device->D3DDevice->CreatePixelShader(psBuffer->GetBufferPointer(), psBuffer->GetBufferSize(), 0, solidColorPSPointer);;
psBuffer->Release();
if (FAILED(d3dResult))
{
DXTRACE_MSG("Error creating pixel shader!");
return;
}
spriteBatch = new NativeSpritebatch(Device->D3DDevice);
// Spostare nel Begin successivamente
D3D11_BLEND_DESC blendDesc;
ZeroMemory(&blendDesc, sizeof(D3D11_BLEND_DESC));
blendDesc.AlphaToCoverageEnable = FALSE;
blendDesc.IndependentBlendEnable = FALSE;
blendDesc.RenderTarget[0].BlendEnable = TRUE;
blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_DEST_ALPHA;
blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
float blendFactor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
pin_ptr<ID3D11BlendState*> alphaBlendStatePointer;
alphaBlendStatePointer = &alphaBlendState_;
Device->D3DDevice->CreateBlendState(&blendDesc, alphaBlendStatePointer);
Device->D3DContext->OMSetBlendState(alphaBlendState_, blendFactor, 0xFFFFFFFF);
}
inline SpriteBatch::~SpriteBatch()
{
}
inline void SpriteBatch::Begin()
{
if (beginInvoked_)
{
throw gcnew SpriteBatchBeginEndException("Beetween two SpriteBatch begin methods you must call SpriteBacth End method!");
}
beginInvoked_ = true;
Device->D2DRenderTarget->BeginDraw();
Device->D2DRenderTarget->SetTransform(D2D1::IdentityMatrix());
if (componentList_ == nullptr)
{
componentList_ = gcnew System::Collections::Generic::List<IDrawableComponent^>();
}
}
inline void SpriteBatch::Begin(SpriteSortMode sortMode, BlendState^ blendState)
{
Begin();
sortMode_ = sortMode;
}
inline void SpriteBatch::Draw(IDrawableComponent^ component)
{
if (component == nullptr)
{
throw gcnew ArgumentNullException("Component argument is null, please ensure to initialize all components correctly!");
}
else
{
componentList_->Add(component);
}
}
inline void SpriteBatch::DrawString(SpriteFont^ font, System::String^ text, Vector2 position)
{
RECT rc;
GetClientRect(Device->Window, &rc);
// Create a D2D rect that is the same size as the window.
D2D1_RECT_F layoutRect = D2D1::RectF(
static_cast<FLOAT>(rc.left) / font->DpiScaleX,
static_cast<FLOAT>(rc.top) / font->DpiScaleY,
static_cast<FLOAT>(rc.right - rc.left) / font->DpiScaleX,
static_cast<FLOAT>(rc.bottom - rc.top) / font->DpiScaleY
);
// Use the DrawText method of the D2D render target interface to draw.
WCHAR textUnicode = Utilities::StringToWCHAR(text);
UINT32 cTextLength_ = (UINT32) wcslen(&textUnicode);
Device->D2DSolidColorBrush->SetColor(D2D1::ColorF(0,0,0,1));
Device->D2DSolidColorBrush->SetColor(D2D1::ColorF(255, 255, 255, 255));
Device->D2DRenderTarget->DrawText(&textUnicode, cTextLength_, font->DWriteTextFormat, layoutRect, Device->D2DSolidColorBrush);
}
inline void SpriteBatch::End()
{
if (componentList_->Count)
{
if (sortMode_ == SpriteSortMode::BackToFront)
{
SortByDepth();
}
for (int i = 0; i < componentList_->Count; i++)
{
Texture* text = componentList_[i]->Texture->TextureInfo;
unsigned int stride = sizeof(VertexPos);
unsigned int offset = 0;
Device->D3DContext->IASetInputLayout(inputLayout_);
if (componentList_[i]->Effect != SpriteEffect::None)
{
ID3D11Buffer* vertexBuffer;
float width = (float)text->textureDesc_.Width;
float height = (float)text->textureDesc_.Height;
D3D11_BUFFER_DESC vertexDesc;
ZeroMemory(&vertexDesc, sizeof(vertexDesc));
vertexDesc.Usage = D3D11_USAGE_DYNAMIC;
vertexDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexDesc.ByteWidth = sizeof(VertexPos) * 6;
D3D11_SUBRESOURCE_DATA resourceData;
ZeroMemory(&resourceData, sizeof(resourceData));
pin_ptr<ID3D11Buffer*> vertexBufferPointer;
vertexBufferPointer = &vertexBuffer;
switch (componentList_[i]->Effect)
{
case BSGameFramework::Graphics::SpriteEffect::FlipHorizontally:
{
VertexPos verticesOne[] =
{
{ XMFLOAT3(width, height, 1.0f), XMFLOAT2(0.0f, 0.0f) },
{ XMFLOAT3(width, 0.0f, 1.0f), XMFLOAT2(0.0f, 1.0f) },
{ XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT2(1.0f, 1.0f) },
{ XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT2(1.0f, 1.0f) },
{ XMFLOAT3(0.0f, height, 1.0f), XMFLOAT2(1.0f, 0.0f) },
{ XMFLOAT3(width, height, 1.0f), XMFLOAT2(0.0f, 0.0f) },
};
resourceData.pSysMem = verticesOne;
Device->D3DDevice->CreateBuffer(&vertexDesc, &resourceData, vertexBufferPointer);
Device->D3DContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
break;
}
case BSGameFramework::Graphics::SpriteEffect::FlipVertically:
{
VertexPos verticesTwo[] =
{
{ XMFLOAT3(width, height, 1.0f), XMFLOAT2(1.0f, 1.0f) },
{ XMFLOAT3(width, 0.0f, 1.0f), XMFLOAT2(1.0f, 0.0f) },
{ XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT2(0.0f, 0.0f) },
{ XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT2(0.0f, 0.0f) },
{ XMFLOAT3(0.0f, height, 1.0f), XMFLOAT2(0.0f, 1.0f) },
{ XMFLOAT3(width, height, 1.0f), XMFLOAT2(1.0f, 1.0f) },
};
resourceData.pSysMem = verticesTwo;
Device->D3DDevice->CreateBuffer(&vertexDesc, &resourceData, vertexBufferPointer);
Device->D3DContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
break;
}
}
}
else
{
Device->D3DContext->IASetVertexBuffers(0, 1, &text->vertexBuffer_, &stride, &offset);
}
Device->D3DContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
Device->D3DContext->VSSetShader(solidColorVS_, 0, 0);
Device->D3DContext->PSSetShader(solidColorPS_, 0, 0);
Device->D3DContext->PSSetShaderResources(0, 1, &text->colorMap_);
Device->D3DContext->PSSetSamplers(0, 1, &text->colorMapSampler_);
spriteBatch->SetTranspose(Device->D3DContext, text, Device->WindowWidth, Device->WindowHeight, componentList_[i]->Position.X, componentList_[i]->Position.Y,
componentList_[i]->Scale.X, componentList_[i]->Scale.Y, componentList_[i]->Rotation);
Device->D3DContext->Draw(6, 0);
}
}
Device->D2DRenderTarget->EndDraw();
componentList_->Clear();
beginInvoked_ = false;
sortMode_ = SpriteSortMode::Deferred;
}
inline bool SpriteBatch::CompileD3DShader(char* filePath, char* entry, char* shaderModel, ID3DBlob** buffer)
{
DWORD shaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
#if defined(DEBUG) || defined(_DEBUG)
shaderFlags |= D3DCOMPILE_DEBUG;
#endif
ID3DBlob* errorBuffer = 0;
HRESULT result;
result = D3DX11CompileFromFile(filePath, 0, 0, entry, shaderModel, shaderFlags, 0, 0, buffer, &errorBuffer, 0);
if (FAILED(result))
{
if (errorBuffer != 0)
{
OutputDebugStringA((char*)errorBuffer->GetBufferPointer());
errorBuffer->Release();
}
return false;
}
if (errorBuffer != 0)
{
errorBuffer->Release();
}
return true;
}
inline void SpriteBatch::SortByDepth()
{
for (int i = 0; i < componentList_->Count - 1; i++)
{
for (int j = 1; j < componentList_->Count; j++)
{
if (componentList_[i]->ZIndex < componentList_[j]->ZIndex)
{
IDrawableComponent^ component = componentList_[i];
componentList_[i] = componentList_[j];
componentList_[j] = component;
}
}
}
}
When I call SpriteBatch.DrawString(...) from my C# app I'm not obtaining nothing written on my screen, can please somebody explaining me what's I'm missing? I'm new on DirectX programming so please be quiet with me xD Thanks!
There's a lot of code you posted and I didn't read it all, but I was trying to do the same thing (successfully) a few days ago and I might have some suggestions.
Overall, it looks like you do this more or less the same way I do. What I did different it that I created the shared texture using D3D11 device, but this should make no difference. The second thing, which I think could be the problem, is that you're not synchronizing the texture resource between D3D10 and D3D11.
When I tried to use such resources without synchronization, D2D was only rendering stuff once in like 50 calls, the rest just had no effect. I think I was continously blocking the resource when rendering it with D3D11.
You should create the texture using
tDesc.MiscFlags = D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX;
instead. Here are the details about this flag: MSDN. Basically, you query two IDXGIKeyedMutex interfaces from the shared texture objects on both D3D10 and D3D11 devices. You lock the D3D10 mutex when you draw your D2D stuff to the texture. You lock the D3D11 mutex when you want to use this texture in D3D11. You do this using IDXGIKeyedMutex::AcquireSync and IDXGIKeyedMutex::ReleaseSync. Just be sure to pass the same Key value to each consecutive D3D10 Release -> D3D11 Acquire and D3D11 Release -> D3D10 Acquire calls.
Oh, one more little, not important thing, I noticed this in your code:
texture->QueryInterface<IDXGISurface>(&dxgiSurface);
dxgiSurface->QueryInterface<IDXGIResource>(&dxgiResource);
I'm not 100% sure, but I think you can get the IDXGIResource interface directly from your texture.